MyBatis
1. MyBatis
- 데이터의 입력, 조회, 수정, 삭제(CRUD)를 보다편하게 할 수 있도록 xml로 구조화한 Mapper설정 파일을 통해 JDBC를 구현한 영속성 프레임워크.
- 기존에 JDBC를 통해 구현했던 상당 부분의 코드, 파라미터 설정 및 결과 mapping을 xml 설정으로 쉽게 구현할 수 있게 함.
- MyBatis는 기존 iBatis의 한계점인 Dynamic query(동적 쿼리)와 Annotation 처리를 보강하여 더 나을 기능을 제공함.
- iBatis는 현재 비활성화 상태이며, 기존에 iBatis로 만들어진 애플리케이션의 지원을 위한 라이브러리만 제공하고 있음.
2. MyBatis Configuration by JAVA
- Environment : 데이터베이스 접속에 관한 환경 설정 정보를 가진 객체로, MyBatis 환경 설정 객체를 생성하는 데 사용함.
- Configuration : 환경 설정 정보 Environment 객체를 가지고 생성한 MyBatis 설정 객체로, DB 접속 관련 정보, mapper 등록, 별칭 등록 등 MyBatis 전역 설정 정보를 담고 있음.
- SqlSessionFactory
- SqlSession 객체를 생성하기 위한 팩토리 역할을 수행하는 인터페이스.
- 애플리케이션이 실행되는 동안 여러 차례 빌드하지 않도록, 싱글톤 패턴 등을 이용하여 어플리케이션 스코프로 사용하는 것이 좋음.
- SqlSessionFactoryBuilder
- SqlSessionFactory 인터페이스 타입의 하위 구현 객체를 생성하기 위한 빌드 역할을 수행함.
- build() 메서드는 설정 정보를 담고 있는 Configuration 타입의 객체 혹은 외부 설정 파일과 연결된 스트림을 매개변수로 전달하면 SqlSessionFactory 인터페이스 타입의 객체를 반환함.
- MyBatis 인스턴스들의 Scope와 Life-Cycle
- SqlSessionFactoryBuilder : 로컬 스코프 -> 메서드 내부 또는 초기화 블럭 내부
- 일반적으로 한 번 SqlSessionFactory를 빌드하고 나면 더 이상 필요하지 않음. (일회성)
- 따라서 짧은 라이프 사이클을 가지게 되며 더 이상 필요하지 않게 되면 즉시 가비지 컬렉터의 대상이 될 수 있음.
- 일반적으로 데이터베이스 작업(CRUD 외 DDL 등)을 수행하는 동안에만 유효하기 때문에 짧은 라이프 사이클을 가지게 됨.
- SqlSessionFactory : 애플리케이션 스코프 -> 싱글턴 패턴 사용
- 애플리케이션 내에서 단 하나만 생성되도록 관리해야 함.
- 애플리케이션이 실행되는 동안 SqlSessionFactory가 여러 번 빌드되지 않도록 하는 것이 가장 좋은 형태.
- 애플리케이션이 실행되는 동안 여러 스래드(= SqlSession)에서 공유되기 때문에 긴 라이프 사이클을 가지게 됨.
- SqlSession : 메서드 스코프 or 트랜잭션 -> 메서드 내부 또는 트랜잭션 범위 내부
- 추후 웹 요소가 결합되면 HTTP 요청과 밀접한 생명 주기를 가져감. 즉, HTTP 요청이 발생했을 때 객체가 생성되고, 요청에 대한 HTTP 응답이 전송되면 객체를 폐기하면 되기 때문에 HTTP 요청과 유사한 스코프에 두는 것이 가장 올바른 방법.
- 데이터베이스 작업이 끝난 후에는 반드시 close() 메서드를 호출하여 리소스를 반환해야 하며, 그렇지 않으면 연결 누수(Connection Leak)가 발생하게 되고 이는 메모리 누수(Memory Leak)로 이어질 수 있음.
3. MyBtis Configuration by XML
- properties
- 설정 파일에서 공통적인 속성을 정의하거나 외부 파일에서 값을 가져오는 태그.
- 외부 프로퍼티 파일은 resource 하위의 경로를 기술하면 기술하면 됨.
- settings
- SqlSessionFactory 객체가 SqlSession 객체를 만들 때, 생성할 객체의 특성을 설정함.
- settings 엘리먼트의 하위 엘리먼트들은 대부분 디폴트값을 가지며, 특별한 경우가 아니면 디폴트값을 사용해도 무방함.
- typeAliases
- MyBatis에서 사용할 자료형의 별칭을 선언함.
- mapper의 쿼리를 작성할 때 ResultType이나 parameter 속성에 풀클래스명으로 사용해야 하는 클래스의 별칭을 등록하여 간략하게 사용할 수 있음.
- environments
- MyBatis에서 연동할 Database 정보를 등록함.
- transactionManager : 트랜잭션 메니저를 JDBC 혹은 MANAGED로 설정할 수 있음.
- JDBC : MyBatis API에서 제공하는 commit, rollback 메서드 등을 사용해서 트랜잭션을 관리하는 방식 (수동 commit)
- MANAGED : MyBatis API 보다는 컨테이너가 직접 트랜잭션을 관리하는 방식 (자동 commit)
- dataSource : 속성으로 커넥션풀 사용 여부를 POOLED와 UNPOOLED로 설정할 수 있음.
- 설정 가능한 type 중 JNDI도 있는데, 이는 MyBatis에서 Connection 객체를 생성하여 관리하지 않고 Web Application의 설정을 따르겠다는 의미.
- mappers
- 사용하고자 하는 쿼리가 정의된 mapper 파일을 등록함.
- <mapper resource=""> : (상대경로) 클래스패스에 위치한 xml 매퍼 파일 지정
- <mapper url=""> : (절대경로) URL을 사용한 xml 매퍼 파일 지정
- <mapper class=""> : 매퍼 인터페이스를 사용하는 인터페이스 위치 지정
- <mapper name=""> : 패키지 지정으로 패키지 내 자동으로 매퍼 검색
Dynamic Query
1. MyBatis Dynamic Query
- 일반적으로 검색 기능이나 다중 입력 처리 등을 수행할 경우, SQL을 실행하는 DAO를 여러 번 호출하거나 batch 기능을 이용하여 버퍼에 담아서 한번에 실행시키는 방식으로 쿼리를 구현함.
- MyBatis에서는 이를 동적으로 제어할 수 있는 구문을 제공하여 쿼리를 좀 더 쉽게 구현할 수 있는 기능을 지원함.
2. if
- 동적 쿼리를 구현할 때 가장 기본적으로 사용되는 구문.
- 특정 조건을 만족하는 경우 내부의 구문을 쿼리에 포함함.
3. choose (when, otherwise)
- Java의 if-else, switch 구문과 JSTL의 choose 구문과 유사하며 주어진 구문 중 한 가지만 수행할 때 사용함.
4. trim (where, set)
- <trim> : 쿼리의 구문의 특정 부분을 없앨 때 쓰임.
- <where> : 기존 쿼리의 WHERE 절을 동적으로 구현할 때 쓰임.
- <set> : 기존 쿼리의 UPDATE SET 절을 동적으로 구현할 때 쓰임.
5. foreach
- Java의 for문과 같은 역할을 하는 것으로, 동적 쿼리를 구현할 때 collection에 대한 반복 처리를 제공함.
6. bind
- 특정 문장을 미리 생성하여 쿼리에 적용해야 할 경우 사용함.
- '_parameter'를 통해 전달 받은 값에 접근하여 구문을 생성함.
MyBatis Dynamic Query (Java Provider) 구문
1. Java Provider
- MyBatis에서 제공하는 기술로 어노테이션과 Java configuration을 이용하여 동적 쿼리를 작성할 수 있음.
- 인터페이스에서 Provider Annotation을 통해 Provider 클래스를 type으로 설정하고 method로 쿼리ID를 설정하여 매핑함.
2. @Provider
- 매퍼 인터페이스의 메서드에 어노테이션을 작성해야 함.
- 어노테이션은 수행할 쿼리문에 따라 @SelectProvider, @InsertProvider, @UpdateProvider, @DeleteProvider로 작성함.
- 어노테이션의 type 속성에는 Provider의 클래스 타입을, method에는 수행할 쿼리ID를 적음.