激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - MyBatis中使用$和#所遇到的問題及解決辦法

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

2020-06-02 11:08RunforLove JAVA教程

這篇文章主要介紹了MyBatis中使用$和#所遇到的問題及解決辦法的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

在上篇文章給大家介紹了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

業務層處理:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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層處理:

?
1
2
3
4
5
6
7
8
//錯誤的處理
<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>

日志描述:

?
1
2
[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有預編譯處理,對于#有占位符?,但是對于$會直接替換。

PS:MyBatis排序時使用order by 動態參數時需要注意,用$而不是#

字符串替換

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

 

復制代碼 代碼如下:

 ORDER BY ${columnName}

 

 這里MyBatis不會修改或轉義字符串。

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费一级特黄毛片视频 | 国产精品一区二区三区在线播放 | 中日韩乱码一二新区 | 精品一区二区三区免费视频 | 免费人成在线播放 | 福利在线免费视频 | 亚洲成人激情在线 | 日本不卡视频在线观看 | 717影院理论午夜伦八戒秦先生 | 免费看成年人视频在线 | 色网站在线免费观看 | 日韩激情一区二区三区 | 香蕉久久久| 免费观看黄色影片 | 中文字幕在线亚洲精品 | 久久成人视屏 | 日日草夜夜草 | 中日韩乱码一二新区 | 欧美黄色看 | 亚洲午夜久久久精品一区二区三区 | 久久久视频免费观看 | 中文字幕一二三区芒果 | 欧美日韩大片在线观看 | 亚洲导航深夜福利涩涩屋 | 午夜视频啊啊啊 | 欧美日韩在线看片 | 羞羞视频.www在线观看 | 国产精品一区二区免费在线观看 | 香蕉久久久久久 | 美女视频网站黄色 | 中文字幕在线观看网址 | 国产在线色 | 免费国产视频在线观看 | 久久精品视频免费观看 | 成人免费福利视频 | 激情小说色 | 中文字幕在线亚洲精品 | 国产一区二区在线免费观看 | 国产一级免费视频 | 国产精品7区 | 毛片免费观看视频 |