程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> MyBatis中應用$和#所碰到的成績及處理方法

MyBatis中應用$和#所碰到的成績及處理方法

編輯:關於JAVA

MyBatis中應用$和#所碰到的成績及處理方法。本站提示廣大學習愛好者:(MyBatis中應用$和#所碰到的成績及處理方法)文章只能為提供參考,不一定能成為您想要的結果。以下是MyBatis中應用$和#所碰到的成績及處理方法正文


在上篇文章給年夜家引見了Mybatis中#{}和${}傳參的差別及#和$的差別小結,假如年夜家有須要可以參考下。

$和#簡略解釋:

#相當於對數據 加上 雙引號,$相當於直接顯示數據。

1、總結

  mybatis中應用sqlMap停止sql查詢時,常常須要靜態傳遞參數。靜態SQL是mybatis的壯大特征之一,也是它優於其他ORM框架的一個主要緣由。mybatis在對sql語句停止預編譯之前,會對sql停止靜態解析,解析為一個BoundSql對象,也是在此處對靜態SQL停止處置的。在靜態 SQL 解析階段,#{ }和${ }會有分歧的表示,#{ }解析為一個JDBC預編譯語句(prepared statement)的參數標志符。

  一個 #{ } 被解析為一個參數占位符 ? 。${ } 僅僅為一個純碎的 string 調換,在靜態 SQL 解析階段將會停止變量調換。

2、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有預編譯處置,關於#有占位符?,然則關於$會直代替換。

PS:MyBatis排序時應用order by 靜態參數時須要留意,用$而不是#

字符串調換

 默許情形下,應用#{}格局的語法會招致MyBatis創立預處置語句屬性並以它為配景設置平安的值(好比?)。如許做很平安,很敏捷也是首選做法,有時你只是想直接在SQL語句中拔出一個不轉變的字符串。好比,像ORDER BY,你可以如許來應用:


 ORDER BY ${columnName}

 這裡MyBatis不會修正或本義字符串。

主要:接收從用戶輸入的內容並供給給語句中不變的字符串,如許做是不平安的。這會招致潛伏的SQL注入進擊,是以你不該該許可用戶輸出這些字段,或許平日自行本義並檢討。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved