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
192
193
194
195
196
197
198
199
200
201
202
|
public class MapperMethod {
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
// 根据 sql语句 的类型 调用 sqlSession 对应的方法
switch (command.getType()) {
case INSERT: {
// 使用 ParamNameResolver 处理 args实参列表,将用户传入的实参与
// 指定参数名称关联起来
Object param = method.convertArgsToSqlCommandParam(args);
// 获取返回结果,rowCountResult()方法 会根据 method属性 中的 returnType,
// 对结果的类型进行转换
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
case SELECT:
// 处理返回值为 void 且 ResultSet 通过 ResultHandler 处理的方法
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
// 处理返回值为集合 或 数组的方法
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
// 处理返回值为 Map 的方法
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
// 处理返回值为 Cursor 的方法
} else if (method.returnsCursor()) {
result = executeForCursor(sqlSession, args);
} else {
// 处理返回值为单一对象的方法
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
// 处理返回值为 Optional 的方法
if (method.returnsOptional()
&& (result == null || !method.getReturnType().equals(result.getClass()))) {
result = Optional.ofNullable(result);
}
}
break;
case FLUSH:
result = sqlSession.flushStatements();
break;
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}
/**
* 当执行 insert、update、delete 类型的 sql语句 时,其执行结果都要经过本方法处理
*/
private Object rowCountResult(int rowCount) {
final Object result;
// 方法的返回值为 void 时
if (method.returnsVoid()) {
result = null;
// 方法的返回值为 Integer 时
} else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {
result = rowCount;
// 方法的返回值为 Long 时
} else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {
result = (long)rowCount;
// 方法的返回值为 Boolean 时
} else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {
result = rowCount > 0;
} else {
throw new BindingException("Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType());
}
return result;
}
/**
* 如果 Mapper接口 中定义的方法准备使用 ResultHandler 处理查询结果集,则通过此方法处理
*/
private void executeWithResultHandler(SqlSession sqlSession, Object[] args) {
// 获取 sql语句 对应的 MappedStatement对象,该对象中记录了 sql语句 相关信息
MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
// 当使用 ResultHandler 处理结果集时,必须指定 ResultMap 或 ResultType
if (!StatementType.CALLABLE.equals(ms.getStatementType())
&& void.class.equals(ms.getResultMaps().get(0).getType())) {
throw new BindingException("method " + command.getName()
+ " needs either a @ResultMap annotation, a @ResultType annotation,"
+ " or a resultType attribute in XML so a ResultHandler can be used as a parameter.");
}
// 转换实参列表
Object param = method.convertArgsToSqlCommandParam(args);
// 如果实参列表中有 RowBounds类型参数
if (method.hasRowBounds()) {
// 从 args参数列表 中获取 RowBounds对象
RowBounds rowBounds = method.extractRowBounds(args);
// 执行查询,并用指定的 ResultHandler 处理结果对象
sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
} else {
sqlSession.select(command.getName(), param, method.extractResultHandler(args));
}
}
/**
* 如果 Mapper接口 中对应方法的返回值为集合(Collection接口实现类) 或 数组,
* 则调用本方法将结果集处理成 相应的集合或数组
*/
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
List<E> result;
// 参数列表转换
Object param = method.convertArgsToSqlCommandParam(args);
// 参数列表中是否有 RowBounds类型的参数
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
// 这里使用了 selectList()方法 进行查询,所以返回的结果集就是 List类型的
result = sqlSession.selectList(command.getName(), param, rowBounds);
} else {
result = sqlSession.selectList(command.getName(), param);
}
// 将结果集转换为数组或 Collection集合
if (!method.getReturnType().isAssignableFrom(result.getClass())) {
if (method.getReturnType().isArray()) {
return convertToArray(result);
} else {
return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
}
}
return result;
}
/**
* 将结果集转换成 Collection集合
*/
private <E> Object convertToDeclaredCollection(Configuration config, List<E> list) {
// 使用前面介绍的 ObjectFactory,通过反射方式创建集合对象
Object collection = config.getObjectFactory().create(method.getReturnType());
MetaObject metaObject = config.newMetaObject(collection);
// 实际上就是调用了 Collection 的 addAll()方法
metaObject.addAll(list);
return collection;
}
/**
* 本方法和上面的 convertToDeclaredCollection()功能 类似,主要负责将结果对象转换成数组
*/
@SuppressWarnings("unchecked")
private <E> Object convertToArray(List<E> list) {
// 获取数组中元素的 类型Class
Class<?> arrayComponentType = method.getReturnType().getComponentType();
// 根据元素类型 和 元素数量 初始化数组
Object array = Array.newInstance(arrayComponentType, list.size());
// 将 List 转换成数组
if (arrayComponentType.isPrimitive()) {
for (int i = 0; i < list.size(); i++) {
Array.set(array, i, list.get(i));
}
return array;
} else {
return list.toArray((E[])array);
}
}
/**
* 如果 Mapper接口 中对应方法的返回值为类型为 Map,则调用此方法执行 sql语句
*/
private <K, V> Map<K, V> executeForMap(SqlSession sqlSession, Object[] args) {
Map<K, V> result;
// 转换实参列表
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
// 注意这里调用的是 SqlSession 的 selectMap()方法,返回的是一个 Map类型结果集
result = sqlSession.selectMap(command.getName(), param, method.getMapKey(), rowBounds);
} else {
result = sqlSession.selectMap(command.getName(), param, method.getMapKey());
}
return result;
}
/**
* 本方法与上面的 executeForMap()方法 类似,只不过 sqlSession 调用的是 selectCursor()
*/
private <T> Cursor<T> executeForCursor(SqlSession sqlSession, Object[] args) {
Cursor<T> result;
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
result = sqlSession.selectCursor(command.getName(), param, rowBounds);
} else {
result = sqlSession.selectCursor(command.getName(), param);
}
return result;
}
}
|