侧边栏壁纸
博主头像
Curllen博主等级

早上的云霞好美~

  • 累计撰写 12 篇文章
  • 累计创建 18 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

mybatis系列(四) maybatis强大特性之resultMap

Curllen
2018-11-03 / 0 评论 / 0 点赞 / 1,012 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2020-05-06,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

位于sql语句所在的映射文件中(也可以抽取为一个单独的映射文件),mybatis最强大的功能, 多用于多表查询的情景

解决两大问题

  • POJO属性名和表结构字段名不一致的问题(有些情况下也不是驼峰格式)
  • 完成高级查询,包括但是不限于: 一对一、一对多、多对多.

在映射文件中定义

<!-- resultMap:自定义映射关系
		属性:type-结果集的封装类型,id-唯一标识,autoMapping-开启自动匹配,如果开启了驼峰匹配,就以驼峰匹配的形式进行匹配
		id:指定主键映射的,不要省。提高性能
		result:其他的非主键普通字段
			子标签的属性:Column-表中的字段名,property-对应的java属性名
	 -->
	<resultMap type="User" id="userMap" autoMapping="true">
		<!-- 数据库表的主键uid映射id, 即使相同也不要省,提高性能 -->
		<id column="uid" property="id"/>
		<!-- 数据库表的普通字段user_name映射userName -->
		<result column="user_name" property="userName"/>
	</resultMap>

自定义resultMap中,主键需要通过id子标签配置,表字段和属性名不一致的普通字段需要通过result子标签配置。
那么,字段名称匹配的字段要不要配置那?
这个取决于resultMap中的autoMapping属性的值:
为true时:resultMap中的没有配置的字段会自动对应。
为false时:只针对resultMap中已经配置的字段作映射。
并且resultMap会自动映射单表查询的结果集(结果是个集合,自定义resultMap,其type="实体类", 集合里存储的是pojo, 故一般而言,任何的select语句都可以使用map存储)。

在映射文件中的使用

在select等标签中,通过rsultMap="自定义的resultMap的id名"来使用

resulttMap其他参数解析

所有参数

<resultMap>
      <constructor>
         <idArg/>
         <arg/>
      </constructor>
      <id/>
      <result/>
      <association/>
      <collection/>
      <discriminator >
          <case/>
      </discriminator>
   </resultMap>
  • constructor元素

用于配置构造方法。一个pojo可能不存在没有参数的构造方法,则使用constructor进行配置。假设RoleBean不存在没有参数的构造方法,它的构造方法声明为public Role(Integer id,String roleName)

<resultMap ...>
      <constructor>
         <idArg column="id" javaType="int"/>
         <arg column="role_name" javaType="string"/>
      </constructor>
</resultMap>
  • mybatis中级联(高级查询)分为这么三种:association,collection和discriminator
    • association:代表一对一关系,作用: 将关联查询信息映射到一个pojo类中
    • collection:代表一对多关系,作用: 将关联查询信息映射到一个list集合中
    • discriminator:鉴别器,它可以根据实际选择采用哪个类作为实例,允许根据特定的条件去关联不同的结果集。比如,人有男人和女人,可以实例化一个对象,但是根据情况用男人类或者女人类去实例化

association
实体类

public class Order implements Serializable {
  private Integer id;

  private Long userId;

  private String orderNumber;
  
  //关联用户信息
  private User user;
    
  //订单明细
  private List<Orderdetail> orderdetails;
 ...省略get/set方法...

SQL语句所在映射文件

<resultMap type="Order" id="orderUserMap" autoMapping="true">
		<id column="id" property="id"/>
		<!-- 
			association:一对一的映射
			property:java的属性名
			javaType:属性名对应的java类型
			autoMapping:开启自动映射
			子标签:参照resultMap
		 -->
		<association property="user" javaType="User" autoMapping="true">
			<id column="user_id" property="id"/>
		</association>
	</resultMap>
	
	<!-- resultType不能完成user信息的映射,必须使用resultMap,resultMap的值对应resultMap标签的id,resultMap和resultType必须二选一 -->
	<select id="queryOrderWithUser" resultMap="orderUserMap">
		select * from tb_order a 
			LEFT JOIN tb_user b on a.user_id=b.id
		where a.order_number = #{number}
	</select>

collection(例1把resultMap抽取为一个单独的映射文件)

  • 例1:

实体类

public class Orders implements Serializable {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //关联用户信息
    private User user;
    
    //订单明细
    private List<Orderdetail> orderdetails;
    ...省略get/set方法...

抽取出来的单独映射文件

<!-- 一对多,查询订单及订单明细 -->
	<resultMap type="orders" id="orderAndOrderDetails" extends="ordersUserResultMap">
		<!-- 映射订单信息,和用户信息,这里使用继承ordersUserResultMap -->
		
		<!-- 映射订单明细信息 
		property:要将关联信息映射到orders的哪个属性中
		ofType:集合中pojo的类型
		-->
		<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
			<!-- id:关联信息订单明细的唯 一标识
			property:Orderdetail的属性名
			  -->
			<id column="orderdetail_id" property="id"/>
			<result column="items_num" property="itemsNum"/>
			<result column="items_id" property="itemsId"/>
		</collection>
	
	</resultMap>
  • 例2

实体类

public class Order implements Serializable {
  private Integer id;

  private Long userId;

  private String orderNumber;
  
  //关联用户信息
  private User user;
    
  //订单明细
  private List<Orderdetail> orderdetails;
 ...省略get/set方法...

SQL语句所在映射文件

<resultMap type="Order" id="orderUserDetailMap" autoMapping="true">
		<id column="id" property="id"/>
		<association property="user" javaType="User" autoMapping="true">
			<id column="user_id" property="id"/>
		</association>
		<!-- 
			collection:一对多的查询
			property:属性名
			javaType:集合类型(可以省略?)
			ofType:集合中的元素类型
			autoMapping:开启自动映射
			子标签:参照resultMap
		 -->
		<collection property="detailList" javaType="list" ofType="Orderdetail" autoMapping="true">
			<id column="detail_id" property="id"/>
		</collection>
	</resultMap>
	
	<select id="queryOrderWithUserDetail" resultMap="orderUserDetailMap">
		select *,c.id as detail_id from tb_order a
			LEFT JOIN tb_user b on a.user_id=b.id
			LEFT JOIN tb_orderdetail c on a.id=c.order_id
		where a.order_number=#{number}
	</select>

0

评论区