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 ...
随机推荐
- 解决win7系统重启后ip丢失问题,即每次电脑重启都要重新设置ip地址,重启后ip地址没了
自己制作的Ghost盘上网有点问题,每次重启后电脑的ip地址被还原,要重新设置 百度后终于找解决办法,在此记录. 第一步:点击左下角的WIN图标,输入CMD然后回车,打开DOS模式窗口. 第二步:在D ...
- JS倒计时执行操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- jquery中ajax用return来返回值无效
jquery中,ajax返回值,有三种写法,只有其中一种是成功的 /** * async:false,同步调用 * 返回1:2 * 失败 * 分析:ajax内部是一个或多个定义的函数,ajax中ret ...
- ajax两张传输数据方式
encodeURI() 函数可把字符串作为 URI 进行编码. 语法 encodeURI(URIstring) 参数 描述 URIstring 必需.一个字符串,含有 URI 或其他要编码的文本. 返 ...
- 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1936 Solved: 551[Submit][Status][Di ...
- ubuntu 下应用 Python 和 SL4A 的 Android 应用程序搭建您自己的android研发环境
转载自:http://code.qtuba.com/article-50680.html 最近在看<head first python>,书中有讲python在android中进行开发的章 ...
- UITextField set placeholderColor and UITextField set clearButton Image
self.usernameTextField.tintColor = [UIColor whiteColor]; [self.usernameTextField setValue:UIColorFro ...
- .net core教程
https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc
- RabbitMQ之window安装步骤
安装Rabbit MQ Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装Rabbit MQ的前提是安装Erlang.通过下面两个连接下载安装3.2.3 版本: 下载并安装 Era ...
- LODProp3D实例
1. Level of detail(LoD)多细节层次描述(简称LoD)是实时绘制复杂几何场景的一种有效工具.基于层次结构的动态简化方法能够根据视点的变化,实时连续地转换场景细节模型.在本例中,实现 ...