스프링(Spring)

Dynamic SQL (MyBatis 동적 SQL), AOP(Aspect Oriented Programming)

개발학생 2022. 11. 2. 20:22
반응형

*22년 4월 한 달간 한국이러닝협회의 '실전 개발자를 위한 Spring Framework'를 수강하고 정리한 내용입니다

*모든 이미지의 출처는 한국이러닝협회의 '전 개발자를 위한 Spring Framework'에 있습니다

 

 

 

1. MyBatis 동적 SQL

1) Dynamic SQL

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

 

2) MyBatis의 표현식

(1) if - MyBatis에서 가장 공통적으로 사용되는 요소

* 아래 구문은 파라미터 중 title에 값이 존재할 경우 and title like #{title} 구문을 본 쿼리문에 포함시킨다.

<select id="findActiveBlogWithTitleLike" resultType="Blog">
	select * from blog where state = 'ACTIVE'
    <if test="title != null">
    	and title like #{title}
    </if>
</select>

 

* 아래 구문은 author와 author.name 파라미터에 값이 존재할 경우 and author_name like #{author.name} 구문을 쿼리문에 포함시킴

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

<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>

 

(2) choose (when, otherwise)

- 여러 구문 중 하나만 실행

- title 파라미터의 값이 존재하면 and title like #{title} 구문을 포함

- author와 author.name 파라미터 값이 존재한다면 and author_name like #{author.name} 구문을 포함
  둘 다 존재하지 않는다면 and featured=1 구문을 포함

<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>
        	and featured=1
        </otherwise>
    </choose>
</select>

 

 

(3) trim (where,set) - 여러 구문 중 하나만 실행

- <where> </where>는 내부에 컨텐츠가 존재할 때 where 키워드를 포함함
  내부에 컨텐츠가 존재하지 않으면 where 키워드를 쓰지 않음

 

* where 다음 and 혹은 or가 바로 올 경우, 다음과 같이 and/or 키워드를 삭제함

<trim prefix="WHERE" prefixOverrides="AND | OR">
  ...
</trim>

 

* 아래 구문과 같이 trim을 바로 사용할 수도 있음

<select id="findActiveBlogLike" resultType="Blog">
	select *
    from BLOG
    <trim prefix="WHERE" prefixOverrids="AND">
    	<if test="state != null">
        	state = #{state}
        </if>
        <if test="title != null">
        	title like #{title}
        </if>
        <if test="author != null and author.name != null">
        	author_name like #{author.name}
        </if>
    </trim>
</select>

 

* 아래 구문은 잘못 사용된 예

<select id="findActiveBlogLike" resultType="Blog">
	select *
    from BLOG
    where
    <if test="state != null">
    	state = #{state}
    </if>
    <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>

 

* 만약 아무런 파라미터도 없다면 다음과 같은 쿼리가 만들어짐

select *
from blog
where

 

(4) foreach

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

- collection 속성은 파라미터가 List일 경우는 list, 파라미터가 Array(배열)일 경우는 array를 사용

- in 키워드 사용 시 종종 사용됨

<select id="selectPostIn" resultType="domain.blog.Post">
	select * from post p where id in
    <foreach item="item" index="index" collection="list" open="("separator=","close=")">
    	#{item}
    </foreach>
</select>

 

3) 동적 SQL 작성 시 유의사항

- MyBatis 구문을 이용하여 SQL문이 실행 시에 변경되기 때문에, 모든 케이스에 대해 테스트 진행해야 함

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

 

 

2. AOP(Aspect Oriented Programming)

1) AOP의 개요

(1) 핵심기능과 부가기능

- 핵심기능(Core Concerns): 업무(Biz) 로직을 포함하는 기능

- 부가기능(Cross-cutting Concerns): 핵심기능을 도와주는 부가적인 기능(로깅, 보안 등)

- 객체지향의 기본 원칙을 적용하여도, 핵심기능에서 부가기능을 분리해서 모듈화하는 것은 매우 어려움

 

(2) AOP의 정의 및 특징

출처: 한국이러닝협회 '실전 개발자를 위한 Spring Framework'

 

- 애플리케이션에선의 관심사의 분리(=기능의 분리)

   => 핵심적인 기능에서 부가적인 기능을 분리하고,
        분리한 부가기능을 애스펙트(Aspect)라는 독특한 모듈 형태로 만들어서(정의해서) 설계하고 개발하는 방법

- OOP(객체지향 프로그래밍)를 적용해도 핵심기능에서 부가기능을 쉽게 분리된 모듈로 작성하기 어려웠던 문제점을 해결

- 핵심기능에서 부가기능을 분리해서, 핵심기능을 설계하고 구현할 때 객체지향적인 가치를 지킬 수 있도록 도와주는 개념

 

2) AOP 용어

(1) 애스펙트(Aspect)

"Advice + PointCut = Aspect"

 

- AOP의 기본 모듈로, 싱글톤 형태의 객체로 존재

- 부가기능을 정의한 코드인 어드바이스(Advice)와 어드바이스를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합침

- AOP 개념을 적용하면, 핵심기능 코드 사이에 침투된 부가기능을 독립적인 애스펙트로 구분해 낼 수 있음

- 구분된 부가기능 애스펙트를 런타임 시에 필요한 위치에 동적으로 참여하게 할 수 있음

 

(2) 타깃(Target)

- 핵심기능을 담고 있는 모듈로, 타깃은 부가기능을 부여할 대상이 됨

 

(3) 어드바이스(Advice)

- 타깃에 제공할 부가기능을 담고 있는 모듈

 

(4) 조인 포인트(Join Point)

- 어드바이스가 적용될 수 있는 위치

- 타깃 객체가 구현한 인터페이스의 모든 메소드는 조인 포인트가 됨

 

(5) 포인트 컷(PointCut)

- 어드바이스를 적용할 타깃의 메소드를 선별하는 정규표현식

- 표현식은 execution으로 시작하고, 메소드의 Signature를 비교하는 방법을 주로 이용

 

(6) 어드바이저(Advisor)

- 어드바이저 = 어드바이스 + 포인트컷

- Spring AOP에서만 사용되는 특별한 용어

 

(7) 위빙(Weaving)

- 포인트컷에 의해 결정된 타깃의 조인 포인트에 부가기능(어드바이스)을 삽입하는 과정

- AOP가 핵심기능(타깃)의 코드에 영향을 주지 않으면서,
  필요한 부가기능(어드바이스)을 추가할 수 있도록 해주는 핵심적인 처리과정

 

3) Spring AOP의 특징

(1) Spring은 프록시(Proxy) 기반 AOP를 지원함

출처: 한국이러닝협회 '실전 개발자를 위한 Spring Framework'

- Spring은 타깃(target) 객체에 대한 프록시를 만들어 제공함

- 타깃을 감싸는 프록시는 실행시간(Runtime)에 생성됨

- 프록시: 어드바이스를 타깃 객체에 적용하면서 생성되는 객체

 

(2) 프록시(Proxy)가 호출을 가로챈다(Intercept)

- 전처리 어드바이스: 프록시는 타깃 객체에 대한 호출을 가로챈 다음,
                                  어드바이스의 부가기능 로직을 수행하고 난 후에 타깃의 핵심기능 로직을 호출함

- 후처리 어드바이스: 타깃의 핵심기능 로직 메소드를 호출한 후에 부가기능(어드바이스)을 수행하는 경우가 있음

 

(3) Spring AOP는 메소드 조인 포인트만 지원함

- Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메소드 조인포인트만 지원함

- 핵심기능(타깃)의 메소드가 호출되는 런타임 시점에만 부가기능(어드바이스)을 적용할 수 있음

- 반면에 AspectJ 같은 고급 AOP 프레임워크를 사용하면
  객체의 생성, 필드값의 조회와 조작, static 메소드 호출 및 초기화 등의 다양한 작업에 부가기능을 적용할 수 있음

 

 

 

 

 

 

 

 

 

 

반응형