MyBatis:关联映射(一对一,一对多,多对多)

  实现项目开发中,存在一对一一对多多对多的映射关系,Mybatis对这些映射关系提供了完全的支持。

一对一

一对一关系:一个用户只有一个身份证号码;在数据库上可以建立主外键关联,增加外键唯一约束。

  1. com.entity.Card.java
1
2
3
4
5
6
public class Card{
private Integer id;
private String code;

//---------set/get方法------------
}
  1. com.entity.User.java
1
2
3
4
5
6
7
8
9
10
public class User{
private Integer id;
private String name;
private String sex;
private Integer age;
//身份证号
private Card card;

//---------set/get方法------------
}
  1. com.mapper.CardMapper.xml
1
2
3
4
<!-- 根据ID查询身份证 -->
<select id="selectCardById" parameterType="int" resultType="com.entity.Card">
select * from card where id = #{id}
</select>
  1. com.mapper.UserMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<mapper namespace="com.mapper.UserMapper">
<select id="selectUserById" parameterType="int" resultMap="userMapper">
select * from uer where id = #{id}
</select>
<resultMap type="com.entity.User" id="userMapper">
<id property="id" column="id" />
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<association property="card" column="card_id"
select="com.mapper.CardMapper.selectCardById"
javaType="com.entity.Card"/>
</resultMap>
</mapper>
  1. 上面例子解读
    • 根据用户ID查询用户信息,用户信息包含了用户身份证信息(对象),在查用户信息时,返回的结果类型resultMap,名为userMapper
    • 查找ID名为userMapperresultMap,里面有字段映射;Card字段使用的是一对一的关联映射association;调用了DAO里的com.mapper.CardMapper.selectCardById接口方法来查询。
  2. 注解方式实现一对一关系映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 一对一关联注解:需要关联执行的SQL语句
* fetchType表示查询时是立即加载(eager)还是懒加载(lazy)
* @param id
* @return
*/
@Select("select * from user where id = #{id}")
@Results({
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(column="sex",property="sex"),
@Result(column="age",property="age"),
@Result(column="card_id",property="card",
one=@One(select="com.vending.mapper.CardMapper.selectCardById",
fetchType=FetchType.EAGER))})
User selectUserById(Integer id);

一对多

一对多关系:一个用户有多个订单,一个订单只属于一个用户;数据库可以使用主外键关联,外键在多方,多方维护关系。

  1. com.entity.User
1
2
3
4
5
6
7
8
public class User{

private Integer id;
private String name;
private List<Order> orderList;

//------set/get方法---------
}
  1. com.entity.Order
1
2
3
4
5
6
7
8
9
public class Order{

private Integer id;
private User user;
private Double totalPrice;
private Date createDateTime;

//------set/get方法---------
}
  1. com.mapper.UserMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<mapper namespace="com.mapper.UserMapper">

<!-- 根据用户ID查询订单信息,返回resultMap -->
<select id="selectUserById" parameterType="int" resultMap="userResultMap">
select * from user where id = #{id}
</select>
<resultMap type="com.entity.User" id="userResultMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<!-- 一对多关系,集合使用collection,
fetchType="lazy"表示懒加载,正常情况下,一对多所关联的集合对象,
应设置成lazy,需要用到该属性时再去加载。
-->
<collection property="orderList" javaType="ArrayList"
column="id" ofType="com.entity.Order"
select="com.mapper.OrderMapper.selectOrderByUserId" fetchType="lazy">
<id property="id" column="id"/>
<result property="totalPrice" column="totalPrice"/>
<result property="createDateTime" column="createDateTime"/>
</collection>
</resultMap>
</mapper>
  1. com.mapper.OrderMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<mapper namespace="com.mapper.OrderMapper">

<!-- 根据ID查询订单信息 -->
<select id="selectOderById" parameterType="int" resultMap="orderResultMap">
select * from order o, user u
where o.user_id = u.id
and o.id = #{id}
</select>

<!-- 根据用户ID查询订单信息,返回resultMap -->
<select id="selectOrderByUserId" parameterType="int" resultMap="orderResultMap">
select * from order where user_id = #{id}
</select>

<!-- 映射Order对象的reultMap -->
<resultMap type="com.entity.Order" id="orderResultMap">
<id property="id" column="id"/>
<result property="totalPrice" column="totalPrice"/>
<result property="createDateTime" column="createDateTime"/>
<!-- 一个订单只属于一个用户,一对一,使用association -->
<association property="user" javaType="com.entity.User">
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
</resultMap>

</mapper>

多对多

多对多关系:一个订单中可以购买多种商品,一种商品可以被多个订单购买;多对多关系采用中间表来维护。

  1. com.entity.order
1
2
3
4
5
public class Order{
private Integer id;
private Double total;
private List<Goods> goodList;
}
  1. com.entity.Goods
1
2
3
4
5
6
7
public class Goods{
private Integer id;
private String name;
private Double price;
private String remark;
private List<Order> orderList;
}
  1. com.mapper.OrderMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<mapper namespace="com.mapper.OrderMapper">
<select id="selectOrderById" parameterType="int" resultMap="orderResultMap">
select o.id as orderId from order o where id = #{id}
</select>
<resultMap type="com.entity.Order" id="orderResultMap">
<id property="id" column="id"/>
<result property="total" column="total"/>
<!-- 多对多映射:collection -->
<collection property="goodList" javaType="ArrayList"
column="orderId" ofType="com.entity.Goods"
select="com.mapper.GoodsMapper.selectGoodsListByOrderId">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
<result property="remark" column="remark"/>
</collection>
</resultMap>
</mapper>
  1. com.mapper.GoodsMapper.xml
    内容同上

MyBatis:关联映射(一对一,一对多,多对多)

http://blog.gxitsky.com/2018/03/07/MyBatis-10-relationMapping/

作者

光星

发布于

2018-03-07

更新于

2022-06-17

许可协议

评论