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")),

一对多查询也是类似的,只不过一个返回单个对象,一个返回一个集合。
详见代码代码

猜你喜欢

转载自blog.csdn.net/weixin_41768073/article/details/84432923
今日推荐