博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
记录一次bug解决过程:mybatis中$和#的使用
阅读量:6217 次
发布时间:2019-06-21

本文共 2317 字,大约阅读时间需要 7 分钟。

一、总结

  mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数。动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因。mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态SQL进行处理的。在动态 SQL 解析阶段,#{ }和${ }会有不同的表现,#{ }解析为一个JDBC预编译语句(prepared statement)的参数标记符。

  一个 #{ } 被解析为一个参数占位符 ? 。${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。

二、Bug描述

前端传入参数:

skip:0take:10ruleName: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层处理:

//错误的处理
AND a.rule_name IN (#{ruleName})
//正确的处理
AND a.rule_name IN (${ruleName})

日志描述:

[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://rroja.baihongyu.com/

你可能感兴趣的文章
【野生程序员】:优先招聘
查看>>
Lucene于Directory
查看>>
Swift - 歌曲播放样例(附带播放时间和播放进度)
查看>>
jquery判断div滚动条到底部
查看>>
alpha to coverage
查看>>
垃圾回收机制及析构器原理解析
查看>>
cocos2d 简单的日常高仿酷跑游戏
查看>>
为什么唱iOS 6.0选择Mantle
查看>>
Odoo 中的 Controller
查看>>
1029. Median (25)
查看>>
cobbler全自动批量安装部署linux
查看>>
网络爬虫基本原理(一)
查看>>
使用Anthem.NET 1.5中的FileUpload控件实现Ajax方式的文件上传
查看>>
jquery截图插件的使用
查看>>
LeetCode——Palindrome Partitioning
查看>>
ORA-19693: 已包括备份片段
查看>>
第十三周(立体类族共同拥有的抽象类)
查看>>
iOS UI-静态单元格与动态单元格
查看>>
iOS: iOS9 beta 请求出现App Transport Security has blocked a cleartext HTTP (http://)
查看>>
linux下查看日志基本命令
查看>>