ResultMap自定义映射

276 阅读2分钟

使用场景:如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

基本标签属性


<!--
    resultMap:设置自定义映射 
    属性: 
    id:表示自定义映射的唯一标识 
    type:查询的数据要映射的实体类的类型 
    子标签: 
    id:设置主键的映射关系 
    result:设置普通字段的映射关系
    association:设置多对一的映射关系 
    collection:设置一对多的映射关系 
    属性: 
    property:设置映射关系中实体类中的属性名 
    column:设置映射关系中表中的字段名 
--> 
<resultMap id="userMap" type="User"> 
    <id property="id" column="id"></id> 
    <result property="userName" column="user_name"></result> 
    <result property="password" column="password"></result> 
    <result property="age" column="age"></result> 
    <result property="sex" column="sex"></result> 
</resultMap> 
    <!--List<User> testMohu(@Param("mohu") String mohu);--> 
    <select id="testMohu" resultMap="userMap"> 
<!--select * from t_user where username like '%${mohu}%'--> 
    select id,user_name,password,age,sex from t_user where user_name like 
    concat('%',#{mohu},'%') 
</select> 

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系

a>可以通过为字段起别名的方式,保证和实体类中的属性名保持一致

b>可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可

以在查询表中数据时,自动将_类型的字段名转换为驼峰

例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为

userName

多对一映射处理

场景模拟:

查询员工信息以及员工所对应的部门信息

级联方式处理映射关系

<resultMap id="empDeptMap" type="Emp"> 
    <id column="eid" property="eid"></id> 
    <result column="ename" property="ename"></result> 
    <result column="age" property="age"></result> 
    <result column="sex" property="sex"></result> 
    <result column="did" property="dept.did"></result> 
    <result column="dname" property="dept.dname"></result> 
</resultMap> 
    <!--Emp getEmpAndDeptByEid(@Param("eid") int eid);--> 
    <select id="getEmpAndDeptByEid" resultMap="empDeptMap"> 
    select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = 
    dept.did where emp.eid = #{eid} 
</select>

使用association处理映射关系

mybatis进行多表查询时会用上association标签,它的属性包括property,column,javaType等,它的作用是让实体类对象与数据库表的列相互对应,以便让mybatis可以进行多表查询。

<resultMap id="empDeptMap" type="Emp"> 
    <id column="eid" property="eid"></id> 
    <result column="ename" property="ename"></result> 
    <result column="age" property="age"></result> 
    <result column="sex" property="sex"></result> 
<association property="dept" javaType="Dept"> 
	<id column="did" property="did"></id> 
<result column="dname" property="dname"></result> 
</association> 
</resultMap> 
    <!--Emp getEmpAndDeptByEid(@Param("eid") int eid);--> 
<select id="getEmpAndDeptByEid" resultMap="empDeptMap"> 
    select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = 
    dept.did where emp.eid = #{eid} 
</select> 
 <!-- 定义封装account和user的resultMap -->
    <resultMap id="标签的id既名字,可随意" type="查询的主表对应的实体类名称或者实体类路径(如:domain.User)">
        <id property="实体类中表示主键的名称" column="数据库表主键名称"></id>
        <result property="实体类属性" column="数据库表列名"></result>
        <result property="实体类属性" column="数据库表列名"></result>
        <!-- 一对一的关系映射,配置封装user的内容 -->
        <association property="实体类中表示主键的名称" column="另一张表的主键名称" javaType="另一张表对应的实体类">
            <!-- 说明封装的实体类对象 -->
            <id property="主键对应的实体类属性" column="主键名称"></id>
            <result property="实体类属性" column="数据库表列名"/>
            <result property="实体类属性" column="数据库表列名"/>
            <result property="实体类属性" column="数据库表列名"/>
            <result property="实体类属性" column="数据库表列名"/>
            <result property="实体类属性" column="数据库表列名"/>
            <result property="实体类属性" column="数据库表列名"/>
        </association>
    </resultMap>

将标签的属性配置好后,在标签体内部配置id标签和result标签,id标签的property和column属性分别配置实体类属性的主键和数据库表的属性,result标签的property和column属性分别配置实体类属性和数据库表列名,实体类属性和表列名一一对应后,mybatis就可以进行相应的多表查询。

使用Mybatis的association标签的注意事项:

  1. association标签是放在resultMap标签体内部的,在select标签的resultMap属性中配置resultMap标签的id名mybatis方可识别。(注意resultMap标签和resultMap属性是不同的,resultMap标签是一个标签体可以配置id属性和type属性,而resultMap属性是放在标签体内部的,需要配置resultMap标签的id属性)
  2. association标签的javaType属性不能遗漏,不然mybatis将不知道是哪个实体类的属性和实体类表相互对应。