MyBatis模糊查询防止通配符查询
项目场景:
MyBatis+Mysql 日常使用问题
问题描述:
模糊查询,传入参数为通配符时,where 条件不生效,导致查询结果超出预期。代码如下:
<if test=title != null and title !""> and title like concat(%,#{title},%) </if>
原因分析:
接收参数之后,实际执行的SQL为 selct * from test where title like ‘%%%’; 即查询结果为表中 title字段有任意多个字符 的数据,导致where条件失效。
***MySQL中的常用统配符有三个:*** %:用来表示任意多个字符,包含0个字符 _ : 用来表示任意单个字符 escape:用来转义特定字符(使用escape,转义字符后面的%或_就不作为通配符了,注意前面没有转义字符的%和_仍然起通配符作用)
解决方案:
最容易想到的解决办法,在每一个查询的位置,传参之前对指定的参数进行通配符转义。示例如下:
// 通配符数组 public static final String[] WILDCARD_CHARACTER = new String[]{ "%","_"}; // 需要替换的内容 public static final String REPLACEMENT_CHARACTER= "\"; public List<Test> getTestList(Test test){ if(StringUtils.isNotEmpty(test.getTitle)){ // % _ 这两个通配符都要进行替换 test.setTitle(StringUtils.replace(test.getTitle(),WILDCARD_CHARACTER,REPLACEMENT_CHARACTER)); } return testMapper.selectTestList(Test test); }
以上方法,非常的繁琐,在每一个查询的地方都需要执行。 通过跟踪源代码的方式,查找到mybatis参数绑定原理,BaseTypeHandler -> StringTypeHandler.setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType); 通过自定义一个类,继承 StringTypeHandler类,并重写setNonNullParameter()方法,以实现string类型参数动态替换。来达到跟上一个方法同样的效果。 具体代码,待以后实现!
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
角度与弧度之间的换算