繁重的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")),
一对多查询也是类似的,只不过一个返回单个对象,一个返回一个集合。
详见代码代码