📢 Enterprise v4.7.2 Released

Enhanced AI SQL Writing feature, supports generating dynamic SQL

Skip to content

SQL 작성 규칙

동적 SQL 태그 구문

동적 SQL 기능을 통해 조건에 따라 SQL 문장을 동적으로 생성할 수 있습니다. 특정 태그를 사용하면 복잡한 SQL 로직을 간편하게 구현할 수 있습니다. 다음은 동적 SQL에서 자주 사용되는 태그와 그 활용법입니다.

1. if 태그

if 태그는 조건 판단에 사용되며, Java의 if 문과 유사합니다.

xml
SELECT * FROM BLOG WHERE state = 'ACTIVE'
<if test="title != null">
  AND title like #{title}
</if>

파라미터 예시

json
{
  "title": "MyBlog"
}

최종 SQL

sql
SELECT * FROM BLOG WHERE state = 'ACTIVE' AND title like ?

2. choose, when, otherwise 태그

이들 태그는 Java의 switch 문과 유사합니다.

xml
SELECT * FROM BLOG WHERE state = 'ACTIVE'
<choose>
  <when test="title != null">
    AND title = #{title}
  </when>
  <when test="author != null and author.name != null">
    AND author_name = #{author.name}
  </when>
  <otherwise>
    AND featured = 1
  </otherwise>
</choose>

파라미터 예시

json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  }
}

최종 SQL

sql
SELECT * FROM BLOG WHERE state = 'ACTIVE' AND title = ? AND author_name = ?

3. trim, where, set 태그

이들 태그는 SQL 문장에서 접두사, 접미사 및 연결어 처리에 사용됩니다.

trim 태그

trim 태그는 사용자 정의 문자열 잘라내기를 지원합니다.

xml
SELECT * FROM BLOG 
<trim prefix="WHERE" prefixOverrides="and |or ">
  <if test="title != null">
    and title like #{title}
  </if>
  <if test="author != null">
    and author_name like #{author.name}
  </if>
</trim>
파라미터 예시
json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  }
}
최종 SQL
sql
SELECT * FROM BLOG WHERE title like ? AND author_name like ?

where 태그

where 태그는 생성된 SQL 문장 앞에 where 키워드를 자동으로 추가하며, 첫 번째 and 또는 or 키워드를 제거합니다.

xml
SELECT * FROM BLOG 
<where>
  <if test="title != null">
    and title like #{title}
  </if>
  <if test="author != null">
    and author_name like #{author.name}
  </if>
</where>
파라미터 예시
json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  }
}
최종 SQL
sql
SELECT * FROM BLOG WHERE title like ? AND author_name like ?

set 태그

set 태그는 동적 UPDATE 문을 작성할 때 사용되며, SET 키워드를 자동으로 추가하고 마지막 쉼표를 제거합니다.

xml
UPDATE BLOG
<set>
  <if test="title != null">title = #{title},</if>
  <if test="author != null">author_name = #{author.name},</if>
</set>
WHERE id = #{id}
파라미터 예시
json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  },
  "id": 123
}
최종 SQL
sql
UPDATE BLOG SET title = ?, author_name = ? WHERE id = ?

4. foreach 태그

foreach 태그는 주로 컬렉션을 순회하여 IN 조건을 생성하는 데 사용됩니다.

xml
SELECT * FROM BLOG
WHERE id in
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
  #{item}
</foreach>

파라미터 예시

json
{
  "list": [1, 2, 3, 4, 5]
}

최종 SQL

sql
SELECT * FROM BLOG WHERE id in (?, ?, ?, ?, ?)

5. bind 태그

bind 태그는 변수를 생성하고 OGNL 표현식의 값을 해당 변수에 바인딩하는 데 사용됩니다.

xml
<bind name="pattern" value="'%' + title + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}

파라미터 예시

json
{
  "title": "MyBlog"
}

최종 SQL

sql
SELECT * FROM BLOG WHERE title LIKE ?

SQL 파라미터 삽입

동적 SQL에서 #{}${}는 모두 파라미터 참조에 사용되지만, 파라미터 처리 방식에는 몇 가지 중요한 차이가 있습니다.

#{}의 사용법

  1. 준비 컴파일 처리: #{}는 JDBC의 ? 자리표시자를 대체하는 역할을 하며, 준비 컴파일 과정을 거쳐 PreparedStatement을 통해 파라미터를 설정합니다.
  2. 자동 이스케이프 처리: #{}는 전달된 파라미터를 자동으로 이스케이프 처리하므로 SQL 인젝션 공격을 효과적으로 방지합니다.
  3. 타입 처리: #{}는 전달된 파라미터의 타입 변환도 처리합니다.

예시:

sql
SELECT * FROM BLOG WHERE title LIKE #{title}

전달된 파라미터 titleMyBlog일 경우, 최종 SQL은 다음과 같습니다:

sql
SELECT * FROM BLOG WHERE title LIKE ?

${}의 사용법

  1. 직접 치환: ${}는 파라미터 값을 직접 SQL 문장에 삽입하며, 준비 컴파일 과정을 거치지 않습니다. 따라서 ${}를 사용할 때는 SQL 인젝션 위험을 각별히 주의해야 합니다.
  2. 이스케이프 없음: ${}는 전달된 파라미터를 이스케이프하지 않으므로 동적 테이블명이나 열명을 지정할 때 적합합니다.
  3. 타입 미처리: ${}는 파라미터의 타입을 변환하지 않고, 단순히 toString() 메서드를 통해 값을 사용합니다.

예시:

xml
SELECT * FROM BLOG WHERE title LIKE '${title}'

전달된 파라미터 titleMyBlog일 경우, 최종 SQL은 다음과 같습니다:

sql
SELECT * FROM BLOG WHERE title LIKE 'MyBlog'

사용 시 권장 사항

  • #{} 사용: 대부분의 경우, 특히 사용자 입력이 포함된 상황에서는 SQL 인젝션을 방지하기 위해 #{}를 우선적으로 사용하는 것이 좋습니다.
  • ${} 사용: 동적 테이블명이나 열명을 생성해야 하며, 전달된 파라미터가 안전하다고 확신되는 경우에만 ${}를 사용합니다.

시스템 내장 변수

DBAPI 시스템에는 현재 클라이언트의 ID를 가져오는 내장 변수인 __clientId가 이미 존재하며, 이를 바로 SQL 파라미터로 사용할 수 있습니다.

사용 예시:

sql
SELECT * FROM users WHERE client_id = #{__clientId}

특수 문자 이스케이프

작은 괄호 < 이스케이프

SQL 문장에서 작은 괄호 <&lt;로 이스케이프되어야 합니다.

잘못된 예시:

sql
-- 오류: XML 해석 오류 발생
SELECT * FROM users WHERE age < 18

올바른 예시:

sql
-- 올바른 방법: 이스케이프 문자 사용
SELECT * FROM users WHERE age &lt; 18