
실습 암기노트
chap03-dynamic-sql-lecture
1. if
2. choose / when / otherwise
3. trim / where / set
4. foreach
5. bind
if역할
형태
<if test="title != null">
AND title LIKE #{title}
</if>
포인트
if 여러 개 사용 가능Map에 넣어서 키 이름으로 비교하는 패턴을 많이 씀Map<String, Integer> map = new HashMap<>();
map.put("price", price):
choose/when/otherwise역할
형태
<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>
포인트
if여러개 사용 시 참일 경우 모두 적용되지만 choose는 하나만 적용된다.공통 역할
WHERE, AND, , 같은 것을 자동으로 정리역할
형태
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="writer != null">
writer = #{writer}
</if>
<if test="title != null">
AND title LIKE #{title}
</if>
</trim>
포인트
where역할
형태
<where>
<if test="writer != null">
writer = #{writer}
</if>
<if test="title != null">
AND title LIKE #{title}
</if>
</where>
포인트
set문제상황
, 가 앞뒤로 붙어 구문오류가 발생할 수 있다.<update id="updateMenu">
UPDATE tbl_menu
<if test="menuName != null and menuName != ''">
SET menu_name = #{ menuName },
</if>
<if test="categoryCode != null and categoryCode gt 0">
category_code = #{ categoryCode }
</if>
.
만약 첫번째 <if> 가 조건불충족으로 넘어가면, '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>
포인트
<set> 을 사용 안하면 <if> 조건에 따라 SET 과 ,이 남거나 없어져서 구문오류가 발생할 수 있다., 자동 제거역할
주요 속성
collection : 반복 대상 (예: list, ids 등)item : 반복마다 꺼내 쓸 변수 이름index : 인덱스 (옵션)open : 처음에 붙일 문자 (예: ()separator : 사이사이에 넣을 구분자 (예: ,)close : 마지막에 붙일 문자 (예: ))형태
WHERE TITLE IN
<foreach item="item" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
결과 예
WHERE TITLE IN ('XXX', '사행성', '욕설', ...)
포인트
@풀클래스명@필드명, @풀클래스명@메소드명())역할
형태
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BOARD
WHERE title LIKE #{pattern}
포인트
_parameter로 넘어온 객체에 접근@SelectProvider, @InsertProvider 등을 붙여 사용역할
형태
@ResultMap("menuResultMap")
@SelectProvider(type = SelectBuilderProvider.class,
method = "searchMenuByCondition")
List<MenuDTO> searchMenuByCondition(SearchCriteria searchCriteria);
포인트
역할
형태
@DeleteProvider(type = SqlBuilderProvider.class, method = "deleteMenu")
int deleteMenu(@Param("code") int code);
포인트
#{code}로 접근 가능 SQL sql = new SQL();
sql.SELECT("menu_code", "menu_name", "menu_price", "category_code", "orderable_status")
.FROM("tbl_menu");
if("category".equals(searchCriteria.getCondition())) {
sql.JOIN("tbl_category USING (category_code)")
.WHERE("orderable_status = 'Y'")
.AND()
.WHERE("category_name = #{ value }");
} else if ("name".equals(searchCriteria.getCondition())) {
sql.WHERE(
"orderable_status = 'Y'",
"menu_name LIKE CONCAT('%', #{ value }, '%')"
);
}
return sql.toString();
WHERE구절을 살펴보면, AND() 가 사이에 있든, 없든 동일한 역할을 수행한다. 자동 AND() 처리된다.출력
chap03-dynamic : section02
.
.
SqlSession sqlSession = getSqlsession();
SelectBuilderMapper mapper = sqlSession.getMapper(SelectBuilderMapper.class);
List<MenuDTO> menuList = mapper.selectAllMenu(); //받아오는 곳
if(menuList != null && !menuList.isEmpty()){
menuList.forEach(System.out :: println);
} else {
System.out.println("검색 결과가 존재하지 않습니다.");
역할
org.apache.ibatis.jdbc.SQL 객체를 사용해 체이닝 방식으로 SQL을 조립하고 toString()으로 문자열 반환기본 패턴
public String searchMenuByCondition(SearchCriteria searchCriteria) {
SQL sql = new SQL();
sql.SELECT("A.MENU_CODE")
.SELECT("A.MENU_NAME")
.FROM("TBL_MENU A");
if ("category".equals(searchCriteria.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(searchCriteria.getCondition())) {
sql.WHERE("A.ORDERABLE_STATUS = 'Y'",
"A.MENU_NAME LIKE CONCAT('%', #{value}, '%')");
}
return sql.toString();
}
포인트
SELECT, FROM, JOIN, WHERE, AND, OR, INSERT_INTO, VALUES, UPDATE, SET, DELETE_FROM 등 메서드 제공if로 SELECT/WHERE/SET 조합을 바꾸면서 동적 쿼리 구현InsertProvider
@InsertProvider(type=SqlBuilderProvider.class, method="insertMenu")
int insertMenu(SqlBuilderProvider
@InsertProvider(type = SqlBuilderProvider.class, method = "insertMenu") no usages
int insertMenu(MenuDTO menuDTO);
/* 전달 파라미터가 유효한 값(문자열의 경우 빈 문자열이 아니여야 하고 숫자의 경우 0이상_을 가질
* 경우에만 수정에 반영하는 동적쿼리*/
@UpdateProvider(type= SqlBuilderProvider.class, method= "updateMenu") no usages new *
int updateMenu(MenuDTO menuDTO);
/* 기본 자료형 값을 전달하는 경우 @Param 어노테이션을 이용해야 한다.
* 또는 전달 값이 2개 이상인 경우에도 @Param어노테이션을 사용해야 한다.
* 단, Provider 메소드의 매개변수 선언부는 없애야 한다.
* */
@DeleteProvider(type= SqlBuilderProvider.class, method= "deleteMenu") no usages new x
int deleteMenu(@Param("menuCode") int menuCode);
& macacolabs
@ResultMap("menuResultMap")
@SelectProvider(type=SelectBuilderProvider.class, method="searchMenuByCondition")
List<MenuDTO> searchMenuByCondition(SearchCriteria searchCriteria);@DeleteProvider(type=SqlBuilderProvider.class, method="deleteMenu")
int deleteMenu(@Param("code") int code);public String deleteMenu() {
*// 내용*
return sql.toString();
}SELECT Provider
public String searchMenuByCondition(SearchCriteria searchCriteria) {
SQL sql = new SQL();
sql.SELECT("A.MENU_CODE") // select 대상 컬럼
.SELECT("A.MENU_NAME")
.SELECT("A.MENU_PRICE")
.SELECT("A.CATEGORY_CODE")
.SELECT("A.ORDERABLE_STATUS")
.FROM("TBL_MENU A"); // select 대상 테이블
if("category".equals(searchCriteria.getCondition())) {
sql.JOIN("TBL_CATEGORY B ON (A.CATEGORY_CODE = B.CATEGORY_CODE)") // join 구문
.WHERE("A.ORDERABLE_STATUS = 'Y'")
.AND()
.WHERE("B.CATEGORY_NAME = #{ value }");
} else if("name".equals(searchCriteria.getCondition())) {
sql.WHERE("A.ORDERABLE_STATUS = 'Y'"
, "A.MENU_NAME LIKE CONCAT('%', #{ value }, '%')"); // 조건절
}
return sql.toString();
}
INSERT Provider
public String registMenu(MenuDTO menu) {
SQL sql = new SQL();
sql.INSERT_INTO("TBL_MENU") // insert 대상 테이블
.VALUES("MENU_NAME", "#{ name }") // (insert *대상 컬럼*, #{ *필드명* })
.VALUES("MENU_PRICE", "#{ price }")
.VALUES("CATEGORY_CODE", "#{ categoryCode }")
.VALUES("ORDERABLE_STATUS", "#{ orderableStatus }");
return sql.toString();
}
UPDATE Provider
public String modifyMenu(MenuDTO menu) {
SQL sql = new SQL();
sql.UPDATE("TBL_MENU"); // update 대상 테이블
if(menu.getName() != null && !"".equals(menu.getName())) {
sql.SET("MENU_NAME = #{ name }"); // set 구문 작성
}
if(menu.getPrice() > 0) {
sql.SET("MENU_PRICE = #{ price }");
}
if(menu.getCategoryCode() > 0) {
sql.SET("CATEGORY_CODE = #{ categoryCode }");
}
if(menu.getOrderableStatus() != null && !"".equals(menu.getOrderableStatus())) {
sql.SET("ORDERABLE_STATUS = #{ orderableStatus }");
}
sql.WHERE("MENU_CODE = #{ code }"); // 조건절 작성
return sql.toString();
}
DELETE Provider
public String deleteMenu(int code) {
SQL sql = new SQL();
sql.DELETE_FROM("TBL_MENU") // delete 대상 테이블
.WHERE("MENU_CODE = #{ code }"); // 조건절 작성
return sql.toString();
}