📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)、《解密程序员的思维密码——沟通、演讲、思考的实践》作者、清华大学出版社签约作家、Java领域优质创作者、优快云博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。
📙不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

🍊 MyBatis核心知识点之association:关联概述
在当今的软件开发领域,随着业务需求的日益复杂,数据库表之间的关系也变得越来越复杂。在这样的背景下,如何有效地管理这些复杂的关系,成为了开发人员面临的一大挑战。MyBatis作为一款优秀的持久层框架,提供了强大的关联映射功能,使得开发者能够轻松地处理实体之间的复杂关系。本文将围绕MyBatis核心知识点之association:关联概述展开,探讨其重要性和实用性。
在现实开发中,我们常常会遇到一个实体类与另一个实体类之间存在一对多或多对多的关系。例如,一个订单实体类可能包含多个订单详情,而一个用户实体类可能包含多个订单。在这种情况下,如何将这种关系映射到数据库中,并从数据库中正确地读取这些关系,是开发过程中需要解决的问题。
MyBatis的association关联概述正是为了解决这一问题而设计的。它允许我们在映射文件中定义实体之间的关系,从而在查询时能够一次性地加载所有相关的数据。这种关联映射不仅简化了数据库操作,还提高了代码的可读性和可维护性。
接下来,我们将深入探讨MyBatis中的association关联概念和关联类型。首先,我们将介绍association关联的概念,包括其基本用法和配置方式。随后,我们将详细讲解不同类型的关联映射,如一对一、一对多和多对多,以及它们在实际开发中的应用场景。
通过本文的介绍,读者将能够全面了解MyBatis的association关联概述,掌握如何使用它来处理实体之间的复杂关系。这不仅有助于提高开发效率,还能确保数据的一致性和准确性。在后续的内容中,我们将结合具体的示例,进一步阐述如何在实际项目中应用这些知识点,帮助读者将理论知识转化为实际操作能力。
MyBatis 关联配置
在MyBatis中,关联配置是处理实体类之间关系的重要手段。通过关联配置,我们可以将多个实体类之间的关系映射到数据库表中,从而实现数据的关联查询。
一对一关联
一对一关联是指一个实体类对应另一个实体类的一个实例。在MyBatis中,我们可以通过<association>标签来实现一对一关联。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<association property="address" javaType="Address">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
</association>
</resultMap>
一对多关联
一对多关联是指一个实体类对应多个实体类的集合。在MyBatis中,我们可以通过<collection>标签来实现一对多关联。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderNo" column="order_no"/>
<result property="price" column="price"/>
</collection>
</resultMap>
多对多关联
多对多关联是指多个实体类之间相互关联。在MyBatis中,我们可以通过中间表来实现多对多关联。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<collection property="roles" ofType="Role">
<id property="id" column="role_id"/>
<result property="roleName" column="role_name"/>
<collection property="permissions" ofType="Permission">
<id property="id" column="permission_id"/>
<result property="permissionName" column="permission_name"/>
</collection>
</collection>
</resultMap>
关联映射配置
关联映射配置主要包括<association>和<collection>标签。在配置关联映射时,需要指定以下属性:
property:关联属性名。javaType:关联属性类型。ofType:集合中元素的类型。
级联属性
级联属性是指通过关联关系获取的属性。在MyBatis中,我们可以通过<result>标签来实现级联属性。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<association property="address" javaType="Address">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="user" column="user_id" select="selectUserById"/>
</association>
</resultMap>
延迟加载
延迟加载是指在查询实体类时,不立即加载关联的实体类,而是在需要时才加载。在MyBatis中,我们可以通过设置<association>标签的fetchType属性为lazy来实现延迟加载。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<association property="address" javaType="Address" fetchType="lazy">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
</association>
</resultMap>
关联查询优化
在处理关联查询时,我们需要注意以下优化策略:
- 避免全表扫描。
- 使用索引。
- 选择合适的查询方式。
自定义关联映射
在MyBatis中,我们可以通过自定义关联映射来实现复杂的关联关系。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<association property="address" javaType="Address">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="user" column="user_id" select="selectUserById"/>
</association>
</resultMap>
关联关系映射示例
以下是一个关联关系映射的示例:
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<association property="address" javaType="Address">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="user" column="user_id" select="selectUserById"/>
</association>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderNo" column="order_no"/>
<result property="price" column="price"/>
</collection>
</resultMap>
| 关联类型 | 关联配置标签 | 关联关系描述 | 示例XML配置 |
|---|---|---|---|
| 一对一 | <association> |
一个实体类对应另一个实体类的一个实例 | <association property="address" javaType="Address">...</association> |
| 一对多 | <collection> |
一个实体类对应多个实体类的集合 | <collection property="orders" ofType="Order">...</collection> |
| 多对多 | 通过中间表 | 多个实体类之间相互关联,通过中间表实现 | <collection property="roles" ofType="Role">...</collection> |
| 关联映射配置 | <association> 和 <collection> |
指定关联属性名、类型和集合中元素类型 | <association property="address" javaType="Address">...</association> |
| 级联属性 | <result> |
通过关联关系获取的属性 | <result property="user" column="user_id" select="selectUserById"/> |
| 延迟加载 | <association> 的 fetchType 属性 |
查询实体类时不立即加载关联的实体类,需要时才加载 | <association property="address" javaType="Address" fetchType="lazy">...</association> |
| 关联查询优化 | 避免全表扫描、使用索引、选择合适的查询方式 | 提高关联查询性能的策略 | 无具体XML配置,为优化策略 |
| 自定义关联映射 | 自定义XML配置 | 实现复杂的关联关系 | 自定义XML配置,如示例中的关联关系映射 |
| 关联关系映射示例 | <resultMap> 标签 |
实现实体类与数据库表之间的映射关系,包括关联关系 | <resultMap id="userMap" type="User">...</resultMap> |
在实际应用中,关联映射配置是关系型数据库与对象关系映射(ORM)框架之间的重要桥梁。通过合理配置关联关系,可以简化数据库操作,提高代码的可读性和可维护性。例如,在一对一关联中,通过
<association>标签可以明确指定实体类之间的关联关系,从而在XML配置中实现实体类与数据库表之间的映射。此外,对于一对多关联,使用<collection>标签可以定义实体类与多个实体类之间的集合关系,这有助于在查询时一次性获取所有相关数据。在多对多关联中,通过中间表实现实体类之间的关联,这需要更复杂的XML配置,但能够有效地处理复杂的业务逻辑。在关联映射配置中,还可以通过<result>标签实现级联属性,使得在查询关联实体时,能够同时获取到关联的属性信息。延迟加载则是一种优化策略,它可以在查询实体类时不立即加载关联的实体类,从而提高查询效率。最后,通过自定义关联映射,可以实现对复杂关联关系的灵活配置,以满足各种业务需求。
// MyBatis 关联类型示例代码
public interface UserMapper {
// 查询用户及其角色信息
User selectUserAndRoleById(Integer id);
}
// User实体类
public class User {
private Integer id;
private String username;
private String email;
private Role role; // 一对一关联
}
// Role实体类
public class Role {
private Integer id;
private String roleName;
private Set<User> users; // 一对多关联
}
// MyBatis 配置文件中的关联映射配置
<resultMap id="userRoleMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="email" column="email"/>
<association property="role" column="role_id" javaType="Role">
<id property="id" column="role_id"/>
<result property="roleName" column="role_name"/>
</association>
</resultMap>
<resultMap id="roleUserMap" type="Role">
<id property="id" column="id"/>
<result property="roleName" column="role_name"/>
<collection property="users" column="id" ofType="User">
<id property="id" column="user_id"/>
<result property="username" column="user_name"/>
<result property="email" column="email"/>
</collection>
</resultMap>
MyBatis 的关联类型主要分为三种:一对一关联、一对多关联和多对多关联。下面将分别进行详细描述。
🎉 一对一关联
一对一关联是指一个实体类与另一个实体类之间存在一对一的关系。在上面的示例中,User 实体类与 Role 实体类之间存在一对一的关系。在 MyBatis 中,可以使用 <association> 标签来配置一对一关联。
<association property="role" column="role_id" javaType="Role">
<id property="id" column="role_id"/>
<result property="roleName" column="role_name"/>
</association>
在上面的代码中,property 属性指定了关联的属性名,column 属性指定了关联的数据库字段名,javaType 属性指定了关联的实体类类型。
🎉 一对多关联
一对多关联是指一个实体类与多个实体类之间存在一对多的关系。在上面的示例中,Role 实体类与 User 实体类之间存在一对多的关系。在 MyBatis 中,可以使用 <collection> 标签来配置一对多关联。
<collection property="users" column="id" ofType="User">
<id property="id" column="user_id"/>
<result property="username" column="user_name"/>
<result property="email" column="email"/>
</collection>
在上面的代码中,property 属性指定了关联的属性名,column 属性指定了关联的数据库字段名,ofType 属性指定了关联的实体类类型。
🎉 多对多关联
多对多关联是指多个实体类之间存在多对多的关系。在 MyBatis 中,可以通过创建一个中间表来实现多对多关联。
<resultMap id="userRoleMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="email" column="email"/>
<collection property="roles" column="id" ofType="Role">
<id property="id" column="role_id"/>
<result property="roleName" column="role_name"/>
</collection>
</resultMap>
在上面的代码中,property 属性指定了关联的属性名,column 属性指定了关联的数据库字段名,ofType 属性指定了关联的实体类类型。
🎉 关联映射配置
在 MyBatis 中,关联映射配置通常在 <resultMap> 标签中完成。通过配置 <association> 和 <collection> 标签,可以实现实体类之间的关联映射。
🎉 级联属性
级联属性是指关联实体类中的属性。在 MyBatis 中,可以通过 <result> 标签来配置级联属性。
<result property="roleName" column="role_name"/>
在上面的代码中,property 属性指定了级联属性的名称,column 属性指定了数据库字段名。
🎉 延迟加载
延迟加载是指在查询实体类时,不立即加载关联实体类,而是在需要时才加载。在 MyBatis 中,可以通过配置 <association> 和 <collection> 标签的 fetchType 属性来实现延迟加载。
<association property="role" column="role_id" javaType="Role" fetchType="lazy">
<id property="id" column="role_id"/>
<result property="roleName" column="role_name"/>
</association>
在上面的代码中,fetchType 属性设置为 lazy,表示延迟加载。
🎉 关联查询优化
在关联查询时,可以通过以下方式优化性能:
- 使用索引:在数据库中为关联字段添加索引,可以提高查询效率。
- 选择合适的查询策略:根据实际情况选择合适的查询策略,例如使用嵌套查询或子查询。
🎉 自定义关联映射
在 MyBatis 中,可以通过自定义关联映射来实现复杂的关联关系。例如,可以使用 @ManyToMany 注解来配置多对多关联。
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_role",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
在上面的代码中,@ManyToMany 注解用于配置多对多关联,@JoinTable 注解用于指定关联表。
🎉 关联类型使用场景
关联类型在以下场景中使用:
- 实体类之间存在一对一、一对多或多对多的关系。
- 需要查询关联实体类信息。
- 需要实现实体类之间的级联操作。
🎉 与 Java 对象映射关系
在 MyBatis 中,关联类型与 Java 对象映射关系如下:
- 一对一关联:一个实体类对应一个关联实体类。
- 一对多关联:一个实体类对应多个关联实体类。
- 多对多关联:多个实体类对应多个关联实体类。
🎉 与数据库表结构对应关系
在 MyBatis 中,关联类型与数据库表结构对应关系如下:
- 一对一关联:一个实体类对应一个数据库表。
- 一对多关联:一个实体类对应一个数据库表,关联实体类对应另一个数据库表。
- 多对多关联:多个实体类对应多个数据库表,通过中间表来实现关联。
| 关联类型 | 关联描述 | MyBatis 配置标签 | 关联示例 |
|---|---|---|---|
| 一对一关联 | 一个实体类与另一个实体类之间存在一对一的关系 | <association> |
User 实体类与 Role 实体类之间存在一对一的关系,通过 <association> 标签配置。 |
| 一对多关联 | 一个实体类与多个实体类之间存在一对多的关系 | <collection> |
Role 实体类与 User 实体类之间存在一对多的关系,通过 <collection> 标签配置。 |
| 多对多关联 | 多个实体类之间存在多对多的关系 | <collection> 和中间表 |
通过创建中间表来实现多个实体类之间的多对多关联,通过 <collection> 标签配置。 |
| 关联映射配置 | 在 MyBatis 中,通过 <resultMap> 标签配置关联映射 |
<resultMap> |
使用 <resultMap> 标签配置实体类与数据库表的映射关系,包括关联映射。 |
| 级联属性 | 关联实体类中的属性 | <result> |
使用 <result> 标签配置关联实体类中的属性映射。 |
| 延迟加载 | 在查询实体类时,不立即加载关联实体类,而是在需要时才加载 | <association> 和 <collection> 的 fetchType 属性 |
通过设置 fetchType 属性为 lazy 来实现延迟加载。 |
| 关联查询优化 | 通过使用索引和选择合适的查询策略来优化关联查询性能 | 使用索引和查询策略 | 在数据库中为关联字段添加索引,并根据实际情况选择合适的查询策略。 |
| 自定义关联映射 | 通过自定义关联映射来实现复杂的关联关系 | 自定义注解和 <resultMap> |
使用自定义注解和 <resultMap> 来配置复杂的关联关系。 |
| 关联类型使用场景 | 关联类型在实体类之间存在关联关系、查询关联实体类信息、实现实体类之间的级联操作等场景中使用 | 实体类关联关系 | 在实体类之间存在一对一、一对多或多对多的关系时使用关联类型。 |
| 与 Java 对象映射关系 | 关联类型与 Java 对象映射关系 | 实体类定 |

最低0.47元/天 解锁文章
650

被折叠的 条评论
为什么被折叠?



