记录一次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 ...
随机推荐
- ecshop验证码
<?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...
- C++常见笔试面试要点以及常见问题
1. C++常见笔试面试要点: C++语言相关: (1) 虚函数(多态)的内部实现 (2) 智能指针用过哪些?shared_ptr和unique_ptr用的时候需要注意什么?shared_ptr的实现 ...
- 页面布局class常见命名规范
头:header 内容:content/container 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体布局宽度:wrapper 左右中:left rig ...
- 中文 iOS/Mac 开发博客列表
中文 iOS/Mac 开发博客列表 博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 一只魔法师的工坊 http://blog.ibireme.com ...
- android绘制圆形图片的两种方式
看下效果先 下面有完整的示例代码 使用BitmapShader(着色器) 我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap ...
- Android之解析XML
1.XML:可扩展标记语言. 可扩展标记语言是一种很像超文本标记语言的标记语言. 它的设计宗旨是传输数据,而不是显示数据. 它的标记没有被预定义.需要自行定义标签. 它被设计为具有自我描述性. 是W3 ...
- postgresql 基本语法
postgresql数据库创建/修改/删除等写入类代码语法总结: 1,创建库 2,创建/删除表 2.1 创建表 create table myTableName 2.2 如果表不存在则创建表 crea ...
- 设置WindowServer2012 时间同步NTP
在powershell中以管理员身份运行以下命令即可 w32tm /config /manualpeerlist:pool.ntp.org /syncfromflags:MANUAL Stop-Ser ...
- Linux.NET学习手记(8)
上一回合中,我们讲解了Linux.NET面对OWIN需要做出的准备,以及介绍了如何将两个支持OWIN协议的框架:SignalR以及NancyFX以OwinHost的方式部署到Linux.NET当中.这 ...
- 判断一个对象是jQuery对象还是DOM对象
今天调试一段代码的时候,看到其中一个变量,想知道它到底是jquery对象还是dom对象. 虽然直接console出这个对象,看它的内部可以判断出来.但是我想有没有什么更方便的方法呢. 后来我想到了一个 ...