3ab1fab2ac0fad9fec4077efdb721f93eaf332f2.svn-base
6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
* Copyright © 2015-2018 ODM All rights reserved.
*/
package com.thinkgem.jeesite.common.persistence.proxy;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import com.thinkgem.jeesite.common.persistence.Page;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 执行代理类,扩展Mybatis的方式来让其Mapper接口来支持.
* </p>
*
* @author poplar.yfyang
* @version 1.0 2012-05-13 上午10:09
* @since JDK 1.5
*/
public class PaginationMapperMethod {
private final SqlSession sqlSession;
private final Configuration config;
private SqlCommandType type;
private String commandName;
private String commandCountName;
private final Class<?> declaringInterface;
private final Method method;
private Integer rowBoundsIndex;
private Integer paginationIndex;
private final List<String> paramNames;
private final List<Integer> paramPositions;
private boolean hasNamedParameters;
public PaginationMapperMethod(Class<?> declaringInterface, Method method,
SqlSession sqlSession) {
paramNames = new ArrayList<String>();
paramPositions = new ArrayList<Integer>();
this.sqlSession = sqlSession;
this.method = method;
this.config = sqlSession.getConfiguration();
this.declaringInterface = declaringInterface;
this.hasNamedParameters = false;
setupFields();
setupMethodSignature();
setupCommandType();
validateStatement();
}
/**
* 代理执行方法。
*
* @param args 参数信息
* @return 执行结果
*/
@SuppressWarnings("unchecked")
public Object execute(Object[] args) {
final Object param = getParam(args);
Page<Object> page;
RowBounds rowBounds;
if (paginationIndex != null) {
page = (Page<Object>) args[paginationIndex];
rowBounds = new RowBounds(page.getFirstResult(), page.getMaxResults());
} else if (rowBoundsIndex != null) {
rowBounds = (RowBounds) args[rowBoundsIndex];
page = new Page<Object>();
} else {
throw new BindingException("Invalid bound statement (not found rowBounds or pagination in paramenters)");
}
page.setCount(executeForCount(param));
page.setList(executeForList(param, rowBounds));
return page;
}
/**
* 执行总数的方法,调用方法执行计算总数,取得总结果
*
* @param param 参数信息
* @return 查询的总记录数
*/
private long executeForCount(Object param) {
Number result = (Number) sqlSession.selectOne(commandCountName, param);
return result.longValue();
}
/**
* 取得分页的执行结果,返回的是纪录信息
*
* @param param 参数
* @param rowBounds row
* @return 纪录列表
*/
private List<Object> executeForList(Object param, RowBounds rowBounds) {
return sqlSession.selectList(commandName, param, rowBounds);
}
/**
* 取得当前执行的参数信息
*
* @param args 参数
* @return 参数信息
*/
private Object getParam(Object[] args) {
final int paramCount = paramPositions.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasNamedParameters && paramCount == 1) {
return args[paramPositions.get(0)];
} else {
Map<String, Object> param = new HashMap<String, Object>();
for (int i = 0; i < paramCount; i++) {
param.put(paramNames.get(i), args[paramPositions.get(i)]);
}
return param;
}
}
private void setupMethodSignature() {
final Class<?>[] argTypes = method.getParameterTypes();
for (int i = 0; i < argTypes.length; i++) {
if (Page.class.isAssignableFrom(argTypes[i])) {
paginationIndex = i;
} else if (RowBounds.class.isAssignableFrom(argTypes[i])) {
rowBoundsIndex = i;
} else {
String paramName = String.valueOf(paramPositions.size());
paramName = getParamNameFromAnnotation(i, paramName);
paramNames.add(paramName);
paramPositions.add(i);
}
}
}
private String getParamNameFromAnnotation(int i, String paramName) {
Object[] annotations = method.getParameterAnnotations()[i];
for (Object annotation : annotations) {
if (annotation instanceof Param) {
hasNamedParameters = true;
paramName = ((Param) annotation).value();
}
}
return paramName;
}
/**
* 设置当前的查询总记录数的ID
*/
private void setupFields() {
commandName = declaringInterface.getName() + "." + method.getName();
commandCountName = commandName + "Count"; // 命名约定
}
/**
* 设置当前的参数的类型信息
*/
private void setupCommandType() {
MappedStatement ms = config.getMappedStatement(commandName);
type = ms.getSqlCommandType();
if (type != SqlCommandType.SELECT) {
throw new BindingException("Unsupport execution method for: " + commandName);
}
}
/**
* 验证Statement
*/
private void validateStatement() {
if (!config.hasStatement(commandName)) {
throw new BindingException("Invalid bound statement (not found): " + commandName);
}
if (!config.hasStatement(commandCountName)) {
throw new BindingException("Invalid bound statement (not found): " + commandCountName);
}
}
}