티스토리 뷰

프레임워크/Spring

Dynamic Query

안싱미 2016. 4. 20. 16:04

Dynamic SQL

쿼리 내에 조건문을 이용해서 중복되는 쿼리들을 최소화시킬 수 있다.


#Dynamic Query 의 종류

  • If

  • Choose

    • Java의 else if 격

  • Trim

  • Foreach

    • 잘 사용되지 않지만 가끔 사용한다.


#if

파라미터로 받아온 값을 조건절로 거를 때 사용한다.

파라미터 타입 안에 다른 타입(클래스)가 포함되어 캡슐화를 이룰 경우 .(dot) 연산자로 변수 접근이 가능하다.


#choose

Else if 가 없기 때문에 choose로 사용한다.

<choose></choose>로 로 크게 감싸고 <when test="조건"> </when>으로 조건을 걸고 <otherwise> </otherwise>로 기타를 거른다.


#Trim(where, set)

여러 구문 중 하나만 실행할 수 있다.


SELECT *

FROM   BLOG

WHERE

<if test="state != null">

    state = #{state}

</if>

<if test="title != null">

AND    title like #{title}

</if>


이런 구문에서 모든 조건이 해당되지 않아 빠져나온다면 SQL자체가 문법상 제대로 형성되지 않아서 SQL 문법 에러가 발생할 수 있다. 그러한 단점을 해결하기 위해서 Trim을 사용한다.


#ForEach

Dynamic Query에서 공통적으로 필요한 기능은 Collection의 반복 처리 기능


<foreach collection="array" item="배열명" separator=",">

    #{배열명}

</foreach>


Collection에는 배열이나 리스트만 사용이 가능하다 item은 파라미터 명을 적어주면 되고

Separator는 안에 담긴 Object들을 구분 시켜줄 기호이다




# 실습


1. firstName을 줄때가 있고, 안줄때가 있다고 할때 처리하는 방법


  • If를 사용하여 조건을 건다.

  • 또한 SELECT 에 보면 주석이 있는데 어떤 DAO에서 사용하는 건지와 작성 날짜를 적어주면 좋다.


쿼리 결과를 확인하기 위해서 ArticleDAOImpl에서 FirstName을 주석처리한다면 조건이 사라진 쿼리로 실행이 된다. 그렇기 때문에 하나의 쿼리로 두가지 상황의 쿼리를 생성할 수 있다.



결과는 다음과 같이 firstName을 주석처리해서 없으니 컬럼들이 조건절에 따라서 없어진 결과를 보여준다.



2.DEPARTMENTS에서 부서명을 더 가져오는 방법


아래와 같이 작성한다면, firstName이 있을 때 부서명을 출력할 수 있다.



departmentName을 출력할 수 있게 VO에 departmentName 변수를 선언하고, getter setter를 추가해준다.


그리고 jsp 에서 출력하는 구문을 추가한다.


그리고 실행을 해보면 아래처럼 잘 실행이 된다.


3. If를 choose when otherwise로 바꾸어서 똑같이 동작하는지 실행해본다.


실행해보면 2. 결과와 동일한 화면을 볼 수 있다.


4. Otherwise, when 절을 걸어보기

departmentName 이 찍히지 않는 것을 볼 수 있다.

이제는 when절을 하나 더 걸어서 두개의 조건으로 어떠한 쿼리가 생성되는지 테스트해본다.


현재 firstName 이 없으므로 2번의 쿼리가 실행된다.


실행을 해보면, 다음과 같다.



그러면 이제는 1번의 쿼리와 2번의 쿼리가 모두 참일 때 어떤 쿼리가 실행되는지 체크해본다.

이를 위해 다시 firstName의 주석을 풀고 다시 실행을 해본다.


결과는 다음과 같이 첫번째 when 절만 실행된 것을 볼 수 있다. When에서 첫번째로 걸린 쿼리를 사용한다.


5. Trim 이용하여 Last name을 조건절로



테스트를 진행하기 위해 lastName을 주석처리한 뒤 실행해본다.



이렇게 하면 에러가 발생한다. SQLSyntaxErrorException이 발생하는 것은, where절 이후에 lastName이 없어서 바로 and가 나오기 때문이다. 이를 해결하기 위해 3가지 방법이 있다.


  1. Where 절에 1=1 을 넣으면 무조건 참이 되고 그 외의 추가 조건들을 AND로 붙여버린다. 그러면 where절에는 무조건 에러가 발생하지 않고 AND 를 통해서 조건절에서 참인것만 추가가 되게 된다.

2) 하지만 위와 같은 방식은 잘 사용하지 않고 아래와 같은 방식으로 해결할 수도 있다.


이렇게 하면 if 구절에 참이 없다면 where 가 붙지 않게 된다. 그리고 firstName의 주석을 지우고 다시 실행을 해본다. 그렇다면 쿼리는 다음과 같이 작성된 것을 볼 수 있다.


WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID AND FIRST_NAME = ?


3) 더욱 편하게 사용을 하려면 trim을 사용하는 것도 볼 수 있다.

'프레임워크 > Spring' 카테고리의 다른 글

Web Socket  (0) 2016.04.27
Spring으로 간단한 게시판 만들어보기(1)  (1) 2016.04.21
MyBatis 전체 요약, CRUD(insert, select)  (0) 2016.04.20
Transaction, AOP, MyBatis 설정  (1) 2016.04.19
Controller, Interceptor, logger  (0) 2016.04.15
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함