玩转MyBatis: Association & Collection的使用秘籍
2023-12-27 20:23:30
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 开发效率。