1. 程式人生 > >springboot極簡使用mybatis實現一對一,一對多查詢

springboot極簡使用mybatis實現一對一,一對多查詢

繁重的mybatis配置經常讓人頭痛,今天總結一下簡單地使用mybatis
先建好表

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');

程式碼中對應的實體類

//省略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;
}

下面開始配置mybatis

匯入依賴

	<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

配置資料庫資訊

#實體類存放的包路徑
mybatis.type-aliases-package=com.ay.mybatis.entity
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test2?serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456..

手寫mapper

@Mapper
public interface AddressMapper {
    @Select("select * from address")
    List<Address> getAll();

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

像這種單表查詢,寫起來是沒什麼難度的,也十分容易理解。

下面是一對一查詢和一對多查詢,因為user中有一個address屬性,和一個car集合,所以下面要使用附屬方法進行查詢。根據使用者id找到使用者,然後根據addressId找到對應的address以及根據使用者id找到對應的car集合。上面已經實現了address的查詢,下面實現car集合的查詢。

    /**
     * 根據使用者id查詢所有的車,property是實體類屬性,column是資料庫欄位
     */
    @Select("SELECT * FROM `car` WHERE user_id = #{userId}")
    @Results(@Result(property = "userId",column = "user_id"))
    List<Car> findCarByUserId(Long userId);

這樣兩個單獨的附屬方法已經都實現了。下面實現主要方法。

@Mapper
public interface UserMapper {
    /**
     * 一對一查詢,根據id找使用者,再根據addressId找Address
     * 因為生產環境中的實體類屬性名跟資料庫的欄位名可能不一樣
     * 所以@Result進行對映
     * 對於一對一查詢,藉助附屬查詢方法,此時的@Result語義是
     * 使用資料庫中column的引數進行附屬方法查詢,返回給property
     * @param id
     * @return
     */
    @Select("SELECT * FROM `user` where id = #{id}")
    @Results({
            @Result(property = "id",column = "id"),
            @Result(property = "addressId",column = "address_id"),
            @Result(property = "nickName",column = "nick_name"),
            @Result(property = "address",column = "address_id",
            one = @One(select = "com.ay.mybatis.dao.AddressMapper.findAddressById")),
            @Result(property = "cars",column = "id",
            many = @Many(select = "com.ay.mybatis.dao.CarMapper.findCarByUserId"))
    })
    User findUserWithAll(Long id);
}

前面三個result都是自動對映就不多說了,下面說這個一對一查詢,即用user表中的address_id作為引數去執行findAddressById這個方法,結果返回給user實體類屬性的address

@Result(property = "address",column = "address_id",
            one = @One(select = "com.ay.mybatis.dao.AddressMapper.findAddressById")),

一對多查詢也是類似的,只不過一個返回單個物件,一個返回一個集合。
詳見程式碼程式碼