问题描述
- 在写一个联合查询时使用到了union all,两部分的查询条件相似,之前写过类似的,没出现问题,这次将union all的上下部分对调之后,出现查询结果异常。
问题解决
- 打印SQL并与之前的对比之后发现,如图所示的判断总是为true,然后将内部的条件拼接到SQL中,导致了查询结果异常。
- 但是通过断点发现,在进入xml之前,查询条件没有异常。所以开始在xml中找问题。
<if test="personalAuthority != null and personalAuthority.size > 0 and (organizationId != null or userId != null)">
</if>
- 打算将这个判断中的每一个条件拿出来进行测试,看到底是哪里的问题,于是写了以下代码:
<if test="personalAuthority != null">
AND 1=1
</if>
<if test="personalAuthority.size > 0">
AND 2=2
</if>
<if test="userId != null">
AND 3=3
</if>
<if test="organizationId != null">
AND 4=4
</if>
- 但是在测试时报错了
Caused by: java.sql.SQLException: sql injection violation, double const condition
。
- 查资料得知,需要给DRUID进行如下设置:
config.setConditionDoubleConstAllow(true);
- 继续报错:
Caused by: java.sql.SQLException: sql injection violation, part alway true condition not allow
。
- 查看API后进行了如下设置:
config.setConditionAndAlwayTrueAllow(true);
- 跑起来后发现,条件中的
organizationId
字段居然有值,很奇怪,也不知道是多少,因此把它打印出来
<if test="organizationId != null">
AND t1.organization_id = ${organizationId}
</if>
- 当我把这条完整的SQL格式化进行查看后,发现
organizationId
的值与上面的循环体中最后一个条件的值相同,然后我想起以前遇到过类似的问题,当在xml中对集合进行循环遍历时,如果循环中item的变量名与传入的参数名有重合,那么参数的值会被覆盖。
问题解决
- 一、可以将上下部分SQL进行对调,这样在我这个场景中是可以解决问题的,但是不一定适合其他场景。
- 二、将循环中的变量名进行修改,不要与参数名重名。