背景:
1. ORM框架的局限性
MyBatis-Plus虽然提供了强大的条件构造器(如QueryWrapper、UpdateWrapper),但在某些场景下存在局限性:
复杂多表关联查询(如嵌套子查询、特殊连接方式)
数据库特定函数或语法(如Oracle的CONNECT BY、MySQL的窗口函数)
需要高度优化的SQL语句
2. 业务需求的多样性
实际开发中会遇到:
报表类复杂查询(需要多个聚合函数、分组条件)
特殊业务逻辑(如递归查询组织架构)
大数据量下的性能优化需求
承上:条件构造器实战
在我们上一篇是学习中,我们知道了使用构造器来减少数据处理的代码量,然后为了避免出错,我们又学习了LambdaQueryWrapper。但是,事与愿违,在真是的业务场景下(如背景处),有些处理条件很多,那么对应的xml文件的代码量也随之上去了。
那么,该怎么办呢?这里引入到我们本篇的主题:自定义拼接SQL。
需求:将id在指定范围内的用户(例如1,2,4)的余额扣减指定的值。
传统SQL:
在此,只是一个简单的查询,如果加上名字,或者其他条件,语句将会更加复杂。
这里,我们有一个这样的需求:更新id为1,2,4的用户的余额,扣减200
首先,将构造条件完善:
@Test
public void customSqlSegment(){
//构造条件
LambdaQueryWrapper<User> lambdaQueryWrapper =new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(User::getId,List.of(1L,2L,4L));
//调用Mapper方法实现功能
}
此时,我们想要在这个mapper里面有一个updateBalanceByWrapper()方法实现我们的需求(类名有点失误,上面的已经更改了,下图忽略)
那我们就在UserMapper这个接口里面创建这个方法:
void updateBalanceByWrapper(@Param("amount") int amount, @Param("ew") LambdaQueryWrapper<User> queryWrapper);
然后编写我们的自定义sql语句:
@Update("update user set balance = balance - #{amount} ${ew.customSqlSegment}")
此时,完整的语句:
那么,开始测试我们的代码:
此时,我们的数据库:
结果:
数据库更新成功!