一、模拟的业务查询
系统中的用户user都有唯一对应的地址信息address,每个用户可以有多量车car,类似如下结构
1
2
3
4
5
|
|-- user |-- address |-- carList |-- car1 |-- car2 |
二、对应的实体类如下
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
|
@Data public class AddressPO { private Long id; /** * 省份 */ private String province; /** * 城市 */ private String city; /** * 街道 */ private String street; } @Data public class CarPO { private Long id; /** * 颜色 */ private String color; /** * 品牌 */ private String name; private Long userId; } @Data public class UserPO extends AbstractPO { private Long id; private String username; private String password; private Integer age; private GenderEnum gender; /** * 地址信息,和用户是一对一的关系 */ private AddressPO address; /** * 地址id */ private Long addressId; /** * 用户拥有的车,和用户是一对多的关系 */ private List<CarPO> cars; } |
三、对应的建表语句和模拟数据如下
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
|
CREATE TABLE IF NOT EXISTS ` user ` ( `id` int (11) NOT NULL AUTO_INCREMENT COMMENT '主键' , `username` varchar (20) NOT NULL UNIQUE COMMENT '用户名' , ` password ` varchar (50) NOT NULL COMMENT '密码' , `age` int (2) NOT NULL COMMENT '年龄' , `gender` varchar (10) NOT NULL COMMENT '性别' , `address_id` int (11) DEFAULT NULL COMMENT '地址' , `creater` varchar (20) DEFAULT NULL COMMENT '创建人' , `modifier` varchar (20) DEFAULT NULL COMMENT '更新人' , `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' , `modify_time` datetime NOT NUll DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间' , PRIMARY KEY (`id`), KEY `index_gender` (`gender`) USING BTREE COMMENT '性别' ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin; CREATE TABLE IF NOT EXISTS `address` ( `id` int (11) NOT NULL AUTO_INCREMENT, `province` varchar (50) DEFAULT NULL , `city` varchar (50) DEFAULT NULL , `street` varchar (50) DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin; CREATE TABLE IF NOT EXISTS `car` ( `id` int (11) NOT NULL AUTO_INCREMENT, `color` varchar (50) DEFAULT NULL , ` name ` varchar (50) DEFAULT NULL , `user_id` int (11) DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin; INSERT INTO ` user `(username, password , age, gender, address_id) VALUES ( 'KimZing' , '123456' , '25' , 'MAN' , 1), ( 'kim' , '123456' , '25' , 'MAN' , 2); INSERT INTO `address` VALUES ( '1' , '北京' , '北京' , '王府井' ), ( '2' , '天津' , '天津' , '周良' ), ( '3' , '安徽' , '宿州' , '涌桥' ), ( '4' , '广东' , '广州' , '顺德' ); INSERT INTO `car` VALUES ( '1' , 'green' , '路虎' , '1' ), ( '2' , 'white' , '奔驰' , '2' ), ( '3' , 'blue' , '玛莎拉蒂' , '1' ), ( '4' , 'yellow' , '兰博基尼' , '2' ); |
四、@One一对一映射
以获取用户的唯一地址为例,首先我们定义一个根据地址id查询地址的查询方法
1
2
3
4
5
6
7
8
|
@Mapper public interface AddressRepository { /** * 根据地址id查询地址 */ @Select ( "SELECT * FROM `address` WHERE id = #{id}" ) AddressPO findAddressById(Long id); } |
然后我们定义一个根据用户id查询用户的方法
1
2
3
4
5
|
@Mapper public interface MySqlUserRepository { @Select ( "SELECT * FROM `user` WHERE id = #{id}" ) UserPO find(Long id); } |
这个时候我们查询出来的user对象中的address属性是空的,和address并没有任何关联。
那么我们要把user中的addressId传递给AddressRepository的查询地址的方法,
然后把查询出的地址对象address赋值给user的address属性,那么我们怎么做呢?
1
2
3
4
5
6
7
8
9
|
@Mapper public interface MySqlUserRepository { @Select ( "SELECT * FROM `user` WHERE id = #{id}" ) @Results ({ @Result (property = "address" , column = "address_id" , one = @One (select = "com.kimzing.data.repository.AddressRepository.findAddressById" )) }) UserPO find(Long id); } |
我们要使用@Resutl注解对返回的结果进行配置,
property = “address”
表示要将返回的查询结果赋值给user的address属性
column = “address_id”
是指将user表中的address_id作为com.kimzing.data.repository.AddressRepository.findAddressById的查询参数
one 表示这是一个一对一的查询
@One(select = "方法全路径)
表示我们调用的方法
五、@Many一对多查询
以获取用户拥有的所有车car为例,首先我们定义一个根据用户id查询车的查询方法
1
2
3
4
5
6
7
8
|
@Mapper public interface CarRepository { /** * 根据用户id查询所有的车 */ @Select ( "SELECT * FROM `car` WHERE user_id = #{userId}" ) List<Car> findCarsByUserId(Long userId); } |
然后我们定义一个根据用户id查询用户的方法
1
2
3
4
5
6
|
@Mapper public interface MySqlUserRepository { @Select ( "SELECT * FROM `user` WHERE id = #{id}" ) UserPO find(Long id); } |
这个时候我们查询出来的user对象中的List属性是空的,和car的查询方法并没有任何关联。
那么我们要把user中的用户id传递给CarRepository的查询车的方法,
然后把查询出的集合对象List赋值给user的cars属性,那么我们怎么做呢?(和获取地址是有些类似的)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.kimzing.data.repository.impl; import com.kimzing.data.domain.po.UserPO; import org.apache.ibatis.annotations.*; import java.util.List; /** * 数据存储. * * @author KimZing - kimzing@163.com * @since 2020/1/31 13:12 */ @Mapper public interface MySqlUserRepository { @Select ( "SELECT * FROM `user` WHERE id = #{id}" ) @Results ({ @Result (property = "address" , column = "address_id" , one = @One (select = "com.kimzing.data.repository.AddressRepository.findAddressById" )), @Result (property = "cars" , column = "id" , many = @Many (select = "com.kimzing.data.repository.CarRepository.findCarsByUserId" )) }), // 对userId进行赋值 @Result (property = "id" , column = "id" ) UserPO find(Long id); } |
我们要使用@Resutl注解对返回的结果进行配置,
property = “cars”, 表示要将返回的查询结果赋值给user的cars属性
column = “id” 是指将user表中的用户主键id作为com.kimzing.data.repository.CarRepository.findCarsByUserId的查询参数
many 表示这是一个一对多的查询
@Many(select = "方法全路径)
表示我们调用的方法, 方法参数userId就是上面column指定的列值
六、@One @Many的总结
首先我们统一下概念:查询Address或Car的方法,接下来统称为User的附属查询。
共同点:
- 无论是一对一还是一对多,都是通过附属查询来实现的,我们需要定义这个附属查询方法。
- 在主查询方法中通过@One、@Many指定附属查询方法的全路径。
- 都通过column来传递参数给附属方法。
不同点:
一对一,那么附属方法返回的是一个单独的对象
一对多,那么附属方法返回的是一个对象集合
以上就是SpringBoot中Mybatis注解一对多和多对多查询实现示例的详细内容,更多关于SpringBoot Mybatis注解一对多多对多查询的资料请关注服务器之家其它相关文章!
原文链接:https://kimzing.blog.csdn.net/article/details/78966789