今天遇到这样一个问题下面是我服务器日志中打印的SQL
SELECT COUNT(not_notice.id)
FROM not_notice not_notice
WHERE 1 = 1
AND not_notice.state IN (?)
AND not_notice.pk_uc_company = ?
打印传入的参数是这样的
Parameters: 1,3,4(String), 1(Integer)
实际数据库执行查询语句是是90条 可是在接收到数据是67条 。SQL没有问题啊
我的Mybatis XML是这样写的
SELECT
COUNT(not_notice.id)
FROM
not_notice not_notice
WHERE
1 = 1
<if test="noticeQuery.sendtime != null">
<![CDATA[ AND not_notice.sendtime >= #{noticeQuery.sendtime}]]>
</if>
AND not_notice.state IN
(#{noticeQuery.states})
<if test="noticeQuery.content != null and noticeQuery.content != ''">
AND (not_notice.title LIKE CONCAT('%',#{noticeQuery.content},'%')
OR not_notice.text LIKE CONCAT('%',#{noticeQuery.content},'%'))
</if>
<if test="noticeQuery.starttime != null and noticeQuery.sendtime != null">
<![CDATA[ AND not_notice.sendtime >= #{noticeQuery.starttime} AND not_notice.sendtime <= #{noticeQuery.endtime}]]>
</if>
AND not_notice.pk_uc_company = #{noticeQuery.companyId}
然后就一直盯着看 突然想到 #在mybatis会把参数在引号(' '),但是我想 ‘1,3,4’ 这样的条件传入应该查询不到呀 后来测试 竟然能查询到下面是执行的SQL
SELECT * FROM not_notice not_notice WHERE 1 = 1 AND not_notice.state IN ('1,3,4') AND not_notice.pk_uc_company = 1
查询到的确实是67条 也就是满足第一个 1 这个条件 在逗号前终止了
后来我把 #{noticeQuery.sates}这个改为了¥{noticeQuery.state}的方式原样传入 结果就正常了。
说一下Mybatis # $的区别
#在Mybatis 中有预编译的功能,也就是我们在JavaWeb中先把要执行的SQL 进行格式校验 也就是调用了PreparedStatement这个接口 有预编译功能 可以防止SQL注入攻击,在实际的工作中大都使用这样表达式。
$是原生转入SQL的参数中,不进行预编译,采用此方式传入的参数不可以暴露到服务接口参数中,防止SQL注入攻击。