SpringBoot中Mybatis注解一對多和多對多查詢實現(xiàn)示例
一、模擬的業(yè)務(wù)查詢
系統(tǒng)中的用戶user都有唯一對應(yīng)的地址信息address,每個用戶可以有多量車car,類似如下結(jié)構(gòu)
|-- user |-- address |-- carList |-- car1 |-- car2
二、對應(yīng)的實體類如下
@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; /** * 地址信息,和用戶是一對一的關(guān)系 */ private AddressPO address; /** * 地址id */ private Long addressId; /** * 用戶擁有的車,和用戶是一對多的關(guān)系 */ private List<CarPO> cars; }
三、對應(yīng)的建表語句和模擬數(shù)據(jù)如下
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 '創(chuàng)建人', `modifier` varchar(20) DEFAULT NULL COMMENT '更新人', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間', `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一對一映射
以獲取用戶的唯一地址為例,首先我們定義一個根據(jù)地址id查詢地址的查詢方法
@Mapper public interface AddressRepository { /** * 根據(jù)地址id查詢地址 */ @Select("SELECT * FROM `address` WHERE id = #{id}") AddressPO findAddressById(Long id); }
然后我們定義一個根據(jù)用戶id查詢用戶的方法
@Mapper public interface MySqlUserRepository { @Select("SELECT * FROM `user` WHERE id = #{id}") UserPO find(Long id); }
這個時候我們查詢出來的user對象中的address屬性是空的,和address并沒有任何關(guān)聯(lián)。
那么我們要把user中的addressId傳遞給AddressRepository的查詢地址的方法,
然后把查詢出的地址對象address賦值給user的address屬性,那么我們怎么做呢?
@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注解對返回的結(jié)果進行配置,
property = “address”
表示要將返回的查詢結(jié)果賦值給user的address屬性
column = “address_id”
是指將user表中的address_id作為com.kimzing.data.repository.AddressRepository.findAddressById的查詢參數(shù)
one 表示這是一個一對一的查詢
@One(select = "方法全路徑)
表示我們調(diào)用的方法
五、@Many一對多查詢
以獲取用戶擁有的所有車car為例,首先我們定義一個根據(jù)用戶id查詢車的查詢方法
@Mapper public interface CarRepository { /** * 根據(jù)用戶id查詢所有的車 */ @Select("SELECT * FROM `car` WHERE user_id = #{userId}") List<Car> findCarsByUserId(Long userId); }
然后我們定義一個根據(jù)用戶id查詢用戶的方法
@Mapper public interface MySqlUserRepository { @Select("SELECT * FROM `user` WHERE id = #{id}") UserPO find(Long id); }
這個時候我們查詢出來的user對象中的List屬性是空的,和car的查詢方法并沒有任何關(guān)聯(lián)。
那么我們要把user中的用戶id傳遞給CarRepository的查詢車的方法,
然后把查詢出的集合對象List賦值給user的cars屬性,那么我們怎么做呢?(和獲取地址是有些類似的)
package com.kimzing.data.repository.impl; import com.kimzing.data.domain.po.UserPO; import org.apache.ibatis.annotations.*; import java.util.List; /** * 數(shù)據(jù)存儲. * * @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注解對返回的結(jié)果進行配置,
property = “cars”, 表示要將返回的查詢結(jié)果賦值給user的cars屬性
column = “id” 是指將user表中的用戶主鍵id作為com.kimzing.data.repository.CarRepository.findCarsByUserId的查詢參數(shù)
many 表示這是一個一對多的查詢
@Many(select = "方法全路徑)
表示我們調(diào)用的方法, 方法參數(shù)userId就是上面column指定的列值
六、@One @Many的總結(jié)
首先我們統(tǒng)一下概念:查詢Address或Car的方法,接下來統(tǒng)稱為User的附屬查詢。
共同點:
- 無論是一對一還是一對多,都是通過附屬查詢來實現(xiàn)的,我們需要定義這個附屬查詢方法。
- 在主查詢方法中通過@One、@Many指定附屬查詢方法的全路徑。
- 都通過column來傳遞參數(shù)給附屬方法。
不同點:
一對一,那么附屬方法返回的是一個單獨的對象
一對多,那么附屬方法返回的是一個對象集合
以上就是SpringBoot中Mybatis注解一對多和多對多查詢實現(xiàn)示例的詳細內(nèi)容,更多關(guān)于SpringBoot Mybatis注解一對多多對多查詢的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Servlet的5種方式實現(xiàn)表單提交(注冊小功能),后臺獲取表單數(shù)據(jù)實例
這篇文章主要介紹了Servlet的5種方式實現(xiàn)表單提交(注冊小功能),后臺獲取表單數(shù)據(jù)實例,非常具有實用價值,需要的朋友可以參考下2017-05-05Java中的構(gòu)造方法(構(gòu)造函數(shù))與普通方法區(qū)別及說明
這篇文章主要介紹了Java中的構(gòu)造方法(構(gòu)造函數(shù))與普通方法區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03MyBatis關(guān)閉一級緩存的兩種方式(分注解和xml兩種方式)
這篇文章主要介紹了MyBatis關(guān)閉一級緩存的兩種方式(分注解和xml兩種方式),mybatis默認開啟一級緩存,執(zhí)行2次相同sql,但是第一次查詢sql結(jié)果會加工處理這個時候需要關(guān)閉一級緩存,本文給大家詳細講解需要的朋友可以參考下2022-11-11