[Spring4] 스프링에서 마이바티스(Mybatis) 사용하기

[Spring4] 스프링에서 마이바티스(Mybatis) 사용하기

* 본 게시물은 http://addio3305.tistory.com/62 을 매우 많이 참고하여 작성되었다. 상세한 설명은 이쪽에 잘 나와있다.

본 게시물은 MySQL을 사용한다는 전제로 작성되었으므로, 오라클에 대해서는 위 게시물을 참고 바란다.

본 게시물은 [Spring4] STS에서 스프링 웹 프로젝트 생성 (http://blog.naver.com/bb_/221339454799) 포스팅에 이어서 곧바로 적용시킬 수 있는 예제이다. 다시 말해 STS 설치부터 마이바티스 연동까지 한 큐에 해결할 수 있다.

스프링에 마이바티스를 붙이려면 파일을 10개 정도 고쳐야 한다.

1. pom.xml 에 디펜던시 추가

(/프로젝트폴더/pom.xml)

        <!– DB –>
        <dependency>
        <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.2</version>
        </dependency>
       
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.0</version>
        </dependency>
       
        <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>6.0.6</version>
        </dependency>

2. web.xml 에 컨텍스트 파람 추가

(/프로젝트폴더/src/main/webapp/WEB-INF/web.xml)

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:config/spring/context-*.xml</param-value>
    </context-param>

3. context-datasource.xml 작성

(/프로젝트폴더/src/main/resources/config/spring/context-datasource.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
xsi:schemaLocation=http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
>
<bean id=“dataSource” class=“org.apache.commons.dbcp.BasicDataSource” destroy-method=“close”>
<property name=“driverClassName” value=“com.mysql.jdbc.Driver”/>
<property name=“url” value=“jdbc:mysql://아이피주소:포트/디비명”/>
<property name=“username” value=“아이디”/>
<property name=“password” value=“비밀번호”/>
</bean>
</beans>

여기서 url 프로퍼티 뒤에 물음표를 붙이고 필요한 파라미터를 더 추가할 수 있다.

개인적으로는 아래와 같이 기입해서 사용하고 있다.

<property name=“url” value=“jdbc:mysql://아이피주소:포트/디비명?userUnicode=true&amp;characterEncoding=utf8&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC”/>

xml이므로 앤드 기호를 &amp; 로 써야 한다.

4. context-mapper.xml 작성

(/프로젝트폴더/src/main/resources/config/spring/context-mapper.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:context=http://www.springframework.org/schema/context
    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
>
    <bean id=“sqlSession” class=“org.mybatis.spring.SqlSessionFactoryBean”>
        <property name=“dataSource” ref=“dataSource” />
        <property name=“mapperLocations” value=“classpath:/mapper/**/*-mapper.xml” />
    </bean>

    <bean id=“sqlSessionTemplate” class=“org.mybatis.spring.SqlSessionTemplate”>
        <constructor-arg index=“0” ref=“sqlSession”/>
    </bean>
</beans>

5. test-mapper.xml 작성

(/프로젝트폴더/src/main/resources/mapper/test/test-mapper.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=“test”>

    <!– <select id=“selectCount” parameterType=“hashmap” resultType=“hashmap”> –>
    <select id=“selectCount” resultType=“int”>

    <![CDATA[
         SELECT COUNT(*) FROM test

    ]]>

</select>

</mapper>

* 이 xml 파일에는 잘 작동하는 쿼리를 적어넣어야 한다. 현재 test라는 테이블의 로우 개수를 가져오고 있는데, 아마 이 글을 읽으시는 독자 분의 DB에는 test 라는 테이블이 없을 것이다. 테스트할 수 있도록 test 라는 테이블을 새로 만들든지, 존재하는 테이블 이름으로 바꿔서 적어주시길 바란다.

6. AbstractDAO.java 작성
(/프로젝트폴더/src/main/java/com/bb/nddoc/common/dao/AbstractDAO.java)

package com.bb.nddoc.common.dao;

import java.awt.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class AbstractDAO {
    private static final Logger logger = LoggerFactory.getLogger(AbstractDAO.class);

    @Autowired
    private SqlSessionTemplate sqlSession;

    protected void printQueryId(String queryId) {
        logger.info(“QueryId : “ + queryId);
    }

    public Object insert(String queryId, Object params) {
        printQueryId(queryId);
        return sqlSession.insert(queryId, params);
    }

    public Object update(String queryId, Object params) {
        printQueryId(queryId);
        return sqlSession.update(queryId, params);
    }

    public Object delete(String queryId, Object params) {
        printQueryId(queryId);
        return sqlSession.delete(queryId, params);
    }

    public Object selectOne(String queryId) {
        printQueryId(queryId);
        return sqlSession.selectOne(queryId);
    }

    public Object selectOne(String queryId, Object params) {
        printQueryId(queryId);
        return sqlSession.selectOne(queryId, params);
    }

    @SuppressWarnings(“rawtypes”)
    public List selectList(String queryId) {
        printQueryId(queryId);
        return (List) sqlSession.selectList(queryId);
    }

    @SuppressWarnings(“rawtypes”)
    public List selectList(String queryId, Object params) {
        printQueryId(queryId);
        return (List) sqlSession.selectList(queryId, params);
    }
}

7. TestDAO.java 작성
(/프로젝트폴더/src/main/java/com/bb/nddoc/dao/test/TestDAO.java)

package com.bb.nddoc.dao.test;

import org.springframework.stereotype.Repository;
import com.bb.nddoc.common.dao.AbstractDAO;

@Repository(“testDAO”)
public class TestDAO extends AbstractDAO {

    public int selectCount() throws Exception {

        // 여기서 test.selectCount 란, 네임스페이스가 test 인 *-mapper.xml 내부의, id 가 selectCount 인 쿼리를 의미한다.

        // 즉, test-mapper.xml 파일에 담긴 쿼리를 뜻한다.​
        return (Integer) selectOne(“test.selectCount”);
    }
}

8. TestModel.java 작성
(/프로젝트폴더/src/main/java/com/bb/nddoc/model/test/TestModel.java)

package com.bb.nddoc.model.test;

import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.bb.nddoc.service.test.TestServiceImpl;

@Controller
public class TestModel {
    
private static final Logger logger = LoggerFactory.getLogger(TestModel.class);
    
    @Resource(name=“testService”)
    private TestServiceImpl testService;
    
    @RequestMapping(value = “/test”, method = RequestMethod.GET)
    public String test(Model model) {
        
        try {
            int result = testService.select();
            logger.info(“result : “ + result);
        
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        
        return “home”;
    }
}

9. TestService.java 작성

(/프로젝트폴더/src/main/java/com/bb/nddoc/service/test/TestService.java)

package com.bb.nddoc.service.test;

public interface TestService {

    public int select() throws Exception;
}

10. TestServiceImpl.java 작성

(/프로젝트폴더/src/main/java/com/bb/nddoc/service/test/TestServiceImpl.java)

package com.bb.nddoc.service.test;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.bb.nddoc.dao.test.TestDAO;

@Service(“testService”)
public class TestServiceImpl implements TestService {

    @Resource(name=“testDAO”)
    private TestDAO testDAO;
    
    public int select() throws Exception {
        return testDAO.selectCount();
    }
}

새로 작성하거나 수정한 파일의 계층구조는 다음과 같다. (10개 파일)

많은 파일을 고쳤지만 앞으로도 그래야 하는 것은 아니다.

pom.xml, web.xml, context-datasource.xml, context-mapper.xml, AbstractDAO.java 은 최초 한 번만 수정/작성하면 된다.

새로운 SQL 세트가 필요할 때에는 test-mapper.xml, TestDAO.java, TestModel.java, TestService.java, TestServiceImpl.java 을 적당히 복사해서 만들면 된다.

예를 들면, board-mapper.xml, BoardDAO.java, BoardModel.java, BoardService.java, BoardServiceImpl.java 식으로 만들면 된다.