一、总结

  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中$和#的使用的更多相关文章

  1. 记录一次bug解决过程:规范变量名称和mybatis的使用以及代码优化

    一.总结 Mybatis中当parameterType为基本数据类型的时候,统一采用_parameter来代替基本数据类型变量. Mybatis中resultMap返回一个对象,resultType返 ...

  2. 记录一次bug解决过程:数据迁移

    一 总结 不擅长语言表达,勤于沟通,多锻炼 调试MyBatis中SQL语法:foreach 问题:缺少关键字VALUES.很遗憾:它的错误报的让人找不着北. 二 BUG描述:MyBatis中批量插入数 ...

  3. 记录一次bug解决过程:velocity中获取url中的参数

    一.总结 在Webx的Velocity中获取url中参数:$rundata.getRequest().getParameter('userId') 在Webx项目中,防止CSRF攻击(Cross-si ...

  4. 记录一次bug解决过程:resultType和手动开启事务

    一.总结 二.BUG描述:MyBatis中resultType使用 MyBatis中的resultType类似于入参:parameterType.先看IDCM项目中的实际使用案例代码,如下: // L ...

  5. 记录一次bug解决过程:git深入学习和JDK8新特性

    一 总结 熟悉廖雪峰git基础; 由于git跟踪的是修改,而不是版本号:因此对于修改撤销的操作,文件在eclipse中依旧有>修改标记,这点不同于svn. 二 BUG描述:熟悉Git基础 在Gi ...

  6. 记录一次bug解决过程:else未补全导致数据泄露和代码优化

    一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...

  7. 记录一次bug解决过程:eclipse集成lombok插件

    一 总结 eclipse集成插件lombok: 启动Spring Boot项目: sublime全局搜索关键字:ctrl + shift + F JDK8中的lambda表达式使用 二 BUG描述:集 ...

  8. 记录一次bug解决过程:eclipse Installed JREs 配置引出的问题

    一 总结 eclipse Installed JREs 配置引出的问题:编译以来JDK,不是JRE spring boot内嵌tomcat运行程序,tomcat:run 二 Bug描述:eclipse ...

  9. 记录一次bug解决过程:可维护性和性能优化

    一.总结 使用某些变量的地方在2次以上的,强烈建议使用枚举值来维护变量,日后方便扩展. 查数据库的方法调用,能合并就净量去合并. 二.Bug描述 枚举变量的维护以及方法使用: public class ...

随机推荐

  1. bzoj3095--数学题

    题目大意:给定一个长度为n的整数序列x[i],确定一个二元组(b, k)使得S=Σ(k*i+b- x[i])^2(i∈[0,n-1])最小 看Claris大神的题解就行了.实际上就是用2次二次函数的性 ...

  2. 【HTML】Html页面跳转的5种方式

    目录结构: // contents structure [-] html实现 javascript方式实现 结合了倒数的javascript实现(IE) 解决Firefox不支持innerText的问 ...

  3. 电脑新建svn仓库

    步骤1:安转svg: 注意事项: 安装的时候选择:Modify 安装到以下图片的步骤时: 黄色区域选择: 步骤2:新建svn仓库文件夹(本教程例子:D:\svn-5gpos),选择文件夹右键,点击下图 ...

  4. Linux实战教学笔记05:远程SSH连接服务与基本排错(新手扫盲篇)

    第五节 远程SSH连接服务与基本排错 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 远程连接LInux系统管理 1.1 为什么要远程连接Linux系统 在实际的工作场景中,虚拟机界面或物理 ...

  5. WebAPI

    WebAPI的Host OWIN IIS WebAPI 的handler和Filter有啥区别? WebAPI  常用 Filters Exception Filter Timer Filter Lo ...

  6. MySQL基础之索引

    这段时间看了好多东西却没有总结,今天在这里写一写 关于索引 索引是一种提高查询效率的方法,它是B+树的结构,从根到中间节点在到叶子节点,无需遍历全部就可以查到所需的东西 关于索引的创建 一般有俩种方式 ...

  7. iOS-推送,证书申请,本地推送

    介绍一点点背景资料 众所周知,使用推送通知是一个很棒的.给应用添加实时消息通知的方式.这样做的结局是,开发者和用户之间,彼此永远保持着一种令人愉悦的亲密关系. 然而不幸的是,iOS的推送通知并非那么容 ...

  8. 【Win10应用开发】签名与验证

    对数据进行签名和验证,是为了防止数据被“盗版”.比较常规的做法是通过公钥进行验证. 算法上多用SAH_xxxx,就是哈希算法.由于MD5后来被发现存在“非唯一性”,你会发现现在很多一些下载的文件验证都 ...

  9. [3D数学基础:图形与游戏开发]专栏前言

    期待的书终于到了,接下来我会把自己的学习笔记以及心得整理出来,形成专栏,每一章都进行记录和学习总结,今天是2016年12月30日,再过一天就是元旦了,就要迎来美好的2017年了!!!加油~ 上面的书就 ...

  10. 1. 使用Filter 作为控制器

    最近整理一下学习笔记,并且准备放到自己的博客上.也顺便把Struts2 复习一遍 1. MVC 设计模式概览 实现 MVC(Model.View.Controller) 模式的应用程序由 3 大部分构 ...