
if — 조건부 구문 삽입<select id="searchBoard" resultType="arraylist">
SELECT * FROM BOARD
WHERE writer = 'admin'
<if test="title != null">
AND title LIKE #{title}
</if>
</select>
choose — 단일 가지 선택<select id="searchBoard" resultType="arraylist">
SELECT * FROM BOARD
WHERE COMMENT != ''
<choose>
<when test="title != null">
AND title LIKE #{title}
</when>
<when test="writer != null">
AND writer LIKE #{writer}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
trim / where / set — 접두/접미 제어로 문법 오류 방지SELECT * FROM BOARD
WHERE
<if test="writer != null">writer = #{writer}</if>
<if test="title != null">AND title LIKE #{title}</if>
WHERE만 남아 오류WHERE AND 오류trim으로 해결<select id="searchBoard" resultType="arraylist">
SELECT * FROM BOARD
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="writer != null">
writer = #{writer}
</if>
<if test="title != null">
AND title LIKE #{title}
</if>
</trim>
</select>
where로 간단 해결<select id="searchBoard" resultType="arraylist">
SELECT * FROM BOARD
<where>
<if test="writer != null">
writer = #{writer}
</if>
<if test="title != null">
AND title LIKE #{title}
</if>
</where>
</select>
where는 내부가 AND/OR로 시작하면 자동 제거.set — 동적 업데이트 컬럼<update id="updateUser">
UPDATE USER
<set>
<if test="username != null">username = #{username},</if>
<if test="password != null">password = #{password},</if>
</set>
WHERE id = #{id}
</update>
trim으로 대체 가능:<trim prefix="SET" suffixOverrides=",">
...
</trim>
foreach — 컬렉션 반복(IN 절 등)| 속성 | 설명 |
|---|---|
collection | 반복 대상(list, array, map 등) |
item | 각 반복 원소 변수명 |
index | 인덱스(선택) |
open / separator / close | 앞/구분자/뒤 문자열 |
<select id="searchBadwords" resultType="arraylist">
SELECT * FROM BOARD
WHERE TITLE IN
<foreach collection="list" item="word" open="(" separator="," close=")">
#{word}
</foreach>
</select>
collection="@풀클래스경로@필드" 또는 @풀클래스경로@메서드()<foreach collection="@com.example.Application@createCodes()" item="code"
open="(" separator=", " close=")">
#{code}
</foreach>
bind — 미리 가공한 값 바인딩<select id="searchBoard" resultType="arraylist">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'"/>
SELECT * FROM BOARD
WHERE title LIKE #{pattern}
</select>
@ResultMap("menuResultMap")
@SelectProvider(type = SelectBuilderProvider.class, method = "searchMenuByCondition")
List<MenuDTO> searchMenuByCondition(SearchCriteria criteria);
@DeleteProvider(type = SqlBuilderProvider.class, method = "deleteMenu")
int deleteMenu(@Param("code") int code);
@Param으로 이름 부여.@Param을 쓰면 Provider 메서드 시그니처는 매개변수 없이 작성하고 #{code}로 참조.public String searchMenuByCondition(SearchCriteria c) {
SQL sql = new SQL()
.SELECT("A.MENU_CODE", "A.MENU_NAME", "A.MENU_PRICE", "A.CATEGORY_CODE", "A.ORDERABLE_STATUS")
.FROM("TBL_MENU A");
if ("category".equals(c.getCondition())) {
sql.JOIN("TBL_CATEGORY B ON (A.CATEGORY_CODE = B.CATEGORY_CODE)")
.WHERE("A.ORDERABLE_STATUS = 'Y'")
.AND().WHERE("B.CATEGORY_NAME = #{value}");
} else if ("name".equals(c.getCondition())) {
sql.WHERE("A.ORDERABLE_STATUS = 'Y'",
"A.MENU_NAME LIKE CONCAT('%', #{value}, '%')");
}
return sql.toString();
}
public String registMenu(MenuDTO m) {
return new SQL()
.INSERT_INTO("TBL_MENU")
.VALUES("MENU_NAME", "#{name}")
.VALUES("MENU_PRICE", "#{price}")
.VALUES("CATEGORY_CODE", "#{categoryCode}")
.VALUES("ORDERABLE_STATUS", "#{orderableStatus}")
.toString();
}
public String modifyMenu(MenuDTO m) {
SQL sql = new SQL().UPDATE("TBL_MENU");
if (m.getName() != null && !m.getName().isEmpty()) sql.SET("MENU_NAME = #{name}");
if (m.getPrice() > 0) sql.SET("MENU_PRICE = #{price}");
if (m.getCategoryCode() > 0) sql.SET("CATEGORY_CODE = #{categoryCode}");
if (m.getOrderableStatus() != null && !m.getOrderableStatus().isEmpty())
sql.SET("ORDERABLE_STATUS = #{orderableStatus}");
sql.WHERE("MENU_CODE = #{code}");
return sql.toString();
}
public String deleteMenu() { // @Param("code") 사용 시 인자 없음
return new SQL()
.DELETE_FROM("TBL_MENU")
.WHERE("MENU_CODE = #{code}")
.toString();
}
where, set, trim(prefixOverrides|suffixOverrides) 활용.#{} 사용 권장. ${}는 그대로 치환되어 인젝션 위험.!= null만이 아니라 빈 문자열 체크까지 함께.foreach로 안전하게 구성.bind로 미리 생성.@*Provider, 구현은 org.apache.ibatis.jdbc.SQL.@Param으로 명시, DTO/Map은 필드/키로 접근.<where>
<if test="a != null">A = #{a}</if>
<if test="b != null">AND B = #{b}</if>
</where>
<set>
<if test="x != null">X = #{x},</if>
<if test="y != null">Y = #{y},</if>
</set>
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
<bind name="kw" value="'%' + _parameter.keyword + '%'"/>
WHERE COL LIKE #{kw}
핵심 요약
where/set/trim, IN 절은 foreach, 값 가공은 bind.#{} 우선, 동적 구조는 명확하게.