MyBatis的注解实现复杂映射开发
xml 配置方式实现复杂映射回顾
实现复杂映射我们之前可以在映射文件中通过配置来实现,使用注解开发后,我们可以通过 @Results
注解,@Result
注解,@One
注解和 @Many
注解组合完成复杂关系的配置。
注解 | 说明 |
---|---|
@Results |
代替的是标签 使用方式: @Results({@Result(), @Result()}) 或者 @Results(@Result()) |
@Result |
代替了 @Result 中的属性介绍 column:数据库中的列名 property:要装配的属性名 one:需要使用 @One 注解( @Result(one=@One)() )many:需要使用 @Many 注解( @Result(many=@many)() ) |
@One(一对一) | 代替了 @One 注解属性介绍 select:指定用来多表查询的 sqlmapper 使用格式: @Result(column="", property="", one=(select="")) |
@Many(多对一) | 代替了 使用格式: @Result(property="", column="", many=@many(select="")) |
一对一查询
一对一查询的模型
用户表和订单表的关系为,一个用户有多个订单,一共订单只属于一个用户
一对一查询需求:查询一个订单,与此同时查询该订单对应的用户
1 | @startuml |
一对一查询的语句
对应的 sql 语句
1 | select * from orders; |
查询结果如下:
id | ordertime | total | uid | id | username | password | birthday |
---|---|---|---|---|---|---|---|
1 | 2019-12-12 | 3000 | 1 | 1 | lucy | 123 | 2019-12-12 |
2 | 2019-12-12 | 4000 | 1 | 1 | lucy | 123 | 2019-12-12 |
3 | 2019-12-12 | 5000 | 2 | 1 | lucy | 123 | 2019-12-12 |
1 | 2019-12-12 | 3000 | 1 | 2 | tom | 123 | 2019-12-12 |
创建 User 和 Order 实体
1 | /** |
创建 IOrderMapper 接口
1 | /** |
使用注解配置接口
1 | /** |
1 | /* |
测试结果
1 | /** |
效果
1 | Opening JDBC Connection |
调用过程分析
一对多查询
一对多查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户。
一对多查询需求:查询一个用户,与此同时查出该用户具有的订单。
1 | @startuml |
一对多查询语句
对应查询语句:
对应的 sql 语句
1 | select * from user; |
查询结果如下:
id | ordertime | total | uid | id | username | password | birthday |
---|---|---|---|---|---|---|---|
1 | 2019-12-12 | 3000 | 1 | 1 | lucy | 123 | 2019-12-12 |
2 | 2019-12-12 | 4000 | 1 | 1 | lucy | 123 | 2019-12-12 |
3 | 2019-12-12 | 5000 | 2 | 1 | lucy | 123 | 2019-12-12 |
1 | 2019-12-12 | 3000 | 1 | 2 | tom | 123 | 2019-12-12 |
修改 User 实体
1 | /** |
1 | /** |
创建IUserMapper接口
1 | /** |
使用注解配置Mapper
1 | /** |
1 | /** |
测试结果
1 | public class IUserMapperTest { |
结果如下:
1 | Opening JDBC Connection |
多对多查询
多对多查询的模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用。
1 | @startuml |
多对多查询需求
查询用户的同时查询该用户对应的角色。
多对多查询的语句
1 | select * from user; |
查询结果如下:
id | rolename | roleDesc | userid | roleid |
---|---|---|---|---|
1 | CTO | CTO | 1 | 1 |
2 | CEO | CEO | 1 | 2 |
代码实现
创建User实体和Role实体
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60/**
* 用户
*
* @name: User
* @author: terwer
* @date: 2022-05-25 13:25
**/
public class User {
private Integer id;
private String username;
// 代表当前用户具备那些订单
private List<Order> orderList;
// 代表当前用户具备的那些角色
private List<Role> roleList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", orderList=" + orderList +
", roleList=" + roleList +
'}';
}
}创建IRoleMapper
1
2
3
4
5
6
7
8
9
10
11/**
* 角色映射
*
* @name: IRoleMapper
* @author: terwer
* @date: 2022-09-06 00:04
**/
public interface IRoleMapper {
List<Role> findRolesByUserId(Integer userId);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/**
* 角色
*
* @name: Role
* @author: terwer
* @date: 2022-05-12 14:14
**/
public class Role {
private Integer id;
private String rolename;
public String toString() {
return "Role{" +
"id=" + id +
", rolename='" + rolename + '\'' +
'}';
}
}修改IUserMapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/**
* 用户映射
*
* @name: IUserMapper
* @author: terwer
* @date: 2022-05-25 13:27
**/
public interface IUserMapper {
List<User> findUserAndRole();
}添加测试方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class IUserMapperTest {
private IUserMapper userMapper;
private SqlSession sqlSession;
public void before() throws Exception {
System.out.println("before...");
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
// 这样也是可以的,这样的话后面就不用每次都设置了
// sqlSession = sqlSessionFactory.openSession(true);
userMapper = sqlSession.getMapper(IUserMapper.class);
}
public void testFindUserAndRole() {
userMapper.findUserAndRole().forEach(user -> {
System.out.println(user);
});
}
}效果如下
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
28
29
30
31
32
33Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@51e5fc98]
==> Preparing: select * from user
==> Parameters:
<== Columns: id, username, password, birthday
<== Row: 1, lucy, 123, 2019-12-12
====> Preparing: select * from sys_role r,sys_user_role ur where r.id=ur.roleid and ur.userid=?
====> Parameters: 1(Integer)
<==== Columns: id, rolename, roleDesc, userid, roleid
<==== Row: 1, CTO, CTO, 1, 1
<==== Row: 2, CEO, CEO, 1, 2
<==== Total: 2
<== Row: 2, tom, 123, 2019-12-12
====> Preparing: select * from sys_role r,sys_user_role ur where r.id=ur.roleid and ur.userid=?
====> Parameters: 2(Integer)
<==== Columns: id, rolename, roleDesc, userid, roleid
<==== Row: 1, CTO, CTO, 2, 1
<==== Row: 2, CEO, CEO, 2, 2
<==== Total: 2
<== Row: 8, 测试2, null, null
====> Preparing: select * from sys_role r,sys_user_role ur where r.id=ur.roleid and ur.userid=?
====> Parameters: 8(Integer)
<==== Total: 0
<== Row: 9, 测试3, null, null
====> Preparing: select * from sys_role r,sys_user_role ur where r.id=ur.roleid and ur.userid=?
====> Parameters: 9(Integer)
<==== Total: 0
<== Total: 4
User{id=1, username='lucy', orderList=null, roleList=[Role{id=1, rolename='CTO'}, Role{id=2, rolename='CEO'}]}
User{id=2, username='tom', orderList=null, roleList=[Role{id=1, rolename='CTO'}, Role{id=2, rolename='CEO'}]}
User{id=8, username='测试2', orderList=null, roleList=[]}
User{id=9, username='测试3', orderList=null, roleList=[]}
Process finished with exit code 0
文章更新历史
2022-08-30 feat:初稿