본문 바로가기
[ Developer ]/Spring Framework

[Spring] 스프링 ORM 마이바티스 MyBatis

by 김현섭. 2016. 6. 12.
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
ORM : MyBatis
  • ORM (Object Relation Mapping) 
  • Object와 DB를 연동하기 위함
  • MyBatis를 위해서 VO를 테이블 구조와 같이 만듬
  • Mapping이란 CRUD를 뜻함

# 기존의 JDBC와의 차이점
  • VO에 필드명을 적으면 그거에 맞는 데이터가 Mapping이 된다
  • ResultSet을 통한 getInt 등을 할 필요가 없다

# ORM의 종류
  • MyBatis
  • iBatis
  • JPA
  • Hibernate
  • MyBatis와 iBatis 사용 빈도가 높음

# MyBatis 연동
  • Spring 4에서는 MyBatis/iBatis 연동 기능 포함되지 않음
  • 대신 MyBatis가 Spring 연동 지원
  • iBatis는 지원하지 않는다


우선 pom.xml에서 추가를 한다 Build와 Dependencies 사이에 공백을 줘서 repositories를 추가해준다
JDBC를 추가해주기 위함이다


그런 후 dependencies 탭에가서 추가를 해준다
아래의 모든 것들을 검색 후 추가해주면 된다



그리고 난 후 applicationContext.xml이 있는 폴더 spring 폴더 내에 rootContext.xml 생성해준다
생성 시 next 눌러서 다음과 같이 선택을 해준다


그리고 rootContext.xml에서 Source를 작성해준다
첫 번째로 dataSource를 작성한다 Connection을 생성해주는 것이다


그리고 그 안에 property로 URL이나 Driver, 계정을 잡아준다


그리고 sqlSessionFactory를 생성한다


추가적으로 sqlSessionTemplate도 추가한다


아래와 같이 두개다 모두 작성하면 된다


sqlSessionFactory는 MyBatis가 사용할 Database에 연결하도록 설정하는 것이고
sqlSessionTemplate는 MyBatis의 CRUD 템플릿을 사용할 수 있도록 설정하는 것이다

이제는 Transaction 설정을 한다
우선 TransactionManager를 설정한다


하나의 트랜잭션으로 묶어서 완료되면 커밋하고 에러나면 롤백하는 역할을 한다

다음은 Transaction의 대상을 설정한다


그 안에 attributes로 메소드를 추가하는데 CRUD의 메소드를 모두 추가하면 된다


우선 Insert의 의미를 가지는 메소드를 추가해주면 된다
insert를 실행 시킬 수 있는 메소드들을 정의하여 넣어주면 된다


이후에는 Update와 Delete 메소드를 추가해준다


Read Only


이제는 AOP:Config를 세팅한다


advice-ref에는 이전에 설정한 tx:advice ID이며 pointcut-ref는 바로 위에서 생성한 pointcut ID 이다

이로써 JDBC와 Transaction 설정이 끝났다

# rootContext.xml
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
    
    <!-- Connection Tool -->
    <bean id="dataSource"
            class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" /> 
        <property name="username" value="HR" />
        <property name="password" value="hr" />
    </bean>
    
    <bean id="sqlSessionFactory"
            class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    <bean id="sqlSessionTemplate"
            class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory" />
    </bean>
    
    <!-- Transaction 설정 -->
    <!-- Transaction Manager 설정 -->
    <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    <!-- Transaction 대상 설정 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            
            <tx:method name="tx*" rollback-for="RuntimeException" />
            
            <!-- Insert -->
            <tx:method name="insert*" rollback-for="RuntimeException" />
            <tx:method name="write*" rollback-for="RuntimeException" />
            <tx:method name="add*" rollback-for="RuntimeException" />
            <tx:method name="create*" rollback-for="RuntimeException" />
            <tx:method name="regist*" rollback-for="RuntimeException" />
            <tx:method name="set*" rollback-for="RuntimeException" />
                
            <!-- Update -->
            <tx:method name="update*" rollback-for="RuntimeException" />        
            <tx:method name="modify*" rollback-for="RuntimeException" />        
            <tx:method name="edit*" rollback-for="RuntimeException" />      
            <tx:method name="change*" rollback-for="RuntimeException" />    
            
            <!-- Delete -->
            <tx:method name="delete*" rollback-for="RuntimeException" />    
            <tx:method name="remove*" rollback-for="RuntimeException" />
            <tx:method name="terminate*" rollback-for="RuntimeException" />
            
            <!-- ReadOnly -->
            <tx:method name="read*" read-only="true" /> 
            <tx:method name="select*" read-only="true" />   
            <tx:method name="get*" read-only="true" />  
            
        </tx:attributes>        
    </tx:advice>
    
    <!-- AOP 누구한테 언제 갈지 -->
    <aop:config>
        <aop:pointcut expression="execution(public * com.ktds.hskim..web.*.*(..))" id="controllerTx" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="controllerTx" />
    </aop:config>
    
</beans>
cs

우선 DAO 패키지를 생성하고 인터페이스를 생성한다


그리고 impl이라는 패키지를 만들고 클래스를 생성하면 된다


extends를 하려면 extends 먼거하고 implements를 정의한다
그리고 ArticleBiz에 가서 ArticleDAO를 변수로 갖도록 설정하고 setter만 생성한다


Spring MVC의 패턴 중 하나는 반드시 변수가 선언되면 Setter가 정의되는 것이다
변수를 직접 선언하지 않고 Setter로 받아와서 쓰는 형태

이제 DAO 변수를 받기 위해서 articleContext.xml가서 작성을 한다

먼저 DAO를 생성할 때 extends SqlSessionDaoSupport를 상속했기 때문에 property가 하나 추가되어야 한다


2개 중 sqlSessionTemplate를 이용해서 name을 지정한다


그리고 ref로 같은 이름을 준다 ref에 들어간 것은 rootContext에서 생성한 sqlSessionTemplate이다
그런 후 articleBiz를 선언한 bean에서 dao를 property로 넣어주면 된다


# Mapper 생성
src/main/resources에서 mybatis라는 패키지를 생성 후 testDao.xml 파일을 생성하는 것이 기본이다
하지만 사용의 편리성을 증가 시키기 위해서 사용하려는 impl 패키지 내에 sql 패키지를 만들어서 
그안에 dao.xml을 통해서 쿼리를 생성한다


new -> file로 articleDAO.xml을 생성한 후 아래와 같이 작성한다


오타가 존재하면 안되고 문제가 없다면 <을 열었을 때 자동완성이 mapper가 뜨면 된다


그리고 mapper를 생성하고 namespace 옵션을 주고 값은 현재 편집 중인 xml 파일 명을 적는다
단 첫 글자를 대문자로 바꿔주는 것이 기본이다


그리고 select를 이용하는데 id는 사용하려는 메소드 명을 적어주면 된다
또한 select에 옵션값을 통해서 resultType을 줄 수 있다


위와 같이 적는다면 문자열로 리턴이 될 것이다 string은 MyBatis의 별칭이다
자주 사용되는 타입은 int인 _int이고 String인 string이다

TypeAliases로 검색하면 더욱 많은 타입을 볼 수 있다

# Configuration 생성
Mapper들을 모아두는 곳이다
Configration은 src/main/resources 안에 만들면 된다


파일을 생성하고 상단은 mapper와 같이 아래의 문장을 적어주면 된다


잘 작성이 되었다면 <configuration 자동완성이 뜰 수 있게 한다


그리고 configuration을 적은 후 mappers 안에 mapper를 통해서 생성한 DAO 위치를 잡아주면 된다


위치가 맞다면 제일 앞에 /를 지우고 Ctrl 누른 후 누른 다면 링크가 될 것이다

이제는 configuration 위치를 잡아주기 위해서 rootContext로 간다
그런 후 sqlSessionFactory로 가서 property를 추가해주면 된다


classpath는 가장 최상위 폴더인데 src/main/java, src/main/resources, src/test/java, src/test/resources가 classpath이다

# MyBatis 사용
모든 설정이 끝났고 사용하기 위해서 ArticleDAOImpl로 가서 메소드를 수정한다
return 타입에 null이 아닌 아래의 문구를 작성하면된다


selectOne은 하나의 값을 가져오겠다는 뜻이고 ArticleDAO.xml에서 getNowSystemDate 쿼리를 사용하겠다는 의미이다
이제 ArticleBizImpl에서 DAO를 이용해본다


/list로 들어왔을 때 insertNewArticle이 실행되므로 실행을 해보자
그럼 다음과 같이 콘솔에 찍히는 것을 볼 수 있다


#Tips 배포시 프로젝트의 jar나 resoureces가 배포안되는 문제
main에 있는 java나 resources에 있는 xml을 모두 배포하기 위해서는 
pom.xml에서 build 밑에 이 구문을 넣어주면 된다


그러나 위와 같이 xml 파일들은 배포가 되었어도 maven 안에 있지 않는 jar는 배포가 되지 않는다

 
여기에 있는 강사님의 Utilities.jar는 공유가 되지 않기 때문에 maven에 넣어 같이 배포가 되게 해야한다

MyBatis


이전에 MyBatis 설정을 통해 만들어진 bean 7개이다
오른쪽의 4개는 AOP 영역이며 나머지 3개는 Bean으로 그냥 변수 역할의 영역이다

는 property를 뜻하며 

는 생성자를 의미한다 
그리고 property나 생성자가 묶여 있는 하나의 테이블이 하나의 Bean이다

sqlSessionFactory가 dataSource를 사용할 때 화살표를 통해서 관계를 나타낸다
그러므로 둘의 관계는 참조 관계임을 알 수 있다

sqlSessionTemplate는 세션을 이용해서 CRUD를 사용할 수 있게 만들어 주는 것이다
ArticleDAO에게 sqlSessionTemplate를 주고 그러므로 쿼리 처리를 할 수 있던 것이다