首页 > 技术文章 > Mybatis结果集ResultMap映射

Arno-vc 2020-07-23 10:16 原文

  1. 基本使用:

    解决属性名和数据库字段名不一致的问题

    <resultMap id="user" type="com.guan.bean.UserBean">
        <result column="UPassword" property="password"></result>
    </resultMap>
    
    <select id="getUserList" resultMap="user" parameterType="map">
        select * from user LIMIT #{startIndex},#{numIndex}
    </select>
    

    注:(1).select标签通过resultMap绑定id为user的resultMap标签
    (2).resultMap标签通过id属性进行申明,通过type属性绑定限定类名
    (3).对数据库中的字段column向Bean中的属性property做映射(这里只要写数据库中的字段名和Bean中的属性名不同的部分即可)

  2. 多对一关系(通常存在组合——一个实体类中包含另一个实体类,association)

    类关系:

    //用户类
    public class UserBean {
        private String UId;
        private String UName;
        private int USet;
        private int UAuth;
        private String UPassword;
        private int UState;
    }
    //签到记录类
    public class RecordBean {
        private int RId;
        private UserBean user;
        private String RClick;
        private String RBack;
    }
    //注意两者之间是组合关系
    

    这里需要做表连接查询到签到记录以及做签到记录的用户的信息

    (1).按照sql嵌套查询

    <select id="getUserById" parameterType="String" resultType="userBean">
        SELECT * FROM user WHERE UId = #{UId}
      </select>
    
      <select id="getRecordList" resultMap="record">
        SELECT * FROM record;
      </select>
      
      <resultMap id="record" type="recordBean">
        <association property="user" column="UId" javaType="userBean" select="getUserById"></association>
      </resultMap>
    

    解释:首先是两条独立的选择语句,我们先查询记录,进而通过记录中的UId字段查询用户的信息.它们通过resultMap中的association标签连接.其中property的属性值user是recordBean中的属性,也是getUserById语句的结果,column是用于做外键连接的属性字段,javaType对应的是record类下user属性的类(由于我这里是用package配置的类型别名,所以首字母小写),select的属性值是嵌套调用的select语句.这个标签在于将getRecordList查询语句获得的UId属性值作为参数放入getUserById查询语句中,返会一组用户数据且放在UserBean类中,也就是一个RecordBean实例的user属性下.

    注意:嵌套查询由于是先选定表一的内容,再选表二的内容,所以可以视为左连接

    (2).联表查询

    起别名,之后做结果集的映射即可(好多说这个方法比较简单,但个人并不是很喜欢)

    <!--这里只给出对于recordBean类下的userBean的映射,其它大致相同,其实许多情况下preperty和column不同更符合常理-->
        <resultMap id="record" type="recordBean">
        	<association preoperty="user" javaType="userBean">
        		<result preperty="UId" column="UId">
        	<association>
        </resultMap>
    

    问题:

    (1).resultMap中的标签有什么区别?

    这些元素是结果映射的基础。id 和 result 元素都将一个列的值映射到一个简单数据类型的属性或字段。

    这两者之间的唯一不同是,id 元素对应的属性会被标记为对象的标识符(类似于主键),在比较对象实例时使用。 这样可以提高整体的性能,尤其是进行缓存和嵌套结果映射(也就是连接映射)的时候。

  3. 一对多

    类关系:

    //签到记录类
    public class RecordBean {
        private int RId;
        private UserBean user;
        private String RClick;
        private String RBack;
    }
    //用户类
    public class UserBean {
        private String UId;
        private String UName;
        private int USet;
        private int UAuth;
        private String UPassword;
        private int UState;
        private List<RecordBean> recordList;
    }
    

    (1).按照查询嵌套处理

    注,作为外键的连接字段可能由于被collection使用而无法在resultMap中赋值,需要显式地在resultMap中添加result标签才能看到

    <select id="getUserRecordsById" resultMap="userRecord">
        SELECT * FROM user WHERE UId = #{UId};
      </select>
    
      <resultMap id="userRecord" type="userBean">
        <collection property="recordList" column="UId" javaType="ArrayList" ofType="recordBean" select="getRecordByUId"></collection>
      </resultMap>
    
      <select id="getRecordByUId" resultType="recordBean">
        SELECT * FROM record WHERE UId = #{UId};
      </select>
    

    解释:本质上还是做了嵌套的连接处理,对于第一条语句的内容(为了方便展示,这里只查了一个人的UId,实际情况应该是多人的UId)首先获取用户信息,然后通过UId使用标签做连接.几个重要的属性,property是user的属性recordList,column对应的是结果集中的UId字段,javaType是recordList的类型(这里写的是泛型),比较重要的属性是ofType,其中填写的是泛型的实际类型参数,select属性是嵌套的语句id.注意,getRecordByUId的resultType还是recordBean,这里我在最一开始是犯了错误的.

    (2).按结果嵌套查询(还是起别名,有点累赘,这里不做演示了)

    对于集合中的泛型信息(list<>中的),我们使用ofType获取

  4. 总结

    (1).关联:多对一的关系,如每个学生关联一位班主任

    (2).集合:一对多的关系,如每个班主任对应一个班级的学生集合

    (3).javaType & ofType:在多对一的关系,javaType表示的是那个特殊属性的类;在一对多的关系中,由于对应的是一个集合,javaType通常为泛型ArrayList,ofType表示实际的参数类型

推荐阅读