去掉MyBatis-Plus进行表之间关联查询的SQL,可好❓
💙 题记
学习使人进步,热爱学习,热爱生活!
💜 起因
最近主要负责一个新项目小程序端的接口开发与调试工作。后台使用的框架核心是
SpringBoot+MyBatis-Plus
,也是当下比较主流的。相比较之前SSM
框架的话,减少了spring相关的配置和tomcat的配置
,开发起来也是比较方便的,速度也提升了不少。但是相比之前的话,sql写的能少一点,sql主要集中在关联查询,还有一些聚合函数方面的(SUM,COUNT
)。在xml写sql实现多表关联查询应用到多查询条件的时候,还是比较好用的。那有没有一种方式可以不用在xml中写sql的吗?答案是肯定有的。有个叫框架叫
MyBatis-Plus-Join
。
下面进行相关知识的介绍与运用!
❤️ MyBatis-Plus-Join 介绍
主要是对 MyBatis-Plus
进行了升级,增加了多表链接查询功能,减少了在xml中编写sql的方式。
有兴趣的可以去官网看看,学习学习。 MyBatis-Plus-Join官网
💚 MyBatis-Plus-Join 运用
🌹 数据准备
DROP TABLE IF EXISTS `order1`;
CREATE TABLE `order1` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`order_number` varchar(64) NOT NULL COMMENT '订单编号',
`user_id` int NOT NULL COMMENT '用户ID',
`product_name` varchar(128) NOT NULL COMMENT '商品名称',
`product_price` decimal(10,2) NOT NULL COMMENT '商品价格',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `order_number_UNIQUE` (`order_number`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COMMENT='订单表';
/*Data for the table `order1` */
insert into `order1`(`id`,`order_number`,`user_id`,`product_name`,`product_price`,`create_time`) values
(1,'ORD0000000001',1,'iPhone 13 Pro Max',999.99,'2024-07-25 10:00:00'),
(2,'ORD0000000002',1,'Apple AirPods Pro',249.99,'2024-07-25 10:05:00'),
(3,'ORD0000000003',2,'Samsung Galaxy S23',899.99,'2024-07-25 10:15:00'),
(4,'ORD0000000004',2,'Samsung Galaxy Buds 2 Pro',199.99,'2024-07-25 10:20:00'),
(5,'ORD0000000005',3,'Google Pixel 7 Pro',799.99,'2024-07-25 10:30:00'),
(6,'ORD0000000006',3,'Google Nest Hub',99.99,'2024-07-25 10:35:00'),
(7,'ORD0000000007',4,'Huawei P60 Pro',849.99,'2024-07-25 10:45:00'),
(8,'ORD0000000008',4,'Huawei FreeBuds Pro 2',149.99,'2024-07-25 10:50:00'),
(9,'ORD0000000009',5,'Xiaomi Mi 13 Ultra',749.99,'2024-07-25 11:00:00'),
(10,'ORD0000000010',5,'Xiaomi Smart Band 7 Pro',49.99,'2024-07-25 11:05:00'),
(11,'ORD0000000011',6,'OnePlus 11R',699.99,'2024-07-25 11:15:00'),
(12,'ORD0000000012',6,'OnePlus Bullets Wireless Z',39.99,'2024-07-25 11:20:00'),
(13,'ORD0000000013',7,'Apple Watch Series 8',399.99,'2024-07-25 11:30:00'),
(14,'ORD0000000014',7,'Apple Magic Mouse 2',79.99,'2024-07-25 11:35:00'),
(15,'ORD0000000015',8,'Samsung Galaxy Buds 2 Pro',199.99,'2024-07-25 11:45:00'),
(16,'ORD0000000016',8,'Samsung Tab S8',699.99,'2024-07-25 11:50:00'),
(17,'ORD0000000017',9,'Google Home Mini',49.99,'2024-07-25 12:00:00'),
(18,'ORD0000000018',9,'Google Pixel 6a',449.99,'2024-07-25 12:05:00'),
(19,'ORD0000000019',10,'Amazon Echo Dot (5th Gen)',39.99,'2024-07-25 12:15:00'),
(20,'ORD0000000020',10,'Amazon Kindle Paperwhite',129.99,'2024-07-25 12:20:00');
/*Table structure for table `user1` */
DROP TABLE IF EXISTS `user1`;
CREATE TABLE `user1` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '用户id',
`name` varchar(64) DEFAULT NULL COMMENT '用户名称',
`phone` varchar(64) DEFAULT NULL COMMENT '用户电话',
`age` int DEFAULT NULL COMMENT '用户年龄',
`address` varchar(128) DEFAULT NULL COMMENT '用户地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='用户表';
/*Data for the table `user1` */
insert into `user1`(`id`,`name`,`phone`,`age`,`address`) values
(1,'孙一','13800138002',27,'西安市雁塔区'),
(2,'黄二','13900139002',31,'青岛市市南区'),
(3,'张三','13800138000',30,'北京市海淀区'),
(4,'李四','13900139000',25,'上海市浦东新区'),
(5,'王五','13600136000',35,'广州市天河区'),
(6,'赵六','13700137000',28,'深圳市南山区'),
(7,'陈七','13800138001',22,'杭州市西湖区'),
(8,'周八','13900139001',32,'南京市鼓楼区'),
(9,'吴九','13600136001',40,'成都市武侯区'),
(10,'郑十','13700137001',33,'武汉市江汉区');
注意:数据库建表的时候不能使用数据库一些关键字,比如我最开始建表的时候是 Order ,最后改成 order1 。
🌺 Maven 引入
<!--mybatis-plus-join-boot-starter-->
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.13</version>
</dependency>
🍁 Mapper中extends
public interface OrderMapper extends MPJBaseMapper<Order> {
}
🍃 代码编写
📄 Service代码
public interface IOrderService extends IService<Order> {
/**
* 获取所有的用户订单列表
* @return
*/
public List<UserOrder> getUserOrderList();
/**
* 获取所有的用户订单分页
* @return
*/
Page<UserOrder> getUserOrderListPage();
/**
* 根据userId获取用户订单列表
* @param userId
* @return
*/
List<UserOrder> getOrderOfUserId(Integer userId);
}
📃 ServiceImpl 代码
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
@Resource
private OrderMapper orderMapper;
@Override
public List<UserOrder> getUserOrderList() {
//定义查询时主表的MPJLambdaWrapper,以此来调用(可认为调用谁的Mapper,谁就是主表)
MPJLambdaWrapper<Order> wrapper = JoinWrappers.lambda(Order.class);
//查询订单表中所有的字段
wrapper.selectAll(Order.class)
//查询用户表里面的name和phone
.select(User::getName,User::getPhone)
//关联用户表,条件为关键表用户表的id与订单表的userId
.leftJoin(User.class,User::getId,Order::getUserId);
//执行查询,并返回自定义的返回实体类型
List<UserOrder> userOrderList=orderMapper.selectJoinList(UserOrder.class, wrapper);
return userOrderList;
}
@Override
public Page<UserOrder> getUserOrderListPage() {
//定义查询时主表的MPJLambdaWrapper,以此来调用(可认为调用谁的Mapper,谁就是主表)
MPJLambdaWrapper<Order> wrapper = new MPJLambdaWrapper<>();
//查询订单表中所有的字段
wrapper.selectAll(Order.class)
//查询用户表里面的name和phone
.select(User::getName,User::getPhone)
//关联用户表,条件为关键表用户表的id与订单表的userId
.leftJoin(User.class,User::getId,Order::getUserId);
//执行分页查询,并返回自定义的返回实体类型(这块注意:需要启用 mybatis plus 分页插件)
Page<UserOrder> listPage=orderMapper.selectJoinPage(new Page<>(1, 10),UserOrder.class, wrapper);
return listPage;
}
@Override
public List<UserOrder> getOrderOfUserId(Integer userId) {
//定义查询时主表的MPJLambdaWrapper,以此来调用(可认为调用谁的Mapper,谁就是主表)
MPJLambdaWrapper<Order> wrapper = new MPJLambdaWrapper<>();
//查询订单表中所有的字段
wrapper.selectAll(Order.class)
//查询用户表里面的name和phone
.select(User::getName,User::getPhone)
//关联用户表,条件为关键表用户表的id与订单表的userId
.leftJoin(User.class,User::getId,Order::getUserId)
//拼接查询条件userId
.eq(Order::getUserId,userId);
//执行查询,并返回自定义的返回实体类型
List<UserOrder> userOrderList=orderMapper.selectJoinList(UserOrder.class, wrapper);
return userOrderList;
}
}
🍄 核心查询方法
/**
* 连表查询返回一条记录
*
* @param wrapper joinWrapper
* @param clazz resultType
*/
<DTO> DTO selectJoinOne(@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map
*
* @param wrapper joinWrapper
*/
Map<String, Object> selectJoinMap(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回记录集合
*
* @param wrapper joinWrapper
* @param clazz resultType
*/
<DTO> List<DTO> selectJoinList(@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map集合
*
* @param wrapper joinWrapper
*/
List<Map<String, Object>> selectJoinMaps(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回记录集合并分页
*
* @param wrapper joinWrapper
* @param clazz resultType
* @param <DTO> 分页返回对象
*/
<DTO, P extends IPage<DTO>> P selectJoinPage(P page,
@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map集合并分页
*
* @param wrapper joinWrapper
*/
<P extends IPage<Map<String, Object>>> P selectJoinMapsPage(P page,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
🌵 备注
可以继承MPJBaseMapper、MPJBaseService、MPJBaseServiceImpl
,里面已经继承好了MyBatis-Plus
中的BaseMapper、BaseService、BaseServiceImpl
。但是需要用到关联查询的时候需要继承 MPJBaseMapper
,其他场景可自行斟酌。
支持原有LambdaWrapper
对应的写法,比如:select、eq、like、orderBy
等等。
增加了关联查询(leftJoin、join、rightJoin
)、可设置字段别名(selectAs
)、 查询那个实体类的所有字段(selectAll
)等等。
🌴 源码地址
有需要的可以去下载呦!!!
🌲 总结
学习了一次,也写出了简单了实例代码,一切的一切都根据实际项目情况来定。
如果大家使用 MyBatis-Plus 框架的话,在一定程度上给大家提供一个可以不用在xml中编写sql的解决方法。
💖 展望
前路漫漫,还需继续努力!
每一天都是新的开始,做好今天就好!
转载自:https://juejin.cn/post/7395523104742359079