问题描述
今天在公司当写代码的时候发现了一个问题
就是我一个列表的查询接口,并没有根据传入的筛选条件进行筛选,字段 execState = 0
的时候,筛选条件没有用,会查询出所有数据。 但是如果 execState 传入的是其他的值,就没有影响
排查过程
查看日志,发现 mybatis拼接出来的sql where子句中并没有 这段
但是前端实际是传了 execState = 0 的
所以就打算去排查下
- 字段名是否写错了
- where子句中是否漏掉了该判断
- service层是否接收到了参数之后没有使用
检查了这些都没有问题
后面检查传入的参数类:
发现 execState这个字段是 Integer类型的。
再看原来的mapper文件中写的sql是这样的
<if test="execState != null and execState != ''"> and sef.exec_state = #{execState}</if>
大胆设想
大胆猜想: 难道是 mybatis 把这个 execState = 0
在 后面的判断条件 execState != ' '
时 当作是 false了?
感觉也只可能是这样,才可能误伤吧
动手实践
然后修改一下 if标签的判断条件,把后面的 execState != ' '
去掉
本地调试,传入参数 execState = 0
发现这时候 sql正常了, where子句会出现 判断条件
问题到这儿应该就解决了
资料查询
MyBatis解析if标签时其表达式使用OGNL处理的。
Interpreting Objects as Booleans
Any object can be used where a boolean is required. OGNL interprets objects as booleans like this:
If the object is a Boolean, its value is extracted and returned;
If the object is a Number, its double-precision floating-point value is compared with zero; non-zero is treated as true, zero as false;
If the object is a Character, its boolean value is true if and only if its char value is non-zero;
Otherwise, its boolean value is true if and only if it is non-null.
如果对象是Number类型,当传值为0时会被解析成false,否则为true,浮点型0.00也是如此。所以这里直接解析成false。只有String类型才需要判断是否 != ' '
,其他类型完全没有这个必要。