位于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>
评论区