mybatis resultmap 如何为对象赋值的调用顺序

resultmap 为对象赋值的调用顺序

写了一个mybatis的mapper映射文件,

java bean定义如下

public class GroupCourseResult extends GroupResult {
    private String cid;
    private String cname;
    public GroupCourseResult(int stuschool, int nian, String stuclass, String cid, String cname) {
        super(stuschool, nian, stuclass);
        this.cid = cid;
        this.cname = cname;
    }
    public String getCid() {
        return cid;
    }
    public void setCid(String cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
}

部分mybatis映射文件如下

实体类中的属性名和查询的列名完全匹配,但是没有查询stuclass,则封装后的实体类中的stuclass属性应该为空。

然而程序运行后,stuclass属性不仅不为空,还与cname完全相同,百思不得其解,故翻了翻mybatis的源码。

在mybatis中的DefaultResultSetHandler类中,

createResultObject方法的代码如下

  private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List> constructorArgTypes, List constructorArgs, String columnPrefix)
      throws SQLException {
    final Class resultType = resultMap.getType();
    final MetaClass metaType = MetaClass.forClass(resultType, reflectorFactory);
    final List constructorMappings = resultMap.getConstructorResultMappings();
    if (hasTypeHandlerForResultObject(rsw, resultType)) {
      return createPrimitiveResultObject(rsw, resultMap, columnPrefix);
    } else if (!constructorMappings.isEmpty()) {
      return createParameterizedResultObject(rsw, resultType, constructorMappings, constructorArgTypes, constructorArgs, columnPrefix);
    } else if (resultType.isInterface() || metaType.hasDefaultConstructor()) {
      return objectFactory.create(resultType);
    } else if (shouldApplyAutomaticMappings(resultMap, false)) {
      return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs);
    }
    throw new ExecutorException("Do not know how to create an instance of " + resultType);
  }


经过调试发现,mybatis会先查找该javabean有无默认构造方法,如果有则采用设值注入,若没有,则根据javabean的有参构造方法进行设值,而在8以前的jdk版本中,我们利用反射只能获取到参数类型,不能获取到参数名称,这其中设值可能出现了匹配失误,将cname的值同时赋给了cname和stuclass。

想要解决这个问题,只须在javabean中添加默认构造方法即可。

使用resultMap时需注意的问题

如果是实体中是直接引用别的对象的具体参数字段,

直接用原始方式就行

    
        
        
        
        
        
        
        
        
        
        
    
    
    

如果是实体中是list集合

    
    	
        
        
        
        
        
        
        
        
        
        
        
            
        
    
    
    

如果实体中引用的是别的对象,

使用association 标签来写

    
        
        
        
        
        
        
        
        
        
	        
	        
	        
        
    
    
    

如果实体中是引用的别的对象的list集合,

应该使用collection标签


        
        
        
        
        
        
        
        
        
            
            
            
        
    
    

tips:

使用resultMap的时候,应该直接用as后面的字段名,即自己命的名字

如果没有使用as的话,直接使用数据库中原本的名字

resultMap中各个标签的含义

mybatis resultmap 如何为对象赋值的调用顺序_第1张图片

tips:

在一个 resultMap 元素中,这些子元素出现的先后顺序是有严格规定的,它们从前到后依次是:constructor–>id --> result–> association–>collection -->discriminator, 不然就会报错。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

你可能感兴趣的:(mybatis resultmap 如何为对象赋值的调用顺序)