MyBatis Like查询处理%_符号
如果我们数据库中存的字段包含有"%_"这两个like查询的通配符,那么在查询的时候把"%_"当作关键字是查询不出来的,因为mybatis会把这两个字符当作通配符。解决方法是要能加转义字符
1.定义一个拦截器,如果要查询的字符串中包含"%_"则增加一个转义字符
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class})})
public class QueryExecutorInterceptor implements Interceptor {
private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
private static final ReflectorFactory DEFAULT_OBJECT_REFLECTOR_FACTORY = new DefaultReflectorFactory();
private static final String ROOT_SQL_NODE = "sqlSource.rootSqlNode";
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object parameter = invocation.getArgs()[1];
MappedStatement statement = (MappedStatement) invocation.getArgs()[0];
MetaObject metaMappedStatement = MetaObject.forObject(statement, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_OBJECT_REFLECTOR_FACTORY);
BoundSql boundSql = statement.getBoundSql(parameter);
if (metaMappedStatement.hasGetter(ROOT_SQL_NODE)) {
//修改参数值
SqlNode sqlNode = (SqlNode) metaMappedStatement.getValue(ROOT_SQL_NODE);
getBoundSql(statement.getConfiguration(), boundSql.getParameterObject(), sqlNode);
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
public static BoundSql getBoundSql(Configuration configuration, Object parameterObject, SqlNode sqlNode) {
DynamicContext context = new DynamicContext(configuration, parameterObject);
sqlNode.apply(context);
String countextSql = context.getSql();
SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
String sql = modifyLikeSql(countextSql, parameterObject);
SqlSource sqlSource = sqlSourceParser.parse(sql, parameterType, context.getBindings());
BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {
boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
}
return boundSql;
}
public static String modifyLikeSql(String sql, Object parameterObject) {
if (parameterObject instanceof Map) {
} else {
return sql;
}
if (!sql.toLowerCase().contains("like"))
return sql;
String reg = "\\bLIKE\\b.*\\#\\{\\b.*\\}";
Pattern pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(sql);
List<String> replaceFiled = new ArrayList<String>();
while (matcher.find()) {
int n = matcher.groupCount();
for (int i = 0; i <= n; i++) {
String output = matcher.group(i);
if (output != null) {
String key = getParameterKey(output);
if (replaceFiled.indexOf(key) < 0) {
replaceFiled.add(key);
}
}
}
}
//修改参数
Map<String, Object> paramMab = (Map) parameterObject;
for (String key : replaceFiled) {
Object val = paramMab.get(key);
if (val != null && val instanceof String && (val.toString().contains("%") || val.toString().contains("_"))) {
val = val.toString().replaceAll("%", "/%").replaceAll("_", "/_");
paramMab.replace(key.toString(), val);
}
}
return sql;
}
private static String getParameterKey(String input) {
String key = "";
String[] temp = input.split("#");
if (temp.length > 1) {
key = temp[1];
key = key.replace("{", "").replace("}", "").split(",")[0];
}
return key.trim();
}
2. 对面的查询mapper like后面要加escape '/'
<select id="getList" resultMap="MultiResultMap" parameterType="java.util.Map">
SELECT * FROM SYS_TEST T
WHERE 1=1
<if test="_parameter.containsKey('key')">
AND UPPER(CONCAT(T.ROLE_NAME,T.ROLE_INFO)) LIKE UPPER (CONCAT(CONCAT('%', #{key, jdbcType=VARCHAR}),'%')) ESCAPE '/'
</if>
</select>
最好的做法是可以直接拦截SQL,然后在SQL后面自动加上ESCAPE '/',但还没有找到合适的方法
MyBatis Like查询处理%_符号的更多相关文章
- mybatis转义反斜杠_MyBatis Plus like模糊查询特殊字符_、\、%
在MyBatis Plus中,使用like查询特殊字符_,\,%时会出现以下情况: 1.查询下划线_,sql语句会变为"%_%",会导致返回所有结果.在MySQL中下划线" ...
- MyBatis关联查询 (association) 时遇到的某些问题/mybatis映射
先说下问题产生的背景: 最近在做一个用到MyBatis的项目,其中有个业务涉及到关联查询,我是将两个查询分开来写的,即嵌套查询,个人感觉这样更方便重用: 关联的查询使用到了动态sql,在执行查询时就出 ...
- MyBatis的查询
MyBatis的查询 在上一个MyBatis的核心API中介绍了SqlSessionFactoryBuilder.SqlSessionFactory以及SqlSession是什么,它们都有什么作用,本 ...
- MyBatis关联查询和懒加载错误
MyBatis关联查询和懒加载错误 今天在写项目时遇到了个BUG.先说一下背景,前端请求更新生产订单状态,后端从前端接收到生产订单ID进行查询,然后就有问题了. 先看控制台报错: org.apache ...
- Mybatis关联查询和数据库不一致问题分析与解决
Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...
- myBatis批量查询操作,xml中使用foreach案例
使用场景:有一个订单表,实体类为OrderBase.java,订单有个状态为status值可能为"1,2,3,4,5,6",现在需要查询状态为"2,3,4"的订 ...
- MyBatis基础:MyBatis关联查询(4)
1. MyBatis关联查询简介 MyBatis中级联分为3中:association.collection及discriminator. ◊ association:一对一关联 ◊ collecti ...
- MyBatis关联查询,一对多关联查询
实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collect ...
- Ibatis/Mybatis模糊查询
Ibatis/Mybatis模糊查询 根据网络内容整理 Ibatis中 使用$代替#.此种方法就是去掉了类型检查,使用字符串连接,不过可能会有sql注入风险. Sql代码 select * from ...
随机推荐
- OC中的多继承
可以间接实现,方法有: 1.消息转发 2.协议 3.组合模式 4.代理 5.分类 直接上code,分别说明集中方法的实现 一.消息转发 消息转发可以参考我的另外一篇博客:http://www.cnbl ...
- Android基础总结(五)
HttpClient 发送get请求 创建一个客户端对象 HttpClient client = new DefaultHttpClient(); 创建一个get请求对象 HttpGet hg = n ...
- 【转】MipMap
原文地址http://www.cppblog.com/wc250en007/archive/2011/08/06/152653.html 首先从MIPMAP的原理说起,它是把一张贴图按照2的倍数进行缩 ...
- 进度条投票-W
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Java中如何把一下字符串转换成map
首先,你先确认你的字符串是否是json格式的,如果是json格式,那你可以使用Gson.jar或json-lib-xx-jdk.jar两个包来自动解析解析. 使用Gson更简单些,只需要导入一个包就可 ...
- net.sf.json.JSONException: There is a cycle in the hierarchy!的解决办法
使用Hibernate manytoone属性关联主表的时候,如果使用JSONArray把pojo对象转换成json对象时,很容易出现循环的异常.解决的办法就是, 在转换json对象时忽略manyto ...
- logback日志写入数据库(mysql)配置
如题 建议将日志级别设置为ERROR.这样可以避免存储过多的数据到数据中. 1 logback 配置文件(如下) <?xml version="1.0" encoding ...
- GNU Radio Radar Toolbox
GNU Radio Radar Toolbox Install guide Change to any folder in your home directory and enter followin ...
- 1.0、修改MyEclipse字体大小及颜色
windows-->prefereces->General-->Appearance-->Colors and Fonts,在右边找到要修改的字体或背景,双击点Edit修改即可 ...
- 【Android】Android属性allowBackup安全风险
allowBackup值为true或false,Android API Level 8及其以上Android系统提供了为应用程序数据的备份和恢复功能,当allowBackup标志为true时,用户即可 ...