SpringBoot使用Mybatis注解進行一對多和多對多查詢(2)


SpringBoot使用Mybatis注解進行一對多和多對多查詢

GitHub的完整示例項目地址kingboy-springboot-data

一、模擬的業務查詢

系統中的用戶user都有唯一對應的地址信息address,每個用戶可以有多量車car,類似如下結構

|-- user
    |-- address
    |-- carList
        |-- car1
        |-- car2

  

二、對應的實體類如下

/省略setter/getter

public class Address {
    private Long id;
    private String province;
    private String city;
}

public class Car {
    private Long id;
    private String color;
    private String name;
    //用戶id
    private Long userId;
}

public class User {
    private Long id;
    //地址信息,和用戶是一對一的關系
    private Address address;
    //地址id
    private Long addressId;
    //用戶擁有的車,和用戶是一對多的關系
    private List<Car> cars;
}

三、對應的建表語句和模擬數據如下

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nick_name` varchar(50) DEFAULT NULL,
  `address_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `address` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `province` varchar(50) DEFAULT NULL,
  `city` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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=utf8;

INSERT INTO
    `user`
VALUES
    ('1', 'baby', '1'),
    ('2', 'kingboy', '2'),
    ('3', 'boy', '3'),
    ('4', 'kingbaby', '4');

INSERT INTO
    `address`
VALUES
    ('1', '北京', '北京'),
    ('2', '天津', '天津'),
    ('3', '安徽', '宿州'),
    ('4', '廣東', '廣州');

INSERT INTO
    `car`
VALUES
    ('1', 'green', '路虎', '1'),
    ('2', 'white', '奔馳', '2'),
    ('3', 'blue', '瑪莎拉蒂', '4'),
    ('4', 'yellow', '蘭博基尼', '4');

四、@One一對一映射

以獲取用戶的唯一地址為例,首先我們定義一個根據地址id查詢地址的查詢方法

public interface AddressRepository {
    /**
     * 根據地址id查詢地址
     */
    @Select("SELECT * FROM `address` WHERE id = #{id}")
    Address findAddressById(Long id);
}

然后我們定義一個根據用戶id查詢用戶的方法

public interface UserRepository {
    @Select("SELECT * FROM `user` where id = #{id}")
    User findUserWithAddress(Long id);
}

這個時候我們查詢出來的user對象中的address屬性是空的,和address並沒有任何關聯。 
那么我們要把user中的addressId傳遞給AddressRepository的查詢地址的方法, 
然后把查詢出的地址對象address賦值給user的address屬性,那么我們怎么做呢?

public interface UserRepository {
    @Select("SELECT * FROM `user` where id = #{id}")
    @Results({
            @Result(property = "address", column = "address_id",
                    one = @One(select = "com.kingboy.repository.address.AddressRepository.findAddressById"))
    })
    User findUserWithAddress(Long id);
}

我們要使用@Resutl注解對返回的結果進行配置, 
- property = “address”, 表示要將返回的查詢結果賦值給user的address屬性 
- column = “address_id” 是指將user表中的address_id作為com.kingboy.repository.address.AddressRepository.findAddressById的查詢參數 
- one 表示這是一個一對一的查詢 
- @One(select = “方法全路徑) 表示我們調用的方法

五、@Many一對多查詢

以獲取用戶擁有的所有車car為例,首先我們定義一個根據用戶id查詢車的查詢方法

public interface CarRepository {
    /**
     * 根據用戶id查詢所有的車
     */
    @Select("SELECT * FROM `car` WHERE user_id = #{userId}")
    List<Car> findCarByUserId(Long userId);
}

  然后我們定義一個根據用戶id查詢用戶的方法

public interface UserRepository {
    @Select("SELECT * FROM `user` where id = #{id}")
    User findUserWithAddress(Long id);
}

這個時候我們查詢出來的user對象中的List屬性是空的,和car的查詢方法並沒有任何關聯。 
那么我們要把user中的用戶id傳遞給CarRepository的查詢車的方法, 
然后把查詢出的集合對象List賦值給user的cars屬性,那么我們怎么做呢?

public interface UserRepository {
    /**
     * 查詢帶有車信息的用戶===============演示一對多(關於多對多其實就是兩個一對多組成)
     */
    @Select("SELECT * FROM `user` WHERE id = #{id}")
    @Results({
            @Result(property = "cars", column = "id",
                    many = @Many(select = "com.kingboy.repository.car.CarRepository.findCarByUserId"))
    })
    User getUserWithCar(Long id);
}
我們要使用@Resutl注解對返回的結果進行配置, 
- property = “cars”, 表示要將返回的查詢結果賦值給user的cars屬性 
- column = “id” 是指將user表中的用戶主鍵id作為com.kingboy.repository.address.CarRepository.findCarByUserId的查詢參數 
- many 表示這是一個一對多的查詢 
- @Many(select = “方法全路徑) 表示我們調用的方法, 方法參數userId就是上面column指定的列值

六、@One @Many的總結

首先我們統一下概念:查詢Address或Car的方法,接下來統稱為User的附屬查詢。

共同點: 
- 無論是一對一還是一對多,都是通過附屬查詢來實現的,我們需要定義這個附屬查詢方法。 
- 在主查詢方法中通過@One、@Many指定附屬查詢方法的全路徑。 
- 都通過column來傳遞參數給附屬方法。

不同點: 
- 一對一,那么附屬方法返回的是一個單獨的對象 
- 一對多,那么附屬方法返回的是一個對象集合

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM