본문 바로가기

Archived(Programming)/Spring #2(기초)

Dynamic SQL

# Dynamic SQL

검색 조건에 따라 검색해야 하는 SQL문이 달라지기 때문에 이를 처리하기 위해서 동적 SQL이 사용됨

 

MyBatis 표현식

if, trim(where, set), choose(when, otherwise), foreach

 

동적 SQL 작성 시 유의사항

Mybatis 구문을 이용하여 SQL문이 실행 시에 변경되기 때문에 모든 케이스에 대해 테스트가 이루어져야 함

동적 SQL문이 없는 상태에서 정상적인 실행 확인 후에 동적 SQL을 추가해서 개발

 

# 예시

if를 활용한 동적 구문

if를 통해 쿼리문에 조건을 걸 수 있다.

파라미터 타입 안에 다른 타입(클래스)가 포함되어 캡슐화를 이용할 경우 .(연산자)를 통해 접근 가능

<select id="findActiveBlogWithTitleLike" resultType="Blog">
	SELECT * FROM BLOG WHERE state='ACTIVE'
    <if test="title != null">
    	AND TITLE LIKE #{title}
    </if>
</select>
<select id="findActiveBlogLike" resultType="Blog">
	SELECT * FROM BLOG WHERE state='ACTIVE'
    <if test="title != null">
    	AND TITLE LIKE #{title}
    </if>
    <if test="author != null and author.name !=null">
    	AND author_name like #{author.name}
    </if>
</select>

 

choose(when, otherwise)

<select id="findActiveBlogLike" resultType="Blog">
	SELECT * FROM BLOG WHERE state='ACTIVE'
    <choose>
      <when test="title != null">
          AND TITLE LIKE #{title}
      </when>
      <when test="author != null and author.name !=null">
          AND author_name like #{author.name}
      </when>
      <otherwise>
          ...
      </otherwise>
	</choose>
</select>

switch~case의 형태와 유사

 

trim(where, set)

만약 WHERE 후에 IF문이 아무것도 걸리지 않는다면 구문 오류가 발생

trim을 통해 해결(만약 if문에 해당하면 prefix를 통해 WHERE도 붙고 뒤에 그에 따라서 AND도 붙어서 정확한 결과 도출 가능)

<select id="findActiveBlogLike" resultType="Blog">
	SELECT * FROM BLOG 
    <trim prefix="WHERE" prefixOverrids="AND">
      <if test="title != null">
          state = #{state}
      </if>
      <otherwise>
          ...
      </otherwise>
	</trim>
</select>

set 키워드를 통해서 <set></set> 은 내부에 컨텐츠가 존재할 때 set 키워드를 포함시킴

그렇지 않을 경우는 set키워드를 쓰지 않음(update set 옵션시 사용)

<update id="updateAuthorIfNecessary">
	UPDATE AUTHOR
    <trim prefix="SET" prefixOverrids=",">
      <if test="title != null">
          state = #{state}
      </if>
      <otherwise>
          ...
      </otherwise>
	</trim>
</select>

foreach

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

IN 키워드를 사용할 때 종종 사용됨

collection 속성은 List일 경우는 list, array가 사용된다

파라미터가 List일 경우 list, Array일 경우 array 사용

<select id="selectPostIn" resultType="Blog">
	SELECT * FROM POST P WHERE ID in
    <foreach item="item" index="index" collection="list"
    	open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

# 실습 insert, selectById 테스트, Dyanamic Query 예제

Mapper의 query 구문을 Mysql로 가져와서 테스트

그리고 insert를 실제로 실행

package kr.co.acomp.hello.dao;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import kr.co.acomp.hello.vo.Article;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
	"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml",
	"file:src/main/webapp/WEB-INF/spring/root-context.xml"}
)
public class ArticleDAOTest {

	@Autowired
	private ArticleDAO dao;
	
	@Test
	public void testInsertArticle() {
		Article article = new Article(3,"yoon","test","test");
		dao.insertArticle(article);
	}
	
	...
}

test 실행 후 MySQL DB 확인하기

package kr.co.acomp.hello.dao;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import kr.co.acomp.hello.vo.Article;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
	"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml",
	"file:src/main/webapp/WEB-INF/spring/root-context.xml"}
)
public class ArticleDAOTest {

	@Autowired
	private ArticleDAO dao;
	
	@Test
	@Ignore
	public void testInsertArticle() {
		Article article = new Article(3,"yoon","test","test");
		dao.insertArticle(article);
	}
	
	@Test
	public void testSelectArticleById() {
		// Test
		Article article = dao.selectArticleById("3");
		System.out.println(article);
		// 값 결과 확인
		Assert.assertTrue(article.getAuthor().contentEquals("yoon"));
	}
}

test 실행 후 결과 값 확인

'Archived(Programming) > Spring #2(기초)' 카테고리의 다른 글

PointCut 표현식과 Advisor 구현  (0) 2020.03.17
AOP(Aspect Oriented Programming)  (0) 2020.03.17
Mapper XML 파일  (1) 2020.03.16
Spring Mybatis  (0) 2020.03.15
Context 분리와 전략  (0) 2020.03.13