目录
需求
测试小姐姐发来删除设备的bug,删除设备之前需要统计处于运行中或故障中子设备的数量,统计的原生SQL应该是这样的:
SELECT
COUNT( 1 )
FROM
table_name
WHERE
(
id = '679135XXXXXXX1212'
AND ( STATUS = 1 OR STATUS = 2 )
AND isRemoved = 0
)
出现的问题
服务端使用mybatis框架的QueryWrapper【query包装器】
来统计子设备,之前的查询语法是这样的:
public int method(String id, int isRemoved) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", id);
queryWrapper.eq("status", DeviceConstant.DeviceStatus.WORK)
.or().eq("status", DeviceConstant.DeviceStatus.FAULT);
return mapper.selectCount(queryWrapper);
}
但是生成出来的SQL语句是
SELECT
count(1)
FROM
table_name
WHERE
(
id = '679135XXXXXXX1212' AND STATUS = 1
OR STATUS = 2 AND isRemoved = 0
);
正如我们所知道的那样,MySQL中的 and
的优先级高于or
,因而,上面的SQL语句可以转化为
SELECT
count(1)
FROM
table_name
WHERE
(
(id = 679135XXXXXXX1212 AND STATUS = 1 )
OR (STATUS = 1 AND isRemoved = 0)
);
于是,就违背了我们最初的SQL语句,自然查询出来的有可能不对,导致统计的结果不对,因为这样的SQL语句表明:查询出设备Id等于‘679135XXXXXXX1212’且状态等于1,或者所有未移除的设备的状态等于2。
探究queryWrap
queryWrapper是mybatis plus中实现查询的对象封装操作类,其层级关系如下:
上图的字段解释:
-
Wrapper : 条件构造抽象类,最顶端父类,抽象类中提供4个方法西面贴源码展示
-
AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
-
AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
-
LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper。
-
LambdaUpdateWrapper : Lambda 更新封装Wrapper
-
QueryWrapper : Entity 对象封装操作类,不是用lambda语法
-
UpdateWrapper : Update 条件封装,用于Entity对象更新操作
解决方案
因此,mybatis的queryMapper的查询语法需要修改,如下:
public int method(String id, int isRemoved) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", id);
queryWrapper.and(wrapper -> wrapper.eq("status", DeviceConstant.DeviceStatus.WORK)
.or().eq("status", DeviceConstant.DeviceStatus.FAULT)
);
return mapper.selectCount(queryWrapper);
}
这种方式生成的SQL语句如下
SELECT
COUNT( 1 )
FROM
table_name
WHERE
(
id = ?
AND ( ( STATUS = ? OR STATUS = ? ) )
AND isRemoved = ?
)
这样的SQL才是我们想要的查询语句。
这是一个很细节的语法,一旦不注意,就陷入了mybatis的陷阱中。mybatis本身没有问题,本身是个优秀的框架。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99223.html