国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

MyBatis中使用$和#所遇到的問題及解決辦法

2019-11-26 14:00:52
字體:
供稿:網(wǎng)友

在上篇文章給大家介紹了Mybatis中#{}和${}傳參的區(qū)別及#和$的區(qū)別小結(jié),如果大家有需要可以參考下。

$和#簡(jiǎn)單說明:

#相當(dāng)于對(duì)數(shù)據(jù) 加上 雙引號(hào),$相當(dāng)于直接顯示數(shù)據(jù)。

一、總結(jié)

  mybatis中使用sqlMap進(jìn)行sql查詢時(shí),經(jīng)常需要?jiǎng)討B(tài)傳遞參數(shù)。動(dòng)態(tài)SQL是mybatis的強(qiáng)大特性之一,也是它優(yōu)于其他ORM框架的一個(gè)重要原因。mybatis在對(duì)sql語句進(jìn)行預(yù)編譯之前,會(huì)對(duì)sql進(jìn)行動(dòng)態(tài)解析,解析為一個(gè)BoundSql對(duì)象,也是在此處對(duì)動(dòng)態(tài)SQL進(jìn)行處理的。在動(dòng)態(tài) SQL 解析階段,#{ }和${ }會(huì)有不同的表現(xiàn),#{ }解析為一個(gè)JDBC預(yù)編譯語句(prepared statement)的參數(shù)標(biāo)記符。

  一個(gè) #{ } 被解析為一個(gè)參數(shù)占位符 ? 。${ } 僅僅為一個(gè)純碎的 string 替換,在動(dòng)態(tài) SQL 解析階段將會(huì)進(jìn)行變量替換。

二、Bug描述

前端傳入?yún)?shù):

skip:0
take:10
ruleName:A,B,C

業(yè)務(wù)層處理:

package SQL;/*** 將前端多選參數(shù)轉(zhuǎn)義為SQL語句內(nèi)容*/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("逗號(hào)分隔:" + 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("http://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層處理:

//錯(cuò)誤的處理<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)

結(jié)果分析:mapper層對(duì)sql有預(yù)編譯處理,對(duì)于#有占位符?,但是對(duì)于$會(huì)直接替換。

PS:MyBatis排序時(shí)使用order by 動(dòng)態(tài)參數(shù)時(shí)需要注意,用$而不是#

字符串替換

 默認(rèn)情況下,使用#{}格式的語法會(huì)導(dǎo)致MyBatis創(chuàng)建預(yù)處理語句屬性并以它為背景設(shè)置安全的值(比如?)。這樣做很安全,很迅速也是首選做法,有時(shí)你只是想直接在SQL語句中插入一個(gè)不改變的字符串。比如,像ORDER BY,你可以這樣來使用:

復(fù)制代碼 代碼如下:

 ORDER BY ${columnName}

 這里MyBatis不會(huì)修改或轉(zhuǎn)義字符串。

重要:接受從用戶輸出的內(nèi)容并提供給語句中不變的字符串,這樣做是不安全的。這會(huì)導(dǎo)致潛在的SQL注入攻擊,因此你不應(yīng)該允許用戶輸入這些字段,或者通常自行轉(zhuǎn)義并檢查。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 额尔古纳市| 济宁市| 固阳县| 祁连县| 通辽市| 新田县| 普定县| 南雄市| 平乐县| 河曲县| 双江| 晋宁县| 望都县| 六盘水市| 亳州市| 奉化市| 南漳县| 湖南省| 应用必备| 贺州市| 武宣县| 佳木斯市| 阿拉善右旗| 五常市| 普宁市| 健康| 无棣县| 彩票| 顺平县| 甘德县| 怀集县| 天气| SHOW| 喀喇沁旗| 长顺县| 彰化县| 襄汾县| 江都市| 新安县| 盐山县| 自治县|