MyBatis中Mapper的返回值类型

一箫一剑平生意,负尽狂名十五年。这篇文章主要讲述MyBatis中Mapper的返回值类型相关的知识,希望能为你提供帮助。
insert、update、delete语句的返回值类型对数据库执行修改操作时,数据库会返回受影响的行数。
在MyBatis(使用版本3.4.6,早期版本不支持)中insert、update、delete语句的返回值可以是Integer、Long和Boolean。在定义Mapper接口时直接指定需要的类型即可,无需在对应的< insert> < update> < delete> 标签中显示声明。
对应的代码在  org.apache.ibatis.binding.MapperMethod 类中,如下:

  • 对于insert、update、delete语句,MyBatis都会使用  rowCountResult 方法对返回值进行转换;
  • rowCountResult 方法会根据Mapper声明中方法的返回值类型来对参数进行转换;
  • 对于返回类型为Boolean的情况,如果返回的值大于0,则返回True,否则返回False
1 public Object execute(SqlSession sqlSession, Object[] args) { 2Object result; 3switch (command.getType()) { 4case INSERT: { 5Object param = method.convertArgsToSqlCommandParam(args); 6result = rowCountResult(sqlSession.insert(command.getName(), param)); 7break; 8} 9case UPDATE: { 10Object param = method.convertArgsToSqlCommandParam(args); 11result = rowCountResult(sqlSession.update(command.getName(), param)); 12break; 13} 14case DELETE: { 15Object param = method.convertArgsToSqlCommandParam(args); 16result = rowCountResult(sqlSession.delete(command.getName(), param)); 17break; 18} 19case SELECT: 20if (method.returnsVoid() & & method.hasResultHandler()) { 21executeWithResultHandler(sqlSession, args); 22result = null; 23} else if (method.returnsMany()) { 24result = executeForMany(sqlSession, args); 25} else if (method.returnsMap()) { 26result = executeForMap(sqlSession, args); 27} else if (method.returnsCursor()) { 28result = executeForCursor(sqlSession, args); 29} else { 30Object param = method.convertArgsToSqlCommandParam(args); 31result = sqlSession.selectOne(command.getName(), param); 32} 33break; 34case FLUSH: 35result = sqlSession.flushStatements(); 36break; 37default: 38throw new BindingException("Unknown execution method for: " + command.getName()); 39} 40if (result == null & & method.getReturnType().isPrimitive() & & !method.returnsVoid()) { 41throw new BindingException("Mapper method ‘" + command.getName() 42+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); 43} 44return result; 45} 46 47private Object rowCountResult(int rowCount) { 48final Object result; 49if (method.returnsVoid()) { 50result = null; 51} else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) { 52result = rowCount; 53} else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) { 54result = (long)rowCount; 55} else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) { 56result = rowCount > 0; 57} else { 58throw new BindingException("Mapper method ‘" + command.getName() + "‘ has an unsupported return type: " + method.getReturnType()); 59} 60return result; 61}

select语句的返回值类型对于select语句,必须在Mapper映射文件中显示声明返回值类型,否则会抛出异常,指出“A query was run and no Result Maps were found for the Mapped Statement”。
【MyBatis中Mapper的返回值类型】select语句返回的column值与Mapper方法返回值的属性的映射有两种方式:
  • 通过名称实现自动映射
  • 通过resultMap标签指定映射方式
通过名称实现自动映射只要保证数据库查询返回的column名称和Bean的属性名一致,Mybatis便能够实现自动映射。如:
< select id="selectActorById"resultType="canger.study.chapter04.bean.Actor"> select actor_id as id, first_name as firstName ,last_name as lastName from actor where actor_id=#{id} < /select>

public class Actor { Long id; String firstName; String lastName; }

  需要特别说明的有3个地方:
  • 返回值Bean无需为属性设置getter/setter方法,Mybatis依然能够为其赋值;
  • 如果column名称和Bean的属性名只有部分相同,那么只有名称相同的属性会被赋值,Bean依然会被创建;
  • 如果column名称与所有Bean的属性名都不相同,则select语句会返回null值,即使数据库中存在符合查询条件的记录;
  通过resultMap标签指定映射方式待续

    推荐阅读