42
- MyBatis - 주식회사 오픈 소스 컨설팅

MyBatis Basic

Embed Size (px)

DESCRIPTION

The MyBatis data mapper framework makes it easier to use a relational database with object-oriented applications. This document explain about MyBatis basic concept.

Citation preview

Page 1: MyBatis Basic

- MyBatis -

주식회사 오픈 소스 컨설팅

Page 2: MyBatis Basic

2 - Internal Use Only -

Introduction (1 / 3)

MyBatis란?

MyBatis는 관계형 데이터베이스 프로그래밍을 위한 퍼시스턴스 프레임워크로써 SQL을 자

바 코드가 아닌 XML로 따로 분리하여 관리하도록 지원하며, SQL 실행 결과를 POJO 또는

Map 객체에 매핑해 준다.

특징

간결함과 쉬운 접근성

자원의 효율적 관리 지원

파라메타를 전달하고 결과셋에서 데이터의 추출을 간단히 처리 가능

SQL을 XML이나 인터페이스 내의 애노테이션으로 관리 가능

트랜잭션 처리 지원

Page 3: MyBatis Basic

3 - Internal Use Only -

Introduction (2 / 3)

구조 mybatis-config.xml : 데이터베이스

설정과 트랜잭션 등 MyBatis가

동작하는 규칙을 정의

Mapper XML : SQL을 XML로 정의

Mapper Interface : SQL을

인터페이스의 메소드마다

애노테이션으로 정의

Mapper : Mapped Statement와

파라메타나 결과 타입 등을 지정

Mapped Statements : SQL을

정의한 구문으로써 XML과

애노테이션 두 가지 방식이 있다.

지원 파라메타 타입 : HashMap,

Java Object, Primitive

Page 4: MyBatis Basic

4 - Internal Use Only -

Introduction (3 / 3)

iBatis vs. MyBatis

구분 iBatis MyBatis

Namespace Optional Mandatory

매핑 구문 정의 XML XML, Annotation

Dynamic SQL XML Elements만 사용 XML Elements 및 구문 빌더 사용

Spring 연동 자체 구현체 사용 별도 라이브러리 모듈 지원

업데이트 ibatis-2.3.4.726를 마지막으로 공식 릴리즈 없음

mybatis-2.3.5를 시작으로 현재 3.2.3 까지 릴리즈

Page 5: MyBatis Basic

5 - Internal Use Only -

MyBatis 설치

https://github.com/mybatis/mybatis-3/releases 에서 mybatis-x.x.x.zip 파일을

다운로드 하고 압축을 해제한다.

Standalone Application

mybatis-x.x.x.jar 파일을 클래스패스에 추가한다.

java -cp mybatis-x.x.x.jar :... MainClass

Web Application

WEB-INF/lib 아래에 mybatis-x.x.x.jar 파일을 추가

Maven을 사용할 경우에는 pom.xml에 다음과 같이 MyBatis에 대한 Dependency만

추가하면 된다.

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>x.x.x</version>

</dependency>

Page 6: MyBatis Basic

6 - Internal Use Only -

MyBatis 설정 (1 / 3)

데이터베이스 설정과 트랜잭션 등 MyBatis가 동작하는 규칙을 정의하기 위해 MyBatis

설정 파일(mybatis-config.xml)을 작성한다.

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN“ "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<properties resource="mybatis/db.properties" />

<environments default="development">

<environment id="development">

<transactionManager type="JDBC"/> <!-- 트랜잭션 관리자 -->

<dataSource type="POOLED"> <!-- 데이터베이스 설정 -->

<property name="driver" value="${jdbc.driver}"/>

<property name="url" value="${jdbc.url}"/>

<property name="username" value="${jdbc.username}"/>

<property name="password" value="${jdbc.password}"/>

</dataSource>

</environment>

</environments>

<mappers> <!-- 매퍼 정보 설정 -->

<mapper resource="org/mybatis/example/BlogMapper.xml"/>

</mappers>

</configuration>

Page 7: MyBatis Basic

7 - Internal Use Only -

MyBatis 설정 (2 / 3)

트랜잭션 관리자

데이터베이스에서 트랜잭션은 가장 중요한 기능 중 하나로써 MyBatis가 JDBC를 대체 하

기 때문에 type은 JDBC로 지정한다.

JDBC 외에 컨테이너가 직접 트랜잭션을 관리할 경우 MANAGED를 사용할 수 있다.

데이터베이스 설정

데이터소스는 데이터베이스의 정보를 갖는 객체로 UNPOOLED, POOLED, JNDI type을 가

질 수 있다.

UNPOOLED : 데이터베이스 요청 시 매번 연결을 새롭게 생성

POOLED : 일정 수의 데이터베이스 연결 객체를 메모리에 넣고 사용

JNDI : 컨테이너의 JNDI 컨텍스트를 참조할 경우 사용

매퍼 정보 설정

매퍼를 지정하는 역할을 하며 resource, url, class 속성을 이용한 매퍼 위치 설정과

package 엘리먼트의 name 속성을 이용한 패키지 내 매퍼 검색을 할 수 있다.

Page 8: MyBatis Basic

8 - Internal Use Only -

MyBatis 설정 (3 / 3)

configuration 엘리먼트 내에 environments, mapper 외에 다음 엘리먼트들을

추가적으로 사용할 수 있다.

properties : configuration 내부에서 사용하는 각종 설정 값을 외부 파일에서 추출하도록

지원

settings : MyBatis 전반에 걸쳐 적용되는 성능과 관련된 옵션을 지정

typeAliases : 파리메타 타입이나 결과 매핑 타입에 별칭을 지정

typeHandlers : 컬럼 타입과 자바 타입별로 처리를 담당하는 타입 핸들러를 정의

objectFactory : 결과 데이터를 만들 때 처리과정을 담당하는 오브젝트 팩토리를 정의

plugins : Mybatis가 처리하는 시점별로 부가적인 작업을 처리할 수 있게 지원

Page 9: MyBatis Basic

9 - Internal Use Only -

Mapper (1 / 5)

MyBatis는 Mapper Interface와 Mapper XML을 이용해 매핑 구문과 결과 매핑 등을

정의할 수 있다.

매퍼 정의 방법에 따른 장단점

정의 방법 장점 단점

Mapper Interface

매핑 구문을 사용할 때 인터페이스의 메소드를 그대로 사용하기 때문에 매핑 구문을 잘못 적는 경우가 없고 타입 변환이 필요 없다.

애노테이션 특성상 동적 SQL을 작성하기 위해서는 별도 클래스를 사용해야 한다. 결과 매핑에 제약이 있다.

Mapper XML 매퍼의 모든 기능을 사용할 수 있다. iBatis를 사용하던 개발자는 거의 그대로 활용 가능하다.

매핑 구문의 아이디를 문자열 형태로 선언해야 하기 때문에 오타로 인한 버그의 가능성이 높다. 범용적인 API 특성상 타입 변환이 필요하고 타입 변환 오류 발생 가능성이 있다.

Mapper Interface + Mapper XML

매핑 구문을 사용할 때 인터페이스의 메소드를 그대로 사용하기 때문에 매핑 구문을 잘못 적는 경우가 없고, 타입 변환이 필요 없다. 매퍼의 모든 기능을 사용할 수 있다. iBatis를 사용하던 개발자는 거의 그대로 활용 가능하다.

인터페이스와 매퍼 XML을 모두 작성해야 하기 때문에 코드 작성에 시간이 좀더 소요된다.

Page 10: MyBatis Basic

10 - Internal Use Only -

Mapper (2 / 5)

Mapper Interface

패키지명과 인터페이스 이름을 합친 문자열이 네임스페이스가 된다.

조건에 따른 분기 처리를 위해 @SelectProvider, @InsertProvider, @UpdateProvider,

@DeleteProvider를 추가로 제공한다.

package com.osc.edu.commons.employees.mapper;

import org.apache.ibatis.annotations.Select;

public interface EmployeesMapper {

@Select({

"SELECT ",

"employee_id, lastname, firstname, extension, email, office_code, reports_to, job_title ",

"FROM EMPLOYEES ",

"WHERE employee_id = #{employeeId}"

})

public EmployeesDto getEmployees(Integer employeeId);

}

Page 11: MyBatis Basic

11 - Internal Use Only -

Mapper (3 / 5)

Mapper XML

iBatis에서 사용하는 방식과 거의 유사하며 파라메타는 #{} 와 같이 표기한다.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.osc.edu.commons.employees.mapper.EmployeesMapper“>

<select id="getEmployees" parameterType="Integer" resultType="com.osc.edu.commons.employees.dto.EmployeesDto">

SELECT employee_id AS employeeId

, lastname AS lastname

, firstname AS firstname

, extension AS extension

, email AS email

, office_code AS officeCode

, reports_to AS reportsTo

, job_title AS jobTitle

FROM EMPLOYEES

WHERE EMPLOYEE_ID = #{employeeId}

</select>

</mapper>

Page 12: MyBatis Basic

12 - Internal Use Only -

Mapper (4 / 5)

Mapper XML에서는 다음과 같은 엘리먼트를 사용할 수 있다.

cache : 해당 네임스페이스를 위한 캐시 설정

cache-ref : 다른 네임스페이스의 캐시 설정에 대한 참조

resultMap : 데이터베이스 결과데이터를 객체에 로드하는 방법을 정의

sql : 다른 구문에서 재사용하기 위한 SQL 조각

insert / update / delete / select : 데이터베이스에 입력, 수정, 삭제, 조회를 위한 SQL 구문

을 정의

selectKey : 데이터 입력 시 키 값을 자동 생성하기 위해 사용

Page 13: MyBatis Basic

13 - Internal Use Only -

Mapper (5 / 5)

Mapper Interface + Mapper XML

Mapper XML 파일을 유지한 채 Mapper Interface 코드에서 애노테이션으로 SQL을 정의하

지 않고 메소드만 선언하면 Mapper Interface를 통한 XML 매핑 구문을 호출할 수 있다.

package com.osc.edu.commons.employees.mapper;

public interface EmployeesMapper {

public EmployeesDto getEmployees(Integer employeeId);

}

public EmployeesDto getEmployees(Integer employeeId) {

EmployeesDto employee = null;

// execute query using Mapper Interface

employee = sqlSession.getMapper(EmployeesMapper.class).getEmployees(employeeId);

// execute query using Mapper XML

employee = sqlSession.selectOne("com.osc.edu.commons.employees.mapper.EmployeesMapper.getEmployees", emp

loyeeId);

return employee;

}

Page 14: MyBatis Basic

14 - Internal Use Only -

동적 SQL (1 / 7)

동적 SQL은 여러가지 분기 조건에 따라 동적으로 SQL을 생성하기 위해 사용한다.

MyBatis 에서는 동적 SQL을 위해 다음 4가지의 엘리먼트를 제공하며, JSTL과 같은

OGNL(Object Graph Navigation Language) 기반의 표현식을 사용한다.

if

choose (when, otherwise)

trim (where, set)

foreach

Page 15: MyBatis Basic

15 - Internal Use Only -

동적 SQL (2 / 7)

if

동적 SQL에서 가장 기본적으로 사용되는 분기 처리 방식이다.

hashmap에 title이 null이 아니면 title 검색 조건이 추가된다.

hashmap에 author가 null이 아니고 author.name이 null이 아니면 author.name 검색 조건

이 추가된다.

<select id="findActiveBlogLike" parameterType="hashmap" 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>

Page 16: MyBatis Basic

16 - Internal Use Only -

동적 SQL (3 / 7)

choose (when, otherwise)

if와 마찬가지로 분기 처리에 사용되며, 자바의 switch 구문과 유사한 기능을 제공한다.

hashmap에 title이 null이 아니면 title 조건만으로 검색된다.

hashmap에 author가 null이 아니고 author.name이 null이 아니면 author.name 조건만으로

검색된다.

title, author가 제공되지 않을 경우 featured가 1인 조건만으로 검색된다.

<select id="findActiveBlogLike" parameterType="hashmap" 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>

Page 17: MyBatis Basic

17 - Internal Use Only -

동적 SQL (4 / 7)

trim (where, set)

trim은 if 엘리먼트의 단점을 보완할 수 있는 기능을 제공한다.

어떠한 조건에도 해당되지 않을 경우

- SELECT * FROM BLOG WHERE;

첫 번째 조건은 해당되지 않고, 두 번째 또는 세 번째 조건만 해당될 경우

- SELECT * FROM BLOG WHERE AND title like ‘something’;

<select id="findActiveBlogLike" parameterType="hashmap" 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>

Page 18: MyBatis Basic

18 - Internal Use Only -

동적 SQL (5 / 7)

trim (where, set)

where 엘리먼트의 역할은 단순히 WHERE 구문을 붙이고 생략하는 역할 뿐 아니라 하위 엘

리먼트에서 생성한 내용이 AND나 OR로 시작할 경우 자동으로 이 단어들을 지워주며, 아래

trim 엘리먼트로 교체하여 사용할 수도 있다.

<select id="findActiveBlogLike" parameterType="hashmap" resultType="Blog">

SELECT * FROM BLOG WHERE

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

</where>

</select>

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

….

</trim>

Page 19: MyBatis Basic

19 - Internal Use Only -

동적 SQL (6 / 7)

trim (where, set)

SELECT 질의 시 where 엘리먼트와 마찬가지로 UPDATE 질의에 set 엘리먼트를 사용하면

SET 구문을 붙이거나 생략하고, 불필요한 쉼표(,)를 제거할 수 있고 trim 엘리먼트로 교체할

수도 있다.

Abcd가나다라

<update id="updateAuthorIfNecessary" parameterType="hashmap">

UPDATE AUTHOR

<set>

<if test="username != null">username = #{username},</if>

<if test="password != null">password = #{password},</if>

<if test="email != null">email = #{email}</if>

</set>

WHERE id = #{id}

</update>

<trim prefix="SET" suffixOverrides=",">

….

</trim>

Page 20: MyBatis Basic

20 - Internal Use Only -

동적 SQL (7 / 7)

foreach

SQL의 조회 조건에는 IN 절로 조건을 추가하는 경우가 있으며, foreach 엘리먼트를 이용해

collection에 대해 반복처리를 할 수 있도록 지원한다.

foreach 엘리먼트는 내부에서 사용할 수 있는 item, index 두 가지 변수를 선언하고, 열고

닫는 문자열로 명시할 수 있고 반복간에 둘 수 있는 구분자도 추가할 수 있다.

<select id="selectPostIn" parameterType="hashmap" resultType="domain.blog.Post">

SELECT * FROM POST

WHERE ID in

<foreach item="item" index="index" open="(" separator="," close=")">

#{item}

</ foreach >

</select>

Page 21: MyBatis Basic

21 - Internal Use Only -

SqlSession API (1 / 4)

SqlSession은 MyBatis를 사용하기 위한 기본적인 자바 인터페이스로써 이

인터페이스를 통해 명령어를 실행하고, 매퍼를 얻으며 트랜잭션을 관리할 수 있다.

반환 타입 메소드 시그니처 설명

int delete(String statement) 데이터를 삭제하는 매핑 구문을 호출한다.

int delete(String statement, Object parameter)

데이터를 삭제하는 매핑 구문을 호출한다. 삭제할 데이터를 한정하기 위해 파라메타를 사용해서 조건을 만든다.

int insert(String statement) 데이터를 입력하는 매핑 구문을 호출한다.

int insert(String statement, Object parameter)

데이터를 입력하는 매핑 구문을 호출한다. 파라메타에 설정한 값을 사용해서 데이터를 입력한다.

void select(String statement, Object parameter, ResultHandler handler)

데이터를 조회하는 매핑 구문을 호출한다. 파라메타를 사용해서 조회 조건을 만들 수 있고, 핸들러를 사용해서 조회 결과에 대해 처리를 추가할 수 있다.

Page 22: MyBatis Basic

22 - Internal Use Only -

SqlSession API (2 / 4)

반환 타입 메소드 시그니처 설명

void

select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)

데이터를 조회하는 매핑 구문을 호출한다. 파라메타를 사용해서 조회 조건을 만들 수 있고, 로우바운드를 사용해서 데이터 개수도 한정할 수 있다. 핸들러를 사용해서 조회 결과에 대해 처리를 추가할 수 있다.

void select(String statement, ResultHandler handler)

데이터를 조회하는 매핑 구문을 호출한다. 핸들러를 사용해서 조회 결과에 대해 처리를 추가할 수 있다.

List selectList(String statement) 데이터를 조회하는 매핑 구문을 호출해서 List 타입으로 반환한다.

List selectList(String statement, Object parameter)

데이터를 조회하는 매핑 구문을 호출해서 List 타입으로 반환한다. 파라메타를 사용해서 조회 조건을 만들 수 있다.

List selectList(String statement, Object parameter, RowBounds rowBounds)

데이터를 조회하는 매핑 구문을 호출해서 List 타입으로 반환한다. 파라메타를 사용해서 조회 조건을 만들 수 있고, 로우바운도를 사용해서 데이터 개수도 한정할 수 있다.

Page 23: MyBatis Basic

23 - Internal Use Only -

SqlSession API (3 / 4)

반환 타입 메소드 시그니처 설명

Map selectMap(String statement, Object parameter, String mapKey)

데이터를 조회하는 매핑 구문을 호출해서 Map 타입으로 반환한다. 파라메타를 사용해서 조회 조건을 만들 수 있고, mapKey 파라메타를 사용해서 Map의 키에 해당하는 프로퍼티를 정할 수 있다.

Map

selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)

데이터를 조회하는 매핑 구문을 호출해서 Map 타입으로 반환한다. 파라메타를 사용해서 조회 조건을 만들 수 있고, mapKey 파라메타를 사용해서 Map의 키에 해당하는 프로퍼티를 정할 수 있다. 로우바운드를 사용해서 데이터 개수도 한정할 수 있다.

Map selectMap(String statement, String mapKey)

데이터를 조회하는 매핑 구문을 호출해서 Map 타입으로 반환한다. mapKey 파라메타를 사용해서 Map의 키에 해당하는 프로퍼티를 정할 수 있다.

Object selectOne(String statement) 데이터를 조회하는 매핑 구문을 호출해서 객체로 반환한다. 조회 조건이 없고 데이터 개수가 2개 이상이면 예외를 발생시킨다.

Object selectOne(String statement, Object parameter)

데이터를 조회하는 매핑 구문을 호출해서 객체로 반환한다. 파라메타를 사용해서 조회 조건을 만들고, 데이터 개수가 2개 이상이면 예외를 발생시킨다.

Page 24: MyBatis Basic

24 - Internal Use Only -

SqlSession API (4 / 4)

반환 타입 메소드 시그니처 설명

int update(String statement) 데이터를 수정하는 매핑 구문을 호출한다.

int update(String statement, Object parameter)

데이터를 수정하는 매핑 구문을 호출한다. 파라메타에 설정한 값을 사용해서 데이터를 수정한다.

void commit(..) 트랜잭션을 커밋해서 직전까지 데이터를 입력하거나 수정, 삭제한 내용을 데이터베이스에 물리적으로 반영한다.

void rollback(..) 트랜잭션을 롤백해서 직전까지 데이터를 입력하거나 수정, 삭제한 내용을 데이터베이스에 물리적으로 반영하지 않고 무시한다.

void clearCache() 세션 레벨의 캐시를 지운다.

void close() 세션을 닫는다.

<T> T getMapper(Class<T> type) 매퍼를 얻어온다.

Page 25: MyBatis Basic

25 - Internal Use Only -

Transaction Management (1 / 6)

트랜잭션은 데이터베이스를 사용함에 있어 가장 중요한 개념이다. 데이터베이스에서

데이터를 조작하는 각종 작업을 처리할 때 메모리 영역에 그 작업들을 저장하고 특정

시점에 물리적으로 완전히 적용하거나 취소하게 되는데, 이때 작업 내용을

데이터베이스에 물리적으로 적용하는 것을 커밋이라 하고 취소하는 것을 롤백이라

한다.

MyBatis에서는 SqlSession을 이용하여 트랜잭션을 관리할 수 있으며, 다음과 같은

특징을 가진다.

SqlSessionFactory를 통해 SqlSession을 생성할 때마다 트랜잭션을 자동으로 시작한다.

SqlSession은 공유되지 않고 쓰레드에 안전하지 않기 때문에 각각의 쓰레드는 자체적으로

SqlSession 인스턴스를 가져야 한다.

자원 해제를 위해 반드시 close() 메소드를 호출해야 한다.

Spring과 연동해 Spring 연동 모듈을 사용하면 트랜잭션에 대한 제어는 MyBatis가

담당하지 않고 스프링에 위임한다.

Page 26: MyBatis Basic

26 - Internal Use Only -

Transaction Management (2 / 6)

public Integer insertEmployees(EmployeesDto employee) {

SqlSession sqlSession = SqlSessionFactoryManager.getSqlSession();

try {

int result = 0;

result = sqlSession.insert(“com.osc.edu.commons.employees.mapper.EmployeesMapper.insertEmployees”, employee);

if (result > 0) {

// Commit

sqlSession.commit();

} else {

// Rollback

sqlSession.rollback();

}

return result;

} finally {

sqlSession.close();

}

}

SqlSession을 이용한 트랜잭션 관리

Page 27: MyBatis Basic

27 - Internal Use Only -

Transaction Management (3 / 6)

Spring 연동 모듈을 이용한 트랜잭션 관리

Spring 트랜잭션 관리자를 한번 설정하면, 대개의 경우처럼 Spring에서 트랜잭션을 설정할

수 있다.

@Transactional 애노테이션과 AOP스타일의 설정 모두 지원한다.

하나의 SqlSession객체가 생성되면 트랜잭션이 동작하는 동안 지속적으로 사용되며, 세션

은 트랜잭션이 완료되면 오류 여부에 따라 커밋 되거나 롤백 될 것이다.

DAO 클래스에 어떠한 추가적인 코드를 넣을 필요가 없다.

Spring 연동을 위한 Context 설정(application-context.xml)

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

Page 28: MyBatis Basic

28 - Internal Use Only -

Transaction Management (4 / 6)

<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">

<property name="driverClass" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>

<property name="username" value=“mybatis"/>

<property name="password" value=“mybatis"/>

</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

<tx:advice id="txAdvice">

<tx:attributes>

<tx:method name="insert*" rollback-for="Throwable" propagation="REQUIRED"/>

<tx:method name="update*" rollback-for="Throwable" propagation="REQUIRED"/>

<tx:method name="delete*" rollback-for="Throwable" propagation="REQUIRED"/>

<tx:method name="get*" read-only="true"/>

<tx:method name="*" rollback-for="Throwable"/>

</tx:attributes>

</tx:advice>

Page 29: MyBatis Basic

29 - Internal Use Only -

Transaction Management (5 / 6)

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />

<property name="mapperLocations">

<list>

<value>com/osc/edu/**/*Mapper.xsql</value>

</list>

</property>

</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<property name="basePackage" value="com.osc.edu" />

<property name="annotationClass" value="com.osc.edu.commons.annotation.SqlMapper" />

</bean>

<bean class="org.mybatis.spring.SqlSessionTemplate">

<constructor-arg ref="sqlSessionFactory" />

</bean>

Page 30: MyBatis Basic

30 - Internal Use Only -

Transaction Management (6 / 6)

<!-- AOP를 이용한 트랜잭션 설정 -->

<tx:advice id="txAdvice">

<tx:attributes>

<tx:method name="insert*" rollback-for="Throwable" propagation="REQUIRED"/>

<tx:method name="update*" rollback-for="Throwable" propagation="REQUIRED"/>

<tx:method name="delete*" rollback-for="Throwable" propagation="REQUIRED"/>

<tx:method name="get*" read-only="true"/>

<tx:method name="*" rollback-for="Throwable"/>

</tx:attributes>

</tx:advice>

<aop:aspectj-autoproxy />

<aop:config proxy-target-class="true">

<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))"/>

</aop:config>

<!-- 애노테이션을 이용한 트랜잭션 설정 -->

<context:annotation-config />

<tx:annotation-driven proxy-target-class="true"/>

</beans>

Page 31: MyBatis Basic

31 - Internal Use Only -

Java Standalone Application (1 / 5)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<environments default="development">

<environment id="development">

<transactionManager type="JDBC" />

<dataSource type="POOLED">

<property name="driver" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>

<property name="username" value=“mybatis"/>

<property name="password" value=“mybatis"/>

</dataSource>

</environment>

</environments>

<mappers>

<mapper resource="com/osc/edu/commons/customers/sql/CustomersMapper.xml” />

</mappers>

</configuration>

mybatis-config.xml

Page 32: MyBatis Basic

32 - Internal Use Only -

Java Standalone Application (2 / 5)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.osc.edu.commons.customers.mapper.CustomersMapper">

<select id="getCustomersList" resultType="com.osc.edu.commons.customers.dto.CustomersDto">

SELECT CUSTOMER_ID AS customerId

, CUSTOMER_NAME AS customerName

….

FROM CUSTOMERS

</select>

<select id="getCustomers" parameterType="Integer" resultType="com.osc.edu.commons.customers.dto.CustomersDto">

SELECT CUSTOMER_ID AS customerId

, CUSTOMER_NAME AS customerName

….

FROM CUSTOMERS

WHERE CUSTOMER_ID = #{customerId}

</select>

….

</mapper>

CustomersMapper.xml

Page 33: MyBatis Basic

33 - Internal Use Only -

Java Standalone Application (3 / 5)

package com.osc.edu.commons.customers.mapper;

import java.util.List;

import com.osc.edu.commons.annotation.SqlMapper;

import com.osc.edu.commons.customers.dto.CustomersDto;

@SqlMapper

public interface CustomersMapper {

public List<CustomersDto> getCustomersList();

public CustomersDto getCustomers(Integer id);

public void insertCustomers(CustomersDto customers);

public void updateCustomers(CustomersDto customers);

public void deleteCustomers(Integer id);

}

CustomersMapper.java

Page 34: MyBatis Basic

34 - Internal Use Only -

Java Standalone Application (4 / 5)

public class SqlSessionFactoryManager {

private static final SqlSessionFactory sqlSessionFactory;

static {

String resource = "mybatis-config.xml";

Reader reader = null;

try {

reader = Resources.getResourceAsReader(resource);

} catch (IOException e) {

e.printStackTrace();

}

sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

}

public static SqlSessionFactory getSqlSessionFactory() {

return sqlSessionFactory;

}

}

SqlSessionFactoryManager.java

Page 35: MyBatis Basic

35 - Internal Use Only -

Java Standalone Application (5 / 5)

public class Starter {

public static void main(String[] args) {

// SqlSessionFactoryManager로부터 mybatis-config.xml 파일을 로딩하여 생성된 SqlSessionFactory를 가져온다.

SqlSession sqlSession = SqlSessionFactoryManager.getSqlSessionFactory().getSqlSession();

try {

// Mapper 인터페이스를 이용한 쿼리 실행

CustomersMapper customersMapper = sqlSession.getMapper(CustomersMapper.class);

List<CustomersDto> customersList = customersMapper.getCustomersList();

System.out.println ("customersList.size() => " + customersList.size());

// (xml) mapper 파일의 namespace, id를 이용한 쿼리 실행

customersList = sqlSession.selectList("com.osc.edu.commons.customers.mapper.CustomersMapper.getCustomersList");

System.out.println("customersList.size() => " + customersList.size());

} finally {

sqlSession.close();

}

}

}

Starter.java

Page 36: MyBatis Basic

36 - Internal Use Only -

Spring (Web) Application (1 / 6)

MyBatis에서 Spring과 연동하기 위해 별도의 모듈이 추가적으로 필요하다.

https://github.com/mybatis/spring/releases 에서 mybatis-spring-x.x.x.zip 파일을

다운로드 하고 압축을 해제한다.

일반 Spring 애플리케이션일 경우 mybatis-spring-x.x.x.jar 파일을 클래스패스에 추가한다.

Web 애플리케이션일 경우 WEB-INF/lib 아래에 mybatis-spring-x.x.x.jar 파일을 추가한다.

Maven을 사용할 경우에는 pom.xml에 다음과 같이 Spring 연동 모듈에 대한

Dependency만 추가하면 된다.

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis-spring</artifactId>

<version>x.x.x</version>

</dependency>

Page 37: MyBatis Basic

37 - Internal Use Only -

Spring (Web) Application (2 / 6)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<settings>

<setting name="cacheEnabled" value="false" />

<setting name="useGeneratedKeys" value="true" />

<setting name="defaultExecutorType" value="REUSE" />

<setting name="defaultStatementTimeout" value="120" />

</settings>

</configuration>

mybatis-config.xml

environments, mapper 엘리먼트 등에서 설정하던 데이터베이스, 매퍼 등에 대한 설정을

Spring 연동 모듈을 통해서 Spring 설정 파일에서 설정할 수 있다.

Page 38: MyBatis Basic

38 - Internal Use Only -

Spring (Web) Application (3 / 6)

@Repository

public class CustomersDao {

private @Autowired CustomersMapper mapper;

private @Autowired SqlSession sqlSession;

public List<CustomersDto> getCustomersList() {

return sqlSession.selectList("com.osc.edu.commons.customers.mapper.CustomersMapper.getCustomersList");

// return mapper.getCustomersList();

}

….

}

application-context.xml

본 문서 27 페이지의 application-context.xml 내용과 동일하다.

Spring MVC를 이용한 Web 애플리케이션일 경우 서블릿 관련 추가 설정이 필요하다.

CustomersDao.java

Page 39: MyBatis Basic

39 - Internal Use Only -

Spring (Web) Application (4 / 6)

@Service

public class CustomersService {

@Autowired

private CustomersDao customersDao;

public List<CustomersDto> getCustomersList() {

return customersDao.getCustomersList();

}

….

}

CustomersService.java

Page 40: MyBatis Basic

40 - Internal Use Only -

Spring (Web) Application (5 / 6)

public class Starter {

public static void main(String[] args) {

AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml" });

CustomersService customersService = applicationContext.getBean(CustomersService.class);

List<CustomersDto> customersList = customersService.getCustomersList();

for (CustomersDto customers : customersList) {

Systeom.out.println(customers);

}

applicationContext.close();

}

}

Starter.java

Page 41: MyBatis Basic

41 - Internal Use Only -

Spring (Web) Application (6 / 6)

@Controller

@RequestMapping("/customers")

public class CustomersController {

@Autowired

private CustomersService customersService;

@RequestMapping("/getCustomersList")

public ModelAndView getCustomersList(HttpServletRequest request, HttpServletResponse response) {

ModelAndView mav = new ModelAndView("customers/list");

mav.addObject("customersList", customersService.getCustomersList());

return mav;

}

….

}

CustomersController.java

Page 42: MyBatis Basic

42 - Internal Use Only -

OPEN

SHARE

CONTRIBUTE

ADOPT

REUSE