♨️本篇文章记录的为Mybatis多表操作相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。
♨️如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛💖个人主页 : 阿千弟
如果大家对mybatis
相关知识感兴趣请点击这里👉👉👉mybatis专栏学习
目标 :
快速掌握Mybatis中的多表操作
(一对一, 一对多, 多对多), 查询过程
,查询结果
.以及学习 < association >
和 < collection >
关键属性的应用👍👍👍
@[TOC]
关联关系概述
先来回顾一下, 在关系型数据库中, 多表之间存在三种关联关系, 分别是一对一, 一对多, 多对一, 如图所示
一对一
: 共用同一主键或在任意一方引入对方主键作为外键一对多
: 在 "多" 的一方, 添加 "一" 的一方的主键作为外键多对多
: 产生中间关系表, 引入两张表的主键作为外键, 两个主键成为联合主键
在Java中,通过对象也可以进行关联关系描述
一对一
: 在本类中定义对方类型的对象, 如A类中定义B类类型的属性b, B类中定义A类类型的属性a
一对多
: 一个A类类型对应多个B类类型的情况, 需要在A类中以集合的方式引入B类类型的对象, 在B类中定义A类类型的属性a
多对多
: 在A类中定义B类类型的集合, 在B类中定义A类类型的集合
一对一
现实中一对一的关系是十分常见的.
例如,一个人只能有一个身份一个身份证对应一个人 证,同时一个身份证也只会对应一个人。
元素中,包含了一个那么使用MyBatis是怎么处理图中的这种一对一关联关系的呢?
< association >
子元素,MyBatis就是通过该元素来处理一对一关联关系的。
### < association > 属性
| 属性 | 描述|
|--|--|
|
property
| 指定映射到的实体类对象属性,与表字段一一对应 |
|
column
| 指定表中对应的字段 |
|
javaType
| 指定映射到实体对象属性的类型 |
|
select
| 指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询 |
|
fetchType
| 指定在关联查询时是否启用延迟加载。该属性有
lazy
和
eager
两个
fetchType 属性值,默认值为
lazy
(
即默认关联映射延迟加载) |
### 代码展示:
在关系表中, 一张订单只能对应一个用户, 就用
Order
和
User
进行演示
数据库中的user表
对应的user实体类
java public class User { private int id; private String username; private String password; }
数据库中的order表
>
对应的order实体类
java public class Order { private int id; private double count; //代表当前订单从属于哪一个客户 private User user; }
OrderMapper
java public interface OrderMapper { List<Order> findAll(); }
OrderMapper.xml
这里我们使用嵌套结果
```java
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
" http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<select id="findAll" resultMap="orderMap">
select u.`u_name`, u.`u_password`, o.`o_id`, o.`o_count` from orders o,user u where o.u_id=u.u_id;
</select>
### <font color="#3D59AB "> 演示结果:</font>
```java
@Autowired
private OrderMapper orderMapper;
@Test
public void findAllTest() {
List<Order> orderList = orderMapper.findAll();
for (Order order : orderList) {
System.out.println(order);
}
}
一对多
开发人员接触更多的关联关系是一对多(或多对一)。例如,一个用户可以有多个订单,同时多个订单归一个用户所有。
那么使用MyBatis是怎么处理这种一对多关联关系的呢?
< resultMap >
元素中,包含了一个< collection >
子元素,MyBatis就是通过该元素来处理一对多关联关系的。< collection >
子元素的属性大部分与 < association >
元素相同,但其还包含一个特殊属性 ofType
。
ofType
属性与javaType
属性对应,它用于指定实体对象ofType
中集合类属性所包含的元素类型。代码展示:
User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String username;
private String password;
@TableField(exist = false)
List<Order> orderList;
}
Order
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private int id;
private double count;
//代表当前订单从属于哪一个客户
private User user;
}
UserMapper
public interface UserMapper {
List<User> findAllOrders();
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jrmedu.mapper.UserMapper">
<resultMap id="userMap" type="com.jrmedu.entity.User">
<result column="u_id" property="id"></result>
<result column="u_name" property="username"></result>
<result column="u_password" property="password"></result>
<collection property="orderList" ofType="com.jrmedu.entity.Order">
<result column="o_id" property="id"></result>
<result column="o_count" property="count"></result>
</collection>
</resultMap>
<select id="findAllOrders" resultMap="userMap">
select u.`u_name`, o.`o_id`, o.`o_count` from user u left join orders o on u.u_id=o.u_id
</select>
</mapper>
演示结果:
测试
@Autowired
private UserMapper userMapper;
@Test
public void findAllOrdersTest() {
List<User> userList = userMapper.findAllOrders();
for (User user : userList) {
System.out.println(user.getUsername());
List<Order> orderList = user.getOrderList();
for (Order order : orderList) {
System.out.println(order);
}
System.out.println("----------------------------------");
}
}
结果如图
多对多
- 多对多查询的模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使
多对多查询的需求:查询用户同时查询出该用户的所有角色
代码展示:
User
@Data
public class User {
private int id;
private String username;
private String password;
@TableField(exist = false)
List<Order> orderList;
List<Role> roleList;
}
Role
@Data
public class Role {
private Integer id;
private String name;
private String description;
List<User> userList;
}
RoleMapper
public interface RoleMapper {
List<User> findAllUserAndRole();
}
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jrmedu.mapper.RoleMapper">
<resultMap id="userRoleMap" type="com.jrmedu.entity.User">
<result column="u_id" property="id"></result>
<result column="u_name" property="username"></result>
<result column="u_password" property="password"></result>
<collection property="roleList" ofType="com.jrmedu.entity.Role">
<result column="id" property="id"></result>
<result column="roleName" property="name"></result>
<result column="roleDesc" property="description"></result>
</collection>
</resultMap>
<select id="findAllUserAndRole" resultMap="userRoleMap">
select u.`u_name`,r.* from user u left join user_role ur on
u.u_id=ur.userid
left join role r on ur.roleid =r.id
</select>
</mapper>
演示结果:
测试
@Autowired
private RoleMapper roleMapper;
@Test
public void findAllRolesTest() {
List<User> userList = roleMapper.findAllUserAndRole();
for(User user : userList){
System.out.println(user.getUsername());
List<Role> roleList = user.getRoleList();
for(Role role : roleList){
System.out.println(role);
}
System.out.println("----------------------------------");
}
}
嵌套过程 & 嵌套结果:
MyBatis加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果。
| 嵌套查询
| 嵌套结果
|
|--|--|
| 嵌套查询是通过执行另外一条SQL映射语句来返回预期的复杂类型。 | 嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。 |
| 嵌套查询是在查询SQL中嵌入一个子查询SQL; | 嵌套结果是一个嵌套的多表查询SQL; |
| 嵌套查询会执行多条SQL语句; | 嵌套结果只会执行一条复杂的SQL语句; |
| 嵌套查询SQL语句编写较为简单; | 嵌套结果SQL语句编写比较复杂; |
虽然使用嵌套查询的方式比较简单,但是嵌套查询的方式要执行多条SQL语句,这对于大型数据集合和列表展示不是很好,因为这样可能会导致成百上千条关联的SQL语句被执行,从而极大的消耗数据库性能并且会降低查询效率。
使用MyBatis的延迟加载在一定程度上可以降低运行消耗并提高查询效率
。
MyBatis默认没有开启延迟加载,需要在核心配置文件中的元素内进行
配置,具体配置方式如下:
< settings >
< setting name="lazyLoadingEnabled" value="true" />
< setting name="aggressiveLazyLoading" value="false"/>
< /settings >
MyBatis多表配置方式:
一对一配置:使用 < resultMap > 做配置一对多配置:使用< resultMap > + < collection > 做配置
多对多配置:使用 < resultMap > + < collection > 做配置
如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对Java后端或者对mybatis
感兴趣的朋友,请多多关注💖💖💖
💖个人主页:阿千弟
如果大家对mybatis
相关知识感兴趣请点击这里👉👉👉mybatis专栏学习