이전 기사에서는 # {}와 $ {} 매개 변수의 차이와 MyBatis에서 #과 $의 차이를 소개했습니다. 필요한 경우 참조 할 수 있습니다.
$ 및 # 간단한 설명 :
#는 데이터에 이중 따옴표를 추가하는 것과 같습니다. $는 데이터를 직접 표시하는 것과 같습니다.
1. 요약
MyBatis에서 SQL 쿼리에 SQLMAP를 사용하는 경우 매개 변수를 동적으로 전달해야합니다. Dynamic SQL은 Mybatis의 강력한 기능 중 하나이며 다른 ORM 프레임 워크보다 우수한 중요한 이유입니다. SQL 명령문을 사전 컴파일하기 전에 Mybatis는 SQL을 동적으로 구문 분석하고 바운드 QL 객체로 구문 분석하여 여기에서 처리됩니다. 동적 SQL 구문 분석 단계에서 #{} 및 $ {}은 다른 성능을 갖고 #{}는 JDBC 사전 컴파일 된 문의 매개 변수 마커로 구문 분석됩니다.
#{}는 매개 변수 자리 표시 자로 구문 분석됩니까? . $ {}는 순수한 문자열 교체품이며 동적 SQL 구문 분석 단계에서 가변 교체가 수행됩니다.
2. 버그 설명
프론트 엔드 매개 변수 :
건너 뛰기 : 0
테이크 : 10
규칙 : A, B, c
비즈니스 계층 처리 :
패키지 SQL;/*** Escape Front-End Multi-Select 매개 변수는 SQL 명령문 내용*/public class sqlutil {개인 최종 정적 문자열 REPLACECHAR_COMMA = ","; 개인 최종 정적 문자열 REPLACECHAR_SEMICOLON = ";"; public static void main (String [] args) {문자열 s1 = "; b, b, c"; "abc"; system.out.println ( "comma-separated :" + formatinstr (s1)); system.out.println ( "space-separated :" + formatinst (s2));} private static string formatinstr (String QueryStr (sliptquerystr); {if (null == querystr || "".equals (querystr.trim ())) return null; querystr = querystr.replaceall (sqlutil.replacechar_comma, "") .replaceall (replacechar_semicolon, ""; return querystr.split ( "// s+"); QueryInst (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 ();}}} 맵퍼 층 처리 :
// 오류 처리 <if test = "rulename! = null 및 rulename! = ''"> 및 a.rule_name in (#{rulename}) </if> // 올바른 처리 < "if test ="rulename! = null and rulename! = '' "> 및 a.rule_name in ($ {rulename}) </if> 로그 설명 :
[Debug] [2016-08-02 17 : 42 : 42.226] [qtp1457334982-157] java.sql.connection- ==> 준비 : 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, c.user. a.gmt_modified, a.ording a idc_logistics_assign_rules a left join app_user c c.work_no = a.modifier and c.is_deleted = 'n', idc_sp_info b a.is_deleted = 'n'및 b.is_deleted = 'n'및 a.sp_id and a.sp_id and a.sp_id on in (?) ?,? [Debug] [2016-08-02 17 : 42 : 42.226] [qtp1457334982-157] java.sql.preparedstatement- ==> 매개 변수 : 'a', 'b'(String), 0 (정수), 10 (Integer)
결과 분석 : Mapper 레이어는 SQL을 사전 컴파일했으며 #에 대한 자리 표시자가 있습니까? 그러나 $로 직접 대체됩니다.
추신 : mybatis를 정렬 할 때 Dynamic 매개 변수 별 순서를 사용하는 경우 # 대신 $를 사용하는 데주의를 기울여야합니다.
문자열 교체
기본적으로 #{} 형식 구문을 사용하면 MyBatis가 전처리 된 명령문 속성을 생성하고 배경 (예 :?)으로 안전한 값을 설정하게합니다. 이것은 안전하고 빠르며 때로는 SQL 문으로 직접 변경되지 않는 문자열을 삽입하려고합니다. 예를 들어, 순서와 같이 다음과 같이 사용할 수 있습니다.
코드 사본은 다음과 같습니다.
$ {columnname} 주문
여기서 mybatis는 줄을 수정하거나 탈출하지 않습니다.
중요 : 사용자로부터 컨텐츠 출력을 수락하여 명령문에서 변경되지 않은 문자열에 제공하는 것은 안전하지 않습니다. 이로 인해 잠재적 인 SQL 주입 공격이 발생할 수 있으므로 사용자가 이러한 필드에 들어가거나 일반적으로 탈출하여 직접 확인할 수 없습니다.