【MybatisPlus】QueryWrapper的副作用(使用@Select);lambdaQuery();思考
QueryWrapper的副作用
【IT老齐751】Service 与 DAO 层职责分离的实践之路_哔哩哔哩_bilibili
开发任务统一使用 @Select,禁止在Service中使用QueryWrappper进行业务构建

在现有的 Java开发中,绝大多数团队都遵循着MVC开发模式:
- 视图部分(界面)发起请求
- 请求发送给控制器
- 控制器调用业务逻辑
- 业务逻辑再向下调用数据持久层
耦合困境

MyBatis-Plus提供了一个 select 的方法,可以传入一个QueryWrapper包装器,能情况动态组织查询条件
查询条件组织好以后,select会将其转换为SQL语句来执行。这么做没问题。针对敏捷开发和快速的价值交付,这是非常好的实现
职责分离原则:
在 Service 这个层面上,Service 是承载业务逻辑的。从实现角度来说,业务逻辑表达的是业务调用的过程,重点是控制业务的流向和数据流
在实际落地过程中,Service 与具体技术耦合越少越好。就是在 Service 当中,我们可以调用某个方法,比如调用一个list方法,就可以获取所有信息的列表。
那这个list的方法是从mysql取还是从redis取,这个过程不应出现在Service类当中。严格意义上来说,这个list方法是应该被包含在DAO 层中进行封装。
未来在业务处理时,对于 list方法,如果今天是从msyql来查,就调用DAO的;如果换成了Redis,那么只需要在底层的DAO 层面上进行替换就行了
问题:QueryWrapper的构建逻辑被写在Service里:
虽然使用的是UserMapper的selectList来进行查询,但在构建查询条件时,是在Service中来构建的
同时在后面的age、name,这本质上是数据库的物理字段名
如果公司要进行微服务的改造建设,就把这些信息拆散了,采用了不同的数据库。尤其是采用 NoSQL进行数据处理时,mybatisplus不能用了
MyBatis-Plus:围绕 SQL 语法和关系型数据库的表结构(行、列、主键、外键)进行设计
使用@Select实现指责分离

如果未来底层实现逻辑发生变化,比如数据从mysql迁移到了oracle上,作为DAO层只需要进行相应调整,而上面的Service层,由于职责切割清晰,完全不需要做任何改动
lambdaQueryWrapper和lambdaQuery()演示
lambdaQueryWrapper
LambdaQueryWrapper,本质是类,最基础的用法:手动 new 一个 Wrapper 对象,然后传给 Mapper
List<User> users = userMapper.selectList(
new LambdaQueryWrapper<User>()
.eq(User::getAge, 25)
.like(User::getName, "张")
);
lambdaQuery
lambdaQuery(),本质是IService 接口的默认方法,必须在 Service 层 (实现 IService 的类) 中使用,是 MyBatis-Plus 提供的“糖”,封装了 Wrapper 的创建过程,写代码更顺畅
底层仍基于 LambdaQueryWrapper,但提供了更流畅的链式 API
List<User> users = lambdaQuery()
.eq(User::getAge, 25)
.like(User::getName, "张")
.list(); // 直接执行并返回结果
思考
看到了QueryWrapper的副作用,实际上以前用的多的是LambdaQueryWrapper,也是在Service层中使用,那样的话也会让Service层耦合DAO层的技术实现
lambdaQuery()也一样,虽然写的更流畅了,但同样有Service层耦合问题
更多推荐
所有评论(0)