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

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

一对一

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

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

    //---------set/get方法------------
    }
  2. 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方法------------
    }
  3. 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>
  4. 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>
  5. 上面例子解读
    • 根据用户ID查询用户信息,用户信息包含了用户身份证信息(对象),在查用户信息时,返回的结果类型resultMap,名为userMapper
    • 查找ID名为userMapperresultMap,里面有字段映射;Card字段使用的是一对一的关联映射association;调用了DAO里的com.mapper.CardMapper.selectCardById接口方法来查询。
  6. 注解方式实现一对一关系映射
    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方法---------
    }
  2. 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方法---------
    }
  3. 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>
  4. 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;
    }
  2. 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;
    }
  3. 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>
  4. com.mapper.GoodsMapper.xml
    内容同上

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

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

作者

光星

发布于

2018-03-07

更新于

2022-06-17

许可协议

评论