根本原因:返回值类型为一个,例如Integer或者实体类,但是sql查询结果(selectOne#selectList)为多个。
mybits,mapper方法底层源码
五种sql类型:insert、update、delete、select、flush
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
//sql类型
switch (command.getType()) {
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
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:
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else if (method.returnsCursor()) {
result = executeForCursor(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
}
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;
}
select的返回类型:
1. void
this.returnsVoid = Void.TYPE.equals(this.returnType);
2. list或array
this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray();
3. map
this.mapKey = this.getMapKey(method);
this.returnsMap = this.mapKey != null;
private String getMapKey(Method method) {
String mapKey = null;
//map类型
if (Map.class.isAssignableFrom(method.getReturnType())) {
MapKey mapKeyAnnotation = (MapKey)method.getAnnotation(MapKey.class);
if (mapKeyAnnotation != null) {
mapKey = mapKeyAnnotation.value();
}
}
return mapKey;
}
4. 游标cursor
this.returnsCursor = Cursor.class.equals(this.returnType);
5. 以上三种都不是,那就是selectOne
查询结果用list接收
public <T> T selectOne(String statement, Object parameter) {
//查询结果用list接收
List<T> list = this.selectList(statement, parameter);
if (list.size() == 1) {
return list.get(0);
} else if (list.size() > 1) {
throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
} else {
return null;
}
}
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
List var5;
try {
MappedStatement ms = this.configuration.getMappedStatement(statement);
//查询
var5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception var9) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + var9, var9);
} finally {
ErrorContext.instance().reset();
}
return var5;
}
疑问:sql中distinct的情况下,上述selectList返回的结果到底是distinct前的还是distinct后的?
本地测试结果,
distinct后的
数据如下:
测试结果:
版权声明:本文为tec_1535原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。