Spring - xml을 사용하여 Spring + Mybatis + MySQL 연동 설정 및 SQL 사용해보기

 

# Spring+MyBatis+MySQL 연동하기

- 1. 필요한 라이브러리 추가.

Spring과 MyBatis 사이에 접착제 역할을 하는 My-Batis-Spring 모듈이 필요한데 여기에 필요한 각종 라이브러리들을

pom.xml에 추가한다.

 

#1 Mybatos

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.2.8</version>
</dependency>

 

#2 MyBatis-spring

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>1.2.2</version>
</dependency>

 

#3 spring-jdbc

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.1.7.RELEASE</version>
</dependency>

 

#4 Spring-tset

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>4.1.7.RELEASE</version>
</dependency>

- 2. root-context.xml 파일에 namespace를 추가

이클립스에서 xml파일을 열고 하단에 namespace탭을 클릭하여 설정&amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp;
체크하면 위와같이 xml에 xmlns 속성으로 자동 작성된다.

네임스페이스를 추가해주지 않으면 스프링에서 사용 가능한 XML 태그를 인식하지 못하는 문제가 발생한다.(?)

- 3. DataSource 설정

스프링과 MyBatis를 같이 사용하는 경우 주로 스프링의 설정으로 JDBC 연결을 처리가 많기 때문에

spring-jdbc모듈을 이용하여  root-context.xml에 다음과 같이 DataSource라는 것을 추가한다.

 

DataSource는 JDBC 커넥션을 처리하는 기능을 가지고 있기 때문에 DB와 연동시 반드시 필요하다.

 

 

#root-context.xml 에 추가할내용

1
2
3
4
5
6
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"></property>
        <property name="url" value="jdbc:log4jdbc:mysql://127.0.0.1:3306/book_ex"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root_password"></property>
    </bean>
cs

 

#ETC : DataSource Test : 스프링은 하나라도 설정이 잘못되면 정상적으로 로딩되지 않기에 변경된 설정에 대해서 바로바로 테스트해주는 것이 좋다. 

 

따라서 다음과 같이 DataSource 설정에 대한 Test code를 작성한다.

 

#DataSource 테스트 코드

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
package org.zerock.controller;
 
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;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
public class DataSourceTest {
    @Inject
    private DataSource ds;
 
    @Test
    public void testconnection() throws Exception{
        try(Connection con = ds.getConnection()) { // try() { TODO } catch (Exception e) { TODO} 형태를 try -with구문이라하며 자동으로 Connection 객체가 clse()될 수 있도록 작성 한 것이다.
            System.out.println("test");
            System.out.println("connection 객체출력 : " + con);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 
 
 
cs

 

- 4. SqlSessionFactory 객체 설정

 MyBatis와 스프링 연동 작업에서의 핵심은 Connection을 생성하고 처리하는 SqlSessionFactory 이다.

SqlSessionFactory는 DB연결과 SQL의 실행에 대한 모든 것을 가지고 있는 중요한 객체이다.

 

아래와 같이 SqlSessionFactoryBean 클래스를 빈으로 등록한다.

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

위 내용을 보면 configLocation을 설정하는 property가 보이는데 따라서 mybatis-config.xml 파일을 추가해야한다.

- 5. mybatis-config.xml 파일 추가

MyBatis는 SQL Mapping 프레임 워크로서 별도의 설정파일을 가진다.

mybatos-config.xml 파일을 src/main/resources 디렉토리에 생성해주고 내용은 아래와 같이 작성한다.

1
2
3
<?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>
cs

 https://mybatis.org/mybatis-3/configuration.html 을 참조하면 더 자세하게 xml에 작성할 내용을 작성할 수 있다.

 

여기까지만 수행하면 MyBatis+Spring+MySQL 연동 설정이 끝난 것이다.

 

제대로 설정이 되었는지 확인하기 위해서 MyBatis 연결 테스트 코드를 아래와 같이 작성 해보자.

 

#MyBatis 연결 테스트코드

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
package org.zerock.controller;
 
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;
 
import javax.inject.Inject;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/**/*.xml" })
public class MyBatisTest {
    @Inject
    public SqlSessionFactory sqlFactory;
 
    @Test
    public void testFactory() {
        System.out.println(sqlFactory);
    }
 
    @Test
    public void testSession() throws Exception {
        try (SqlSession session = sqlFactory.openSession()) {
            System.out.println("session 객체출력 : " + session);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
}
 
cs

 

이제 다음은 실제로 MyBatis를 xml을 통해서 sql을 사용해보도록 한다.

 

 

 

# XML을 통해서 DAO에 사용할 실제 SQL query 사용해보기

1. DAO 인터페이스 작성

 일반적인 경우 DAO는 persistence라는 패키지에 작성하며 DAO인터페이스를 해당 패키지 내에 작성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package org.zerock.persistence;
 
import org.zerock.domain.BoardVO;
 
import java.util.List;
 
public interface BoardDAO {
 
    public void create(BoardVO vo) throws Exception;
    public BoardVO read(Integer bno) throws Exception;
    public void update(BoardVO vo) throws Exception;
    public void delete(Integer bno) throws Exception;
    public List<BoardVO> listAll() throws Exception;
}
 
cs

 

2. XML Mapper 작성

  DAO 클래스를 사용하는 실질적인 SQL 문이 작성되는 Mapper.xml 파일을 만들어준다.

  xxxxMapper.xml과 같이 Mapper xml파일들은 src/main/resources 경로에 생성해주도록 한다.

 

다음은 간단한 게시판 페이지에 쓰일 DAO에 사용하는 SQL이 작성된 Mapper.xml 파일 예시이다.

 

#boardMapper.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
<?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="org.zerock.mapper.BoardMapper">
    <insert id="create">
        insert into tbl_board (title, content, writer) values(#{title}, #{content}, #{writer})
    </insert>
 
    <select id="read" resultType="org.zerock.domain.BoardVO">
        select bno, title, content, writer, regdate, viewcnt
        from tbl_board
        where bno = #{bno}
    </select>
 
    <update id="update">
        update tbl_board set title = #{title}, content = #{content}
        where bno = #{bno}
    </update>
 
    <delete id="delete">
        delete from tbl_board where bno = #{bno}
    </delete>
 
    <select id="listAll" resultType="org.zerock.domain.BoardVO">
        <![CDATA[
        select
        bno, title, content, writer, regdate, viewcnt,
        from
        tbl_board
        where bno > 0
        order by bno desc, regdate desc
        ]]>
    </select>
 
</mapper>
cs

 

 

 

3. XML-Mapper 인식 설정

MyBatis가 위에서 작성된 Mapper.xml 파일을 인식하기 위해서 root-context.xml 파일에서

sqlSessionFactory 빈을 등록한 곳에 mapper.xml파일이 어디에 존재하는지 알려주기 위해서

mapperlocation 속성을 추가해줘야한다.

 

 

1
2
3
4
5
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
        <property name="mapperLocations" value="classpath:mappers/**/*Mapper.xml"></property>
    </bean>
cs

<property name="mapperLocations" value="classpath:mappers/**/*Mapper.xml"></property>

요 한줄이 추가 된 것을 확인 할 수 있다.

 

 

 

 4. SqlSessionTemplate 설정 

DAO 작업에서 제일 귀찮은 것이 db관련 작업이후 close()해주는 것이다. 그런데 mybatis에서는 이것을 처리 해주는 sqlSesstionTemplate라는 클래스는 제공하는데 이 클래스의 객체를 쓰겠다고 설정하는 것이다.

 

즉 , SqlSessionTemplate 객체를 스프링 컨테이너의 bean으로 등록해주는 것이다.

1
2
3
    <bean id="sqlSession" name="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
          <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
    </bean>
cs

 

5. 구현 클래스 작성하고 스프링에 Bean으로 등록해주기.

DAO interface에 대한 구현 클래스를 작성해준다. 이때 구현클래스를 @Repository 어노테이션을 설정해주더라도 스프링에서 해당 패키지 디렉토리를 스캔하지 않으면 빈으로 등록되지 않기 때문에 root-context.xml 에서 아래와 같이

특정 디렉토리를 스캔하라는 태그를 작성해준다.

 

#root-context.xml 추가할 내용

1
<context:component-scan base-package="org.zerock.persistence"></context:component-scan>
cs

 

 

#구현 클래스 작성 예시

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
package org.zerock.persistence;
 
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import org.zerock.domain.BoardVO;
 
import javax.inject.Inject;
import java.util.List;
 
@Repository
public class BoardDAOImpl implements BoardDAO {
 
    @Inject
    private SqlSession session;
 
    private static String namespace = "org.zerock.mapper.BoardMapper";
 
    @Override
    public void create(BoardVO vo) throws Exception {
        session.insert(namespace+".create", vo);
    }
 
    @Override
    public BoardVO read(Integer bno) throws Exception {
        return session.selectOne(namespace+".read", bno);
    }
 
    @Override
    public void update(BoardVO vo) throws Exception {
        session.update(namespace+".update", vo);
    }
 
    @Override
    public void delete(Integer bno) throws Exception {
        session.update(namespace+".delete", bno);
    }
 
    @Override
    public List<BoardVO> listAll() throws Exception {
        return session.selectList(namespace+".listAll");
    }
}
 
cs

 

 

# Etc : 작성된 BoardDAO 테스트

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
package test;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.zerock.domain.BoardVO;
import org.zerock.persistence.BoardDAO;
 
import javax.inject.Inject;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
public class BoardDAOTest {
 
    private static final Logger logger = LoggerFactory.getLogger(BoardDAOTest.class);
 
    @Inject
    private BoardDAO dao;
 
    @Test
    public void testCreate() throws Exception {
        BoardVO boardVO = new BoardVO();
        boardVO.setTitle("초기 제목입니다.");
        boardVO.setContent("초기 내용입니다.");
        boardVO.setWriter("user000");
        dao.create(boardVO);
    }
 
    @Test
    public void testRead() throws Exception{
        logger.info(dao.read(5).toString());
    }
 
 
    @Test
    public void testUpdate() throws Exception{
        BoardVO boardVO = new BoardVO();
        boardVO.setBno(5);
        boardVO.setTitle("제목이 수정되었습니다.");
        boardVO.setContent("내용이 수정되었습니다.");
        dao.update(boardVO);
    }
 
    @Test
    public void testDelete() throws Exception{
        dao.delete(1);
    }
}
 
cs

 

#Etc2 : table 작성 sql 문

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE TABLE tbl_member(
    useridbook_exbook_ex     VARCHAR(50NOT NULL,
    userpw    VARCHAR(50NOT NULL,
    username VARCHAR(50NOT NULL,
    email        VARCHAR(100),
    regdate TIMESTAMP DEFAULT NOW(),
    updatedate TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY(userid)
    );
    
CREATE TABLE tbl_board(
    bno INT NOT NULL AUTO_INCREMENT,
    title VARCHAR(200NOT NULL,
    content TEXT NULL,
    wirter VARCHAR(50NOT NULL,
    regdate TIMESTAMP NOT NULL DEFAULT NOW(),
    viewcnt INT DEFAULT 0,
    PRIMARY KEY (bno)
    );
    
ALTER TABLE tbl_board CONVERT TO CHARSET UTF8;
cs

 

결과확인