小程序三方平台开发: 解析小程序开发的未来趋势和机遇
971
2022-10-18
SpringBoot中Mybatis注解一对多和多对多查询实现示例
目录一、模拟的业务查询二、对应的实体类如下三、对应的建表语句和模拟数据如下四、@One一对一映射五、@Many一对多查询六、@One @Many的iMRNL总结
一、模拟的业务查询
系统中的用户user都有唯一对应的地址信息address,每个用户可以有多量车car,类似如下结构
|-- user
|-- address
|-- carList
|-- car1
|-- car2
二、对应的实体类如下
@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;
/**
* 地址信息,和用户是一对一的关系
*/
private AddressPO address;
/**
* 地址id
*/
private Long addressId;
/**
* 用户拥有的车,和用户是一对多的关系
*/
private List
}
三、对应的建表语句和模拟数据如下
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 '密码iMRNL',
`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 '创建人',
`modifier` varchar(20) DEFAULT NULL COMMENT '更新人',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`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一对一映射
以获取用户的唯一地址为例,首先我们定义一个根据地址id查询地址的查询方法
@Mapper
public interface AddressRepository {
/**
* 根据地址id查询地址
*/
@Select("SELECT * FROM `address` WHERE id = #{id}")
AddressPO findAddressById(Long id);
}
然后我们定义一个根据用户id查询用户的方法
@Mapper
public interface mysqlUserRepository {
@Select("SELECT * FROM `user` WHERE id = #{id}")
UserPO find(Long id);
}
这个时候我们查询出来的user对象中的address属性是空的,和address并没有任何关联。那么我们要把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注解对返回的结果进行配置,
property = “address”
表示要将返回的查询结果赋值给user的address属性
column = “address_id”
是指将user表中的address_id作为com.kimzing.data.repository.AddressRepository.findAddressById的查询参数
one 表示这是一个一对一的查询
@One(select = "方法全路径)
表示我们调用的方法
五、@Many一对多查询
以获取用户拥有的所有车car为例,首先我们定义一个根据用户id查询车的查询方法
@Mapper
public interface CarRepository {
/**
* 根据用户id查询所有的车
*/
@Select("SELECT * FROM `car` WHERE user_id = #{userId}")
List
}
然后我们定义一个根据用户id查询用户的方法
@Mapper
public interface MySqlUserRepository {
@Select("SELECT * FROM `user` WHERE id = #{id}")
UserPO find(Long id);
}
这个时候我们查询出来的user对象中的List属性是空的,和car的查询方法并没有任何关联。那么我们要把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;
/**
* 数据存储.
*
* @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",
iMRNL 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注解对返回的结果进行配置,
property = “cars”, 表示要将返回的查询结果赋值给user的cars属性
column = “id” 是指将user表中的用户主键id作为com.kimzing.data.repository.CarRepository.findCarsByUserId的查询参数
many 表示这是一个一对多的查询
@Many(select = "方法全路径)
表示我们调用的方法, 方法参数userId就是上面column指定的列值
六、@One @Many的总结
首先我们统一下概念:查询Address或Car的方法,接下来统称为User的附属查询。
共同点:
无论是一对一还是一对多,都是通过附属查询来实现的,我们需要定义这个附属查询方法。在主查询方法中通过@One、@Many指定附属查询方法的全路径。都通过column来传递参数给附属方法。
不同点:
一对一,那么附属方法返回的是一个单独的对象
一对多,那么附属方法返回的是一个对象集合
以上就是SpringBoot中Mybatis注解一对多和多对多查询实现示例的详细内容,更多关于SpringBoot Mybatis注解一对多多对多查询的资料请关注我们其它相关文章!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~