MyBatis를 사용하기 위한 라이브러리
MyBatis와 Mysql db를 연동하기 위해 먼저 pom.xml에 필요한 라이브러리들을 넣어준다.
<!-- DB 프로그래밍을 위해 필요한 Library
1.jdbc class: spring-jdbc
org.springframework.jdbc.core.JdbcTemplate
2.data source: commons-dbcp
org.apache.commons.dbcp.BasicDataSource
3.jdbc driver: mysql-connector-java
com.mysql.jdbc.Driver
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<!-- 마이바티스 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 마이바티스 스프링-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
MyBatis의 사용
MyBatis의 핵심 API는 SqlSession(Mybatis가 제공하는 인터페이스) 이다. SqlSession오브젝트는 SQL문을 외부 파일에서 읽어 들여서 발행하고, 도메인과 레코드의 변환을 담당해준다. 매핑 파일이란 SQL과 변환을 위한 매핑 정보를 기술한 파일을 말한다. 또한 SqlSession오브젝트는 SqlSessionFactory(MyBatis가 제공하는 API, SqlSession의 펙토리)에서 취득할 수 있다.
스프링의 Bean으로서 SqlSessionFactory를 관리하므로 리소스 관련 제어, 예를들어, SqlSession 오브젝트의 생성과 파기 및 트랜젝션 제어는 스프링에게 일임되기 때문에, 별도의 코드를 쓰지 않아도 된다.
개발자는 단순히 스프링이 제공하는 SqlSession 오브젝트를 DAO 등의 Bean에 인젝션해 사용하면 된다.
또한, MyBatis는 DAO의 구현을 자동으로 생성해주는 Mapper 라는 기능을 제공한다. Mapper를 사용할 경우에는 개발자가 Mapper용 인터페이스(DAO인터페이스와 같음)를 준비해서 Mapper 오브젝트를 생성하도록 Bean 정의를 추가한 다음, 서비스 등에 인젝션해 사용한다.
예제소개
PetDao는 DAO인터페이스이고, MyBatisPetDao는 DAO의 구현 클래스이다. 또한, Pet은 도메인 클래스로서, SQL의 결과 취득이나 파라미터로써 Pet 오브젝트를 사용한다. 발행할 Sql문이나 Pet 클래스와 PET 테이블 간의 매핑 정보는 pet.xml에 기재돼 있다.
pet.xml
<?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="sample.mybatis.business.service.PetDao">
<select id="findById" parameterType="int" resultType="sample.mybatis.business.domain.Pet">
SELECT * FROM PET WHERE PET_ID = #{id}
</select>
<select id="findAll" resultType="sample.mybatis.business.domain.Pet">
SELECT * FROM PET
</select>
<!-- <resultMap id="petResultMap" type="sample.entity.Pet"> -->
<!-- <id property="petId" column="PET_ID" /> -->
<!-- <result property="petName" column="PET_NAME" /> -->
<!-- <result property="price" column="PRICE" /> -->
<!-- <result property="birthDate" column="BIRTH_DATE" /> -->
<!-- </resultMap> -->
</mapper>
한가지 중요한 점은 어노테이션에는 발행할 SQL문을 특정 해줄필요가 있다. 이때 사용할 정보로는 mapper 태그의 namespace 속성과 select 태그의 id 속성이 있다. 이 두가지 속성값을 연결한 것이 SQL 문의 식별자가 된다.
DAO 인터페이스와 Mapper가 연결돼 DAO의 구현이 자동 생성됐다. 덧붙이면 DAO 인터페이스와 Mapper를 연계시키기 위해 인터페이스를 사용한다든지, 어노테이션을 추가하는 식의 설정은 필요하지 않다. 패키지명, 인터페이스명, 메서드명의 정보를 pet.xml에 기술한 SQL식별자 (mapper 태그의 namespace 속성과 select 태그의 id 속성을 연결한 것)에 연결하면 된다.
SqlSessionFactory의 Bean 설정
Mapper의 사용 여부와 관계없이, SqlSessionFactory의 Bean 정의는 필요하다.
SqlSessionFactory의 Bean 설정 파일
<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring.xsd
">
<!-- 1번 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="sample/config/mybatis-config.xml"/>
<property name="mapperLocations">
<list>
<!-- <value>sample/mybatis/dataaccess/pet.xml</value> -->
<value>classpath*:sample/mybatis/dataaccess/**/*.xml</value>
</list>
</property>
</bean>
<bean id="petDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="sample.mybatis.business.service.PetDao" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<mybatis:scan base-package="sample.mybatis.business.service"/>
<!-- 2번 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="script/table.sql" />
<jdbc:script location="script/data.sql" />
</jdbc:embedded-database>
</beans>
1번의 Bean에는 SqlSessionFactoryBean이 설정되었다. SqlSessionFactoryBean은 SqlSessionFactory를 쉽게 설정하기 위한 FactoryBean이다. 프로퍼티 지정에서는 데이터 소스로 시작해, Mybatis 설정 파일의 경로
<property name="configLocation" value="sample/config/mybatis-config.xml"/>
와 매핑 파일의 경로 (아래)
<value>sample/mybatis/dataaccess/pet.xml</value>
가 지정됐다. 매핑 파일이 여럿일 경우, value 태그를 추가해서 하나하나 지정할 수 있지만, 귀찮다면 와일드 카드를 사용해서 다음과 같이 기술 할 수 있다.
<value>classpath*:sample/mybatis/dataaccess/**/*.xml</value>
와일드 카드를 사용하면 sample/mybatis/dataaccess 이하의, 확장자가 xml인 파일을 모두 읽어 들일 수 있다. classpath 가 아닌 classpath*라고 기술하는 이유는 복수의 파일을 읽어 들일 때 필요한 설정이기 때문이다.
또한 2번에는 트랜잭션 매니저의 Bean 정의를 설정하고 있다. 클래스에는 DataSourceTransactionManager 를 지정하고 데이터 소스를 인젝션 해준다.
마이바티스 설정 파일
<?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="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
아파치가 제공하는 데이터 소스
위에서는 sqlSessionFactory가 참조하는 데이터 소스를 HSQL로 지정해줬는데 BasicDataSource 클래스인 아파치의 데이터 소스를 사용해도 된다.
<!--
Data Source 설정
mysql 8.0 부터는 url 에 ?serverTimezone=UTC 넣어야함.
driverClassName 은 com.mysql.cj.jdbc.Driver
서드파티가 제공하는 데이터 소스 - Apache Commons DBCP
-->
<bean id="dataSourceSpied" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/MYDB?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true"/>
<property name="username" value="root" />
<property name="password" value="11@" />
</bean>
<!-- 초기화
<jdbc:initialize-database data-source="dataSource" ignore-failures = "DROPS">
<jdbc:script location="classpath:/META-INF/script/table.sql" />
<jdbc:script location="classpath:/META-INF/script/data.sql" />
</jdbc:initialize-database> -->
<!-- 트랜잭션 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
DAO의 구현
Mapper를 사용하는 경우
Mapper를 사용하는 경우에는 Mapper 오브젝트를 Bean으로 정의해야 할 필요가 있다. Mapper의 구현은 MyBatis가 자동 생성하기 때문에, 엄밀히 말하면, Mapper를 자동생성하는 FactoryBean을 Bean으로 정의해주는 것이 된다.
자동 생성의 대상이 되는 DAO의 인터페이스를 아래에서 확인 할 수 있다.
DAO의 인터페이스
package sample.mybatis.business.service;
import java.util.List;
import sample.mybatis.business.domain.Pet;
public interface PetDao {
Pet findById(int petId);
List<Pet> findAll();
}
얼핏 보면 특징 없는 인터페이스로 보이지만, 패키지명, 인터페이스명, 메서드명은 pet.xml에 기재해 두었던, SQL식별자 (mapper 태그의 namespace 속성과 select 태그의 id 속성을 연결한것)와 연결됐음을 알 수 있다. 다음으로 Mapper를 생성하는 FactoryBean의 Bean정의를 아래에서 확인 할 수 있다.
<bean id="petDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="sample.mybatis.business.service.PetDao" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<mybatis:scan base-package="sample.mybatis.business.service"/>
클래스 속성에는 MapperFactoryBean을 지정해 준다. 프로퍼티 속성에는 Mapper에 연결해줄 인터페이스 (petDao)를 설정한 다음, SqlSessionFactory 오브젝트를 인젝션하고 있다. 또한 Mapper 오브젝트를 하나씩 Bean으로 정의하는 것이 싫다면 다음과 같이 한꺼번에 정의 할 수 있다.
<mybatis:scan base-package="sample.mybatis.business.service"/>
sample.mybatis.business.service 이하의 인터페이스에 대해 Mapper 오브젝트가 생성돼 Bean으로 관리된다. 또 위의 태그는 mybatis 스키마를 사용하므로 이 스키마를 사용하기 위한 bean 태그의 설정 예는 아래와 같다.
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring.xsd
">
범용 데이터 액세스 예외의 사용
Mybatis의 처리 중 내부에서 예외가 발생하면 자동으로 범용 데이터 액세스 예외로 변환된다.
딱히 범용 데이터 액세스 예외를 사용하기 위한 설정은 필요하지 않는다.
예제파일
참고할만한 포스팅 : 스프링, Mybatis, MySQL_연동
스프링과 JDBC를 사용하여 데이터베이스 사용하기(깃북)
Java Data Access Layer의 이해 및 Spring JDBC를 이용한 데이터 접근 방법
참고: 스프링 4입문 (한빛미디어)
'웹개발 > 스프링' 카테고리의 다른 글
스프링 개발전 Controller Class파일 작성하기 - part2 (0) | 2020.11.14 |
---|---|
스프링 개발전 설정파일 작성하기 - part1 (0) | 2020.11.14 |
스프링 4 MVC - part 3 (0) | 2020.11.11 |
스프링 4 MVC - part 2 (0) | 2020.11.11 |
스프링 4 MVC - part 1 (0) | 2020.11.10 |