记录一次bug解决过程:mybatis中$和#的使用
一、总结
mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数。动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因。mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态SQL进行处理的。在动态 SQL 解析阶段,#{ }和${ }会有不同的表现,#{ }解析为一个JDBC预编译语句(prepared statement)的参数标记符。
一个 #{ } 被解析为一个参数占位符 ? 。${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。
二、Bug描述
前端传入参数:
skip:0
take:10
ruleName:A,B,C
业务层处理:
package SQL; /**
* 将前端多选参数转义为SQL语句内容
*/
public class SQLUtil { private final static String REPLACECHAR_COMMA = ",";
private final static String REPLACECHAR_SEMICOLON = ";"; public static void main(String[] args) {
String s1 = "A,B,C";
String s2 = "A B C";
System.out.println("逗号分隔:" + formatInStr(s1));
System.out.println("空格分隔:" + formatInStr(s2));
} private static String formatInStr(String queryStr) {
return queryInStr(sliptQueryStr(queryStr));
} private static String[] sliptQueryStr(String queryStr) {
if (null == queryStr || "".equals(queryStr.trim())) return null;
queryStr = queryStr.replaceAll(SQLUtil.REPLACECHAR_COMMA, " ").replaceAll(REPLACECHAR_SEMICOLON, " ");
return queryStr.split("\\s+");
} private static String queryInStr(String[] queryStrs) {
if (null == queryStrs || 0 == queryStrs.length) return null;
StringBuffer buf = new StringBuffer();
for (int i = 0; i < queryStrs.length; i++) {
if (i != 0) buf.append(",");
buf.append("'").append(queryStrs[i]).append("'");
}
return buf.toString();
}
}
Mapper层处理:
//错误的处理
<if test="ruleName != null and ruleName != ''">
AND a.rule_name IN (#{ruleName})
</if> //正确的处理
<if test="ruleName != null and ruleName != ''">
AND a.rule_name IN (${ruleName})
</if>
日志描述:
[DEBUG] [2016-08-02 17:42:42.226] [qtp1457334982-157] java.sql.Connection - ==> Preparing: SELECT a.id, a.is_valid, a.rule_lable, a.rule_name, a.type, b.sp_id, b.sp_name,
a.rule_content, c.user_name, a.gmt_modified, a.ordering FROM idc_logistics_assign_rules a LEFT JOIN app_user c on c.work_no=a.modifier and c.is_deleted='n',
idc_sp_info b WHERE a.is_deleted = 'n' AND b.is_deleted = 'n' AND a.sp_id = b.sp_id AND a.rule_name IN (?) ORDER BY ordering asc limit ?, ?
[DEBUG] [2016-08-02 17:42:42.226] [qtp1457334982-157] java.sql.PreparedStatement - ==> Parameters: 'A','B'(String), 0(Integer), 10(Integer)
结果分析:mapper层对sql有预编译处理,对于#有占位符?,但是对于$会直接替换。
参考:http://www.tuicool.com/articles/VvyMN3A
记录一次bug解决过程:mybatis中$和#的使用的更多相关文章
- 记录一次bug解决过程:规范变量名称和mybatis的使用以及代码优化
一.总结 Mybatis中当parameterType为基本数据类型的时候,统一采用_parameter来代替基本数据类型变量. Mybatis中resultMap返回一个对象,resultType返 ...
- 记录一次bug解决过程:数据迁移
一 总结 不擅长语言表达,勤于沟通,多锻炼 调试MyBatis中SQL语法:foreach 问题:缺少关键字VALUES.很遗憾:它的错误报的让人找不着北. 二 BUG描述:MyBatis中批量插入数 ...
- 记录一次bug解决过程:velocity中获取url中的参数
一.总结 在Webx的Velocity中获取url中参数:$rundata.getRequest().getParameter('userId') 在Webx项目中,防止CSRF攻击(Cross-si ...
- 记录一次bug解决过程:resultType和手动开启事务
一.总结 二.BUG描述:MyBatis中resultType使用 MyBatis中的resultType类似于入参:parameterType.先看IDCM项目中的实际使用案例代码,如下: // L ...
- 记录一次bug解决过程:git深入学习和JDK8新特性
一 总结 熟悉廖雪峰git基础; 由于git跟踪的是修改,而不是版本号:因此对于修改撤销的操作,文件在eclipse中依旧有>修改标记,这点不同于svn. 二 BUG描述:熟悉Git基础 在Gi ...
- 记录一次bug解决过程:else未补全导致数据泄露和代码优化
一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...
- 记录一次bug解决过程:eclipse集成lombok插件
一 总结 eclipse集成插件lombok: 启动Spring Boot项目: sublime全局搜索关键字:ctrl + shift + F JDK8中的lambda表达式使用 二 BUG描述:集 ...
- 记录一次bug解决过程:eclipse Installed JREs 配置引出的问题
一 总结 eclipse Installed JREs 配置引出的问题:编译以来JDK,不是JRE spring boot内嵌tomcat运行程序,tomcat:run 二 Bug描述:eclipse ...
- 记录一次bug解决过程:可维护性和性能优化
一.总结 使用某些变量的地方在2次以上的,强烈建议使用枚举值来维护变量,日后方便扩展. 查数据库的方法调用,能合并就净量去合并. 二.Bug描述 枚举变量的维护以及方法使用: public class ...
随机推荐
- FILE文件流的中fopen、fread、fseek、fclose的使用
FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...
- C# Entity Framework并发处理
原网站:C# Entity Framework并发处理 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NE ...
- 小程序用户反馈 - HotApp小程序统计仿微信聊天用户反馈组件,开源
用户反馈是小程序开发必要的一个功能,但是和自己核心业务没关系,主要是产品运营方便收集用户的对产品的反馈.HotApp推出了用户反馈的组件,方便大家直接集成使用 源码下载地址: https://gith ...
- 让你从零开始学会写爬虫的5个教程(Python)
写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚本是很简单的,但是对于新手来说却并不是那么容易. ...
- windows下的命令行工具babun
什么是babun babun是windows上的一个第三方shell,在这个shell上面你可以使用几乎所有linux,unix上面的命令,他几乎可以取代windows的shell.用官方的题目说就是 ...
- Vue.js——基于$.ajax实现数据的跨域增删查改
概述 之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的.在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax ...
- 为革命保护视力 --- 给 Visual Studio 换颜色
“为革命,保护视力,预防近视,眼保健操开始......” 这个应该是最老版本的眼保健操了,你听过? 一堆废话 且不说上面这个眼保健操到底有木有用,让眼睛放松下还是很有必要的,尤其是现在天天对着不是手机 ...
- C#的泛型的类型参数可以有带参数的构造函数的约束方式吗?
Review后看到标题让我十分羞愧自己语文功底太差,估计...请见谅......我还特地把这句写回开头了...... 问题 前天遇到的一个问题,所以在MSDN发了个问,刚也丰富了下问题,关于泛型的. ...
- 实现ABP中Person类的权限功能
菜单项的显示功能已经完全OK了.那么我们就开始制作视图功能吧. 首先测试接口是否正常 我们通过代码生成器将权限和application中大部分功能已经实现了.那么我们来测试下这些接口ok不. 浏览/a ...
- .NET 基础 一步步 一幕幕[数组、集合、异常捕获]
数组.集合.异常捕获 数组: 一次性存储多个相同类型的变量. 一维数组: 语法: 数组类型[] 数组名=new 数组类型[数组长度]; 声明数组的语法: A.数据类型 [] 数组名称= new 数据类 ...