스프링 프레임워크(Spring Framework) MyBatis와 MySQL의 설정
스프링 프레임워크와 MyBatis 연동 및 MySQL의 설정에 대해 알아보겠습니다.
MyBatis는 Java Persistence Framework의 한 종류로 XML 또는 애너테이션을 통해 SQL문 또는 저장 프로시저로 객체들을 매핑해줍니다. MyBatis는 스프링을 이용한 개발 중 국내에서 가장 많이 쓰이는 형태로 SQL 처리에 대한 개발 생산성을 높이는 형태로 사용됩니다.
※ 퍼시스턴스 프레임워크(Persistence Framework)
데이터의 저장, 조회, 변경, 삭제를 다루는 클래스 및 설정 파일들의 집합입니다. JDBC의 복잡함이나 번거로움 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있으며, 안정적인 구동도 보장됩니다. 퍼시스턴스 프레임워크의 종류로는 SQL문으로 직접 데이터베이스의 데이터를 다루는 SQL Mapper 방식의 MyBatis와 자바 객체를 통해 간접적으로 데이터를 다루는 객체 관계 매퍼(Object-Relational Mapper) 방식의 Hibernate 등이 있습니다.
1. 일반적인 스프링 웹 프로젝트의 구성
일반적으로 웹 프로젝트는 다음과 같이 3개의 레이어(또는 tier)로 구성됩니다.
- 표현 계층 (Presentation Layer)
UI를 담당하는 구성 요소들이 포함됩니다. 웹 또는 모바일 여부에 따라 사용되는 기술이 변경됩니다.
JSP와 같은 뷰(View)를 구성하는 부분과 Controller 부분으로 분리되어 작성됩니다. - 비즈니스 계층 (Business Layer)
서비스 계층이라고도 하며, 고객의 요구사항을 반영하는 계층입니다. 기능적인 요구사항을 구현한 계층이며 어떠한 형태의 데이터가 필요하고 반환될 것인지 결정합니다. - 데이터 관리 계층 (Data Access Layer)
흔히 Persistence Layer 라고도 하는데, 데이터 처리를 주로 담당합니다.
MyBatis가 추가되는 부분입니다. DAO(Data Access Object)의 경우 MyBatis를 호출하고 사용하는 구조로 구성됩니다.
2. MyBatis의 연동
먼저 스프링은 다양한 프레임워크와의 융합이 가능하다는 큰 장점을 가지고 있습니다. 다양한 프레임워크를 융합하여 사용하면 기존 환경을 그대로 흡수하여 사용할 수 있게 됩니다.
다음은 MyBatis를 사용했을 때 이용할 수 있는 특징입니다.
- 간결한 코드의 처리
MyBatis는 SQL Mapper 라이브러리입니다. 일반적으로 JDBC를 사용하여 개발하게되면 많은 코드를 반복하여 사용하게 되는데 MyBatis는 이러한 코드를 상당히 많이 줄여줄 수 있기 때문에 개발 생산성 향상에 크게 기여해줍니다. MyBatis를 사용하면 추가적인 코드 작성 없이도 JDBC의 처리가 가능하게 됩니다. - SQL문의 분리 운영
JDBC 방식은 개발자가 SQL문을 처리하기 위해서 별도의 파일을 작성하는 등의 번거로운 작업을 필요로 합니다. 반면에 MyBatis의 경우는 XML 또는 애노테이션을 사용하여 별도로 처리하는 작업이 가능하고 필요한 경우 두 가지 방식을 혼합해서 사용하는 것도 가능합니다. - Spring과의 연동으로 자동화된 처리
Spring과 연계된 MyBatis-Spring 라이브러리를 사용하면 개발자는 직접적인 SQL문의 호출없이도 원하는 결과를 얻을 수 있습니다. 이 때문에 MyBatis를 단독으로 사용하는 것보다는 스프링과 연계하여 사용하는 것이 코드를 간결하게 해주고 자동화된 처리를 가능하게 해줍니다. - 동적 SQL을 이용한 제어
MyBatis는 내부적으로 제어문이나 루프 등의 처리 기능을 갖고 있습니다. 이를 통해서 SQL문의 결과와 관련된 처리를 Java 코드에서 분리하여 작성할 수 있습니다.
2.1 MyBatis, spring-jdbc, spring-test, mybatis-spring 라이브러리 추가
MyBatis 사용을 위한 관련 라이브러리를 추가하기 위해서 pom.xml 파일에 필요한 라이브러리를 설정해주고 스프링의 설정 파일을 수정해줘야 합니다.
pom.xml에 다음과 같이 라이브러리를 추가해줍니다.
* mybatis 라이브러리
1 2 3 4 5 | <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> |
1 2 3 4 5 | <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> | cs |
1 2 3 4 5 | <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework-version}</version> </dependency> | cs |
* spring-test 라이브러리
1 2 3 4 5 | <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${org.springframework-version}</version> </dependency> | cs |
spring-test 라이브러리는 MyBatis가 정상적으로 연동되었는지 확인하는 용도로 사용합니다. 또한 WAS의 구동 없이 정상적으로 동작하는지 확인하는 용도로 사용합니다.
2.2 Spring Project에서 root-context.xml 파일 수정
스프링 프로젝트 내의 src/main/webapp/WEB-INF/spring/root-context.xml 파일은 스프링에 대한 설정을 할 때 웹 자원과 관련되지 않은 나머지 모든 자원의 설정을 해주는 파일입니다. (웹과 관련된 설정은 src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml 파일에서 해줍니다.)
root-context.xml 파일에서 스프링에 대한 다양한 설정을 하기 위해서는 Namespaces 설정을 사용하여 사용 가능한 XML의 폭을 넓혀줘야 합니다. 네임스페이스는 XML 문서 내에서 어떤 태그나 속성을 사용할 수 있는지 명시해주는 역할을 합니다.
이클립스를 사용하는 경우 아래와 같이 하단 Namespaces 탭을 클릭하여 필요한 설정을 추가해줄 수 있습니다.
네임스페이스를 추가하면 다음과 같이 선택한 XML 네임스페이스가 추가된 것을 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd 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-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- Root Context: defines shared resources visible to all other web components --> </beans> | cs |
2.3 MySQL과의 연결을 담당하는 DataSource 설정하기
스프링의 설정으로 JDBC 연결을 처리하기 위해 spring-jdbc 모듈의 클래스를 사용하여 root-context.xml에 다음과 같이 DataSource 태그를 추가해줍니다.
1 2 3 4 5 6 | <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/springdb?useSSL=false"></property> <property name="username" value="bybit"></property> <property name="password" value="bybit"></property> </bean> | cs |
설정에 사용된 <bean> 태그의 class 속성의 값을 보면 org.springframework.jdbc 경로로 시작하는 것을 확인할 수 있는데, 실제로 spring-jdbc 라이브러리를 받아 압축을 풀어 확인해보면 클래스 파일의 패키지 경로가 위와 같이 설정되어있는 것을 확인할 수 있습니다.
<bean> 태그의 id 속성은 스프링 내에서 특정한 객체를 찾기위해 설정한 alias 값입니다. 일반적으로 변경없이 그대로 사용하는 것이 에러 발생 가능성을 줄여줍니다.
2.4 DataSource 테스트 진행
테스트를 위해 src/test/java 경로 하위에 다음과 같이 클래스를 작성하여 생성해줍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | package com.myproject.myapp; import java.sql.Connection; import javax.inject.Inject; import javax.sql.DataSource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /* * DataSourceTest * @Test */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration( locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"} ) public class DataSourceTest { @Inject private DataSource dataSource; @Test public void testConnection() throws Exception { try(Connection conn1 = dataSource.getConnection(); Connection conn2 = dataSource.getConnection();) { System.out.println("===== mysql datasource connection test start ====="); System.out.println(conn1); System.out.println(conn2); System.out.println("===== mysql datasource connection test end ====="); } catch(Exception e) { e.printStackTrace(); } } } | cs |
사용한 애노테이션에 대한 설명은 다음과 같습니다.
- @RunWith
스프링의 test context framework인 jUnit의 확장기능을 설정해주며 스프링 버전별로 상속받는 클래스에 차이가 있습니다.
jUnit에 내장된 기본 테스트 러너인 BlockJUnit4ClassRunner 대신에 @RunWith에 지정된 클래스를 이용하여 클래스 내의 테스트 메서드들을 실행하도록 해줍니다. - @ContextConfiguration
테스트 컨텍스트가 자동으로 만들어줄 application context의 위치를 지정해줍니다.
스프링 bean 메타 설정 파일의 위치를 지정할 때 사용합니다. - @Inject
스프링에서 의존 관계를 가진 객체를 자동으로 생성하여 주입해주는 역할로 사용됩니다.
Java에서 기존에 지원하는 애노테이션입니다. (스프링 한정으로 의존성 주입 애노테이션은 @Autowired와 @Qualifier를 별도로 제공)
위의 코드를 jUnit Test 로 실행하면 아래와 같이 console에 Connection 객체가 생성되어 출력되는 것을 확인할 수 있습니다.
3. MyBatis와 MySQL의 연결
root-context.xml에 DataSource를 설정하여 확인한 이후엔 MyBatis와 MySQL의 연결을 진행해줍니다.
3.1 SqlSessionFactory 객체 설정
MyBatis와 스프링 연동에서의 핵심은 데이터베이스의 Connection을 생성하고 처리하는 SqlSessionFactory의 존재입니다. SqlSessionFactory 객체는 데이터베이스와 연결과 SQL문의 실행에 대한 모든 것을 관리하는 중요한 객체입니다.
root-context.xml 파일에 다음과 같이 SqlSessionFactoryBean을 등록해줍니다.
1 2 3 | <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> </bean> | cs |
3.2 mybatis-config.xml 파일 추가
MyBatis는 SQL Mapping 프레임워크로서 별도의 설정파일을 가질 수 있습니다. 이를 이용하여 스프링의 설정과는 별도로 사용되는 모든 MyBatis의 설정 기능을 활용할 수 있습니다.
src/main/resources 하위 경로에 mybatis-config.xml 파일을 다음과 같이 작성하여 생성해줍니다. 생성한 파일을 편리하게 사용하기 위해서는 XML 파일의 DTD(Document Type Definition)나 XML 스키마를 적용하여 마크업 문서의 형식을 지정해줘야 하는데, <!DOCTYPE> 태그 내에 정의해줍니다.
1 2 3 4 5 6 7 | <?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> </configuration> |
다음으로 생성한 파일이 스프링과 함께 동작하도록 root-context.xml의 SqlSessionFactoryBean 태그에 configLocaction <property> 태그를 추가하여 아래와 같이 수정해줍니다.
1 2 3 4 | <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:/mybatis-config.xml"></property> </bean> | cs |
3.2 MyBatis 연결 테스트
모든 설정이 완료되었다면 스프링에서 정상적으로 MyBatis와 MySQL이 제대로 연결되었는지 테스트를 해줍니다.
src/test/java 경로 하위에 다음과 같이 클래스를 작성하여 생성해줍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package com.myproject.myapp; import javax.inject.Inject; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /* * MyBatisTest * @Test */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration( locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"} ) public class MyBatisTest { @Inject private SqlSessionFactory sqlFactory; @Test public void testFactory() { System.out.println("===== sql session factory check start ====="); System.out.println(sqlFactory); System.out.println("===== sql session factory check end ====="); } @Test public void testSession() throws Exception { try(SqlSession session1 = sqlFactory.openSession(); SqlSession session2 = sqlFactory.openSession();) { System.out.println("===== mybatis sql session test start ====="); System.out.println(session1); System.out.println(session2); System.out.println("===== mybatis sql session test end ====="); } catch(Exception e) { e.printStackTrace(); } } } | cs |
@Inject 애노테이션으로 적용한 sqlFactory는 스프링이 정상적으로 동작할 경우 SqlSessionFactory 객체를 생성하여 주입해주는 역할을 수행합니다.
위의 코드를 jUnit Test 로 실행하면 아래와 같이 console에 sqlSessionFactory의 sqlSession 객체가 생성되어 출력되는 것을 확인할 수 있습니다.
이상으로 스프링의 MyBatis와 MySQL의 설정에 대해서 알아봤습니다.
※ 참고 문헌
구멍가게 코딩단, 『코드로 배우는 스프링 웹 프로젝트』, 남가람북스(2015), p77 ~ p96. Chapter 1-4. 스프링 + MyBatis + MySQL의 설정
ko.wikipedia.org, 마이바티스, https://ko.wikipedia.org/wiki/%EB%A7%88%EC%9D%B4%EB%B0%94%ED%8B%B0%EC%8A%A4
ko.wikipedia.org, 퍼시스턴스 프레임워크, https://ko.wikipedia.org/wiki/%ED%8D%BC%EC%8B%9C%EC%8A%A4%ED%84%B4%EC%8A%A4_%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC
hodong.appspot.com, 스프링 애노테이션 정리, http://hodong0828.appspot.com/%EC%8A%A4%ED%94%84%EB%A7%81_%EC%95%A0%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98_%EC%A0%95%EB%A6%AC
blog.naver.com/platinasnow, [Spring] @Autowired, @Resource, @Inject의 차이, https://blog.naver.com/platinasnow/220053030295