忙里偷闲,继续上周的话题,记录Mybatis的扩展。
扩展5:设置默认的返回结果类型
大家知道,在Mybatis的sql-mapper配置文件中,我们需要给<select>元素添加resultType或resultMap属性,这两个属性有且只能有一个。2013年我在做一个系统的时候,因为业务关系,查询出的结果集字段经常变化,为了简化处理,采用map作为返回数据的载体,然后不得不在绝大多数<select>元素上添加类似 resultType='java.util.HashMap'(Mybatis有HashMap的简写形式,这里为了更清晰,使用全限定符),于是催生了一个想法,能不能设置默认的返回结果类型?后面经过调试,继承SqlSessionFactoryBean添加如下代码实现:
1 /** 2 * 设置默认的查询结果返回类型 3 * @param configuration 4 * @param cls 5 * @throws Exception 6 */ 7 private void setDefaultResultType(Configuration configuration, Class<?> cls) throws Exception{ 8 try { 9 Field resultMaps = MappedStatement.class.getDeclaredField("resultMaps"); 10 resultMaps.setAccessible(true); 11 for(Iterator<MappedStatement> i = configuration.getMappedStatements().iterator(); i.hasNext();){ 12 Object o = i.next(); 13 /** 14 * 这里添加类型判断,是因为Mybatis实现中还存放了Ambiguity对象(sql-id的最后一段id重复情况下) 15 */ 16 if(o instanceof MappedStatement){ 17 MappedStatement ms = (MappedStatement)o; 18 if(SqlCommandType.SELECT.equals(ms.getSqlCommandType()) && ms.getResultMaps().isEmpty()){ 19 ResultMap.Builder inlineResultMapBuilder = new ResultMap.Builder(configuration,ms.getId()+"-Inline",cls,new ArrayList<ResultMapping>(),null); 20 ResultMap resultMap = inlineResultMapBuilder.build(); 21 List<ResultMap> rm = new ArrayList<ResultMap>(); 22 rm.add(resultMap); 23 resultMaps.set(ms, Collections.unmodifiableList(rm)); 24 }else{ 25 } 26 } 27 } 28 } catch (Exception e) { 29 e.printStackTrace(); 30 throw e; 31 } 32 }