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 ...
随机推荐
- Android 样式 (style) 和主题(theme)
转载:https://gold.xitu.io/post/58441c48c59e0d0056a30bc2 样式和主题 样式是指为 View 或窗口指定外观和格式的属性集合.样式可以指定高度.填充.字 ...
- 论php数组合并
注:尽量不要在循环中操作数据库. 1.两个一维数组合并成一个一维数组 $a = array('morning','afternoon','night'); $b = array('breakfast' ...
- Premiere使用整理
整理部分自己在使用Premiere CC中遇到的问题和注意点. 1. 新建序列 若是录屏文件,可选择已加入到项目中的视频文件,点击 文件-新建-来自剪辑的序列. 2. 新建字幕 用于在视频中添加文字. ...
- 聊一聊PV和并发
最近和几个朋友,聊到并发和服务器的压力问题.很多朋友,不知道该怎么去计算并发?部署多少台服务器才合适? 所以,今天就来聊一聊PV和并发,还有计算web服务器的数量 的等方法.这些都是自己的想法加上一些 ...
- LibreOffice去重复数据
菜单:数据--更多筛选---标准筛选 点开“选项”,勾上“无重复值”. 然后还可以把结果复制到其它单元格.
- 使用sublime一键格式化XML文件
1 sublime简介 sublime是一款代码编辑和阅读软件,体积小,运行快,界面非常简洁漂亮.官方地址:https://www.sublimetext.com/ 2 在sublime上安装插件 使 ...
- sqlserver数据库标注为可疑的解决办法(转)
前几天客户那边的服务器死机了,然后客户强制关机,重新启动服务器后,系统就没法正常使用,连接不上服务器,我远程操作后,看到数据库标注为可疑,由于客户之前没备份数据库,看来只能是修复了: 1:停止数据库服 ...
- 关于MySQL的wait_timeout连接超时问题报错解决方案
bug回顾 : 想必大家在用MySQL时都会遇到连接超时的问题,如下图所示: ### Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsExce ...
- 【linux使用】bash shell命令行常用快捷键 (转载)
移动: Ctrl + A: 移动到当前编辑的命令行首, Ctrl + E: 移动到当前编辑的命令行尾, Ctrl + F 或 ->:按字符右移(往命令行尾部方向,前移) Ctrl + B 或 & ...
- Apache服务器安装过程及问题的解决(for windows system32bit)
在使用Hbuilder设计网站时,在制作本站搜索时,用到了Php文件,而Hbuilder的内置web服务器不支持php的解析, 所以需要安装配置外部服务器,有多个选择,我安装的apache服务器,并遇 ...