返回

玩转MyBatis: Association & Collection的使用秘籍

后端

MyBatis 的 Association 和 Collection:关联映射的黑科技

在使用 MyBatis 操作数据库时,我们经常会遇到一对一、一对多和多对多关系。为了简化这些关系的映射,MyBatis 提供了 Association 和 Collection 两大法宝,帮助我们轻松处理复杂的数据结构。

Association:一对一关系的制胜法宝

Association(关联)用于映射一对一的关系。让我们以 User 和 Card 表为例。User 表中的 card_id 字段是外键,指向 Card 表的主键 id。使用 Association,我们可以轻松地将 User 对象与对应的 Card 对象关联起来。

// User.java
private Card card;

// UserDao.java
@Select("SELECT * FROM tb_user WHERE id = #{id}")
User queryById(Integer id);
<!-- UserDao.xml -->
<select id="queryById" resultMap="UserResultMap">
  SELECT * FROM tb_user WHERE id = #{id}
</select>

<resultMap id="UserResultMap">
  <id column="id" property="id" />
  <result column="name" property="name" />
  <association property="card" column="card_id" select="com.example.mapper.CardMapper.queryById" />
</resultMap>

通过 @Association 注解,我们可以指定 card_id 字段是外键,并通过 select 属性指定要查询 Card 信息的方法。这样,当我们查询 User 时,就会自动加载相关的 Card 信息。

Collection:一对多关系的终极解决方案

Collection(集合)用于映射一对多关系。例如,User 和 Order 表。一个 User 可以有多个 Order。使用 Collection,我们可以轻松地获取 User 的所有 Order。

// User.java
private List<Order> orders;

// UserDao.java
@Select("SELECT * FROM tb_user WHERE id = #{id}")
User queryById(Integer id);
<!-- UserDao.xml -->
<select id="queryById" resultMap="UserResultMap">
  SELECT * FROM tb_user WHERE id = #{id}
</select>

<resultMap id="UserResultMap">
  <id column="id" property="id" />
  <result column="name" property="name" />
  <collection property="orders" column="id" select="com.example.mapper.OrderMapper.queryByUserId" />
</resultMap>

通过 @Collection 注解,我们可以指定 id 字段是外键,并通过 select 属性指定要查询 Order 信息的方法。这样,当我们查询 User 时,就会自动加载相关的 Order 集合。

多对多关系的映射技巧

多对多关系需要使用中间表来建立关系。例如,User 和 Role 表。一个 User 可以有多个 Role,一个 Role 也可以有多个 User。

// User.java
private List<Role> roles;

// Role.java
private List<User> users;
<!-- UserMapper.xml -->
<select id="queryById" resultMap="UserResultMap">
  SELECT * FROM tb_user WHERE id = #{id}
</select>

<resultMap id="UserResultMap">
  <id column="id" property="id" />
  <result column="name" property="name" />
  <collection property="roles" column="id" select="com.example.mapper.RoleMapper.queryByUserId" />
</resultMap>

<!-- RoleMapper.xml -->
<select id="queryByUserId" resultType="com.example.model.Role">
  SELECT * FROM tb_role WHERE id IN (
    SELECT role_id FROM tb_user_role WHERE user_id = #{userId}
  )
</select>
<!-- UserRoleMapper.xml -->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
  INSERT INTO tb_user_role (user_id, role_id) VALUES (#{userId}, #{roleId})
</insert>

<delete id="deleteByUserId" parameterType="int">
  DELETE FROM tb_user_role WHERE user_id = #{userId}
</delete>

<delete id="deleteByRoleId" parameterType="int">
  DELETE FROM tb_user_role WHERE role_id = #{roleId}
</delete>

通过中间表 tb_user_role,我们可以将 User 和 Role 关联起来。当我们查询 User 时,就会自动加载相关的 Role 集合,反之亦然。

常见问题解答

  • 什么是 Association 和 Collection?
    Association 用于映射一对一关系,而 Collection 用于映射一对多和多对多关系。
  • 如何使用 Association 映射一对一关系?
    通过 @Association 注解指定外键字段和要查询的方法。
  • 如何使用 Collection 映射一对多关系?
    通过 @Collection 注解指定外键字段和要查询的方法。
  • 如何映射多对多关系?
    需要使用中间表来建立关系,并通过 Association 或 Collection 映射中间表。
  • Association 和 Collection 的优点是什么?
    简化了复杂关系的映射,提高了代码的可读性和可维护性。

结语

Association 和 Collection 是 MyBatis 中用于映射关系的强大工具。熟练掌握这些技术,可以轻松处理各种复杂的数据结构,提升 MyBatis 开发效率。