快捷搜索: 王者荣耀 脱发

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类型参数动态替换。来达到跟上一个方法同样的效果。 具体代码,待以后实现!

经验分享 程序员 微信小程序 职场和发展