Mybatis---ResultMap

ResultMap

resultMap元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码。ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

一、字段映射

如果数据库中表的字段与User类的属性名称一致,我们就可以使用resultType来返回。但是当数据库中的字段名称 和 对象中的属性名称不一致时,就需要resultMap属性。

<!-- 最强大对象resultMap,结果封装到哪个pojo对象,type就是谁 -->

    <resultMap type="Person" id="personRM">

       <!-- 主键,property是对象的属性名,column是表里的字段名 -->

       <id property="id" column="id"/>

       <!-- 普通字段 -->

       <result property="userName" column="user_name"/>

    </resultMap>

    <!-- 查询所有 -->

<select id="find"  resultMap="personRM">

SELECT id,user_name FROM person WHERE id=#{id}

</select>

这里面column对应的是数据库的列名或别名;property对应的是结果集的字段或属性。

这就是resultMap最简单,也最基础的用法:字段映射。

自动匹配驼峰规则:

数据库字段: is_man
Javabean属性: private Integer isMan
mapper配置不需要写字段与属性的配置,会自动映射
注意:主键需要单独写,其它字段就可以直接利用驼峰规则自动映射。

mybatis:
  configuration:
    map-underscore-to-camel-case: true

二、构造方法:

如果你希望将结果注入构造方法里,就可以用到constructor元素。

<resultMap id="getUserByIdMap" type="User">
	<constructor>
	<!-- column代表数据库字段 name代表构造方法中的参数 javaType代表数据类型 -->
		<idArg column="id" name="id" javaType="string"></idArg>
		<arg column="username" name="name" javaType="string"></arg>
	</constructor>
</resultMap>

三、对象关系:

分为一对一和一对多,分别使用resultMap提供的不同方案来处理:

1, 一对一:使用association + javaType

2, 一对多:使用collection + ofType

一对一:

比如说一个User对象对应一个身份:管理员、游客、用户等。

主实体类中要有一个关系类的字段:

private UserExtra userExtra;

和对应的get,set方法,association 将查询结果封装成对象并返回到这个字段。


    <resultMap type="UserInfo" id="One21RM">

       <!-- 描述主表 -->

       <id column="id" property="id"/>

       <result column="user_name" property="userName"/>

       <result column="user_age" property="userAge"/>

       <result column="user_addr" property="userAddr"/>

       <!-- 描述 一对一的 UserExtra  association+javaType固定搭配 -->

           <association property="userExtra"  javaType="UserExtra">

              <id column="id" property="id"/>

              <result column="user_id" property="userId"/>

              <result column="work" property="work"/>

              <result column="salary" property="salary"/>

           </association>

    </resultMap>

    <!-- 多表查询 -->

    <select id="One21" resultMap="One21RM">

       select * from user_info a,user_extra b

       where a.id=b.user_id and a.id=#{id}

    </select>

一对多:

比如说一个User对象对应多种身份,一个User既是管理员同时也是用户。

主实体类中要有一个关系类的字段,用List接收:

private List<UserExtra> userExtras;
 <!-- 根据用户查询用户详情 -->

    <resultMap type="cn.tedu.pojo.UserInfo" id="userRM">

       <id column="id" property="id"/>

       <result column="user_name" property="userName"/>

       <result column="user_addr" property="userAddr"/>

       <result column="user_age" property="userAge"/>

    </resultMap>

   

    <!-- 一对一 -->

    <resultMap type="cn.tedu.pojo.UserInfo" id="userExtraRM" extends="userRM">

       <association property="userExtra" javaType="cn.tedu.pojo.UserExtra">

           <id column="id" property="id"/>

           <result column="user_id" property="userId"/>

           <result column="work" property="work"/>

           <result column="salary" property="salary"/>

       </association>

    </resultMap>

   

    <!-- 根据用户id查询用户详情 -->

    <select id="findExtraByUser" resultMap="userExtraRM">

       select * from

       userinfo t1,userextra t2

       where

       t1.id=t2.user_id

       and t1.id=#{id}

    </select>

   

<!-- 一对多 -->

    <resultMap type="cn.tedu.pojo.UserInfo" id="ordersRM" extends="userRM">

       <collection property="orders" ofType="cn.tedu.pojo.Orders">

           <id column="id" property="id"/>

           <result column="user_id" property="userId"/>

           <result column="order_no" property="orderNo"/>

           <result column="order_desc" property="orderDesc"/>

           <result column="price" property="price"/>

       </collection>

    </resultMap>

四、自动填充关联对象

我们知道,在Mybatis解析返回值的时候。
第一步是获取返回值类型,拿到Class对象,然后获取构造器,设置可访问并返回实例,然后又把它包装成MetaObject对象。
从数据库rs中拿到结果之后,会调用MetaObject.setValue(String name, Object value) 来填充对象。
在这过程中,有趣的是,它会以.来分隔这个name属性。
如果name属性中包含.符号,就找到.符号之前的属性名称,把它当做一个实体对象来处理。

<select id="getUserList" resultType="User">
	SELECT
		u.id,
		u.username,
		u.password,
		u.address,
		u.email,
		r.id as 'role.id',
		r.name as 'role.name'
	FROM
		USER u
			LEFT JOIN user_roles ur ON u.id = ur.user_id
			LEFT JOIN role r ON r.id = ur.role_id
</select>

这样,在Mybatis解析到role.id属性的时候,以.符号分隔之后发现,role别名对应的是Role对象,则会先初始化Role对象,并将值赋予id属性。

上一篇:PostgreSQL角色问题


下一篇:射击操作实现