好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SpringBoot中Mybatis注解一对多和多对多查询实现示例

一、模拟的业务查询

系统中的用户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测试数据

  * @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

查看更多关于SpringBoot中Mybatis注解一对多和多对多查询实现示例的详细内容...

  阅读:10次