多表查询
- 表之间关系划分
数据库中多表之间存在着三种关系,也就是系统设计中的三种实体关系。如下图所示:
- 一对一查询
假设订单和用户的关系是一对一。
需求:查询订单,同时还要查询出订单所属的用户信息。
编写接口
/**
* 根据订单号查询订单信息以及该订单所属的用户
* @param number
* @return
*/
public Order findOrderUserByNumber(@Param("number")String number);
编写mapper文件
<!--
查询订单及对应用户的信息,mybatis不能直接把用户的信息封装到user对象中,需要自定义resultMap
-->
<resultMap type="Order" id="orderUserMap" autoMapping="true">
<id column="id" property="id" />
<!--
association:一对一映射
property属性:Order类中关联的另一方的属性名
javaType属性:Order类中关联的另一方的属性的类型
autoMapping属性:开启自动映射
-->
<association property="user" javaType="User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
</resultMap>
<select id="findOrderUserByNumber" resultMap="orderUserMap">
select * from tb_order a left join tb_user b on a.user_id = b.id where a.order_number = #{number}
</select>
- 一对多查询
假设订单和订单详情的是一对多的关系。
需求:查询订单,同时还要查询出该订单下的订单详情信息。
编写接口
/**
* 根据订单号查询订单信息以及该订单所属的用户及该订单下的详细信息
* @param number
* @return
*/
public Order findOrderUserDetailByNumber(@Param("number")String number);
编写mapper文件
<!--
查询订单及对应用户的信息,mybatis不能直接把用户的信息封装到user对象中,需要自定义resultMap
-->
<resultMap type="Order" id="orderUserDetailMap" autoMapping="true">
<id column="id" property="id" />
<!--
association:一对一映射
property属性:Order类中关联的另一方的属性名
javaType属性:Order类中关联的另一方的属性的类型
autoMapping属性:开启自动映射
-->
<association property="user" javaType="User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
<!--
collection:一对多映射
property属性:Order类中集合属性的名字
javaType属性:集合的类型
ofType属性:集合中元素的类型
-->
<collection property="orderDetails" javaType="list" ofType="OrderDetail" autoMapping="true">
<id column="detail_id" property="id"/>
</collection>
</resultMap>
<!-- 需要给tb_detail表中的id加别名,不然id这个列名会有冲突 -->
<select id="findOrderUserDetailByNumber" 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>
- 多对多查询
订单和商品的是多对多的关系:一个订单中有多个商品,一个商品也属于多个订单。
需求:查询订单,同时还要查询出订单下的商品信息。
编写接口
/**
* 根据订单号查询订单信息以及该订单所属的用户及该订单下的详细信息以及商品信息
* @param number
* @return
*/
public Order findOrderUserDetailItemByNumber(@Param("number")String number);
编写mapper文件
<resultMap type="Order" id="orderUserDetailItemMap" autoMapping="true">
<id column="id" property="id" />
<!--
association:一对一映射
property属性:Order类中关联的另一方的属性名
javaType属性:Order类中关联的另一方的属性的类型
autoMapping属性:开启自动映射
-->
<association property="user" javaType="User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
<!--
collection:一对多映射
property属性:Order类中集合属性的名字
javaType属性:集合的类型
ofType属性:集合中元素的类型
-->
<collection property="orderDetails" javaType="list" ofType="OrderDetail" autoMapping="true">
<id column="detail_id" property="id"/>
<association property="item" javaType="Item" autoMapping="true">
<id column="item_id" property="id"/>
</association>
</collection>
</resultMap>
<select id="findOrderUserDetailItemByNumber" resultMap="orderUserDetailItemMap">
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 left join tb_item d on c.item_id = d.id where a.order_number = #{number}
</select>
- resultMap的继承
有的时候,在一个Mapper文件中会有多个resultMap有着相同的配置,此时我们可以采用继承的形式减少代码的冗余。
<!--
查询订单及对应用户的信息,mybatis不能直接把用户的信息封装到user对象中,需要自定义resultMap
-->
<resultMap type="Order" id="orderUserMap" autoMapping="true">
<id column="id" property="id" />
<!-- association:一对一映射
property属性:Order类中关联的另一方的属性名
javaType属性:Order类中关联的另一方的属性的类型
autoMapping属性:开启自动映射 -->
<association property="user" javaType="User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
</resultMap>
<resultMap type="Order" id="orderUserDetailMap" autoMapping="true" extends="orderUserMap">
<collection property="orderDetails" javaType="list" ofType="OrderDetail" autoMapping="true">
<id column="detail_id" property="id"/>
</collection>
</resultMap>
<resultMap type="Order" id="orderUserDetailItemMap" autoMapping="true" extends="orderUserMap">
<collection property="orderDetails" javaType="list" ofType="OrderDetail" autoMapping="true">
<id column="detail_id" property="id"/>
<association property="item" javaType="Item" autoMapping="true">
<id column="item_id" property="id"/>
</association>
</collection>
</resultMap>