공부하는 블로그

Spring Boot | MyBatis - MySQL - Hikari CP 연동하기 본문

Spring/Spring Boot

Spring Boot | MyBatis - MySQL - Hikari CP 연동하기

치킨닮은닭 2020. 12. 24. 00:25

# MyBatis?

 마이바티스(MyBatis)는 일반 SQL, 저장 프로시저 및 고급 매핑(Mapping)을 지원하는 프레임워크로 JDBC로 처리하는 상당 부분의 코드와 파라미터 설정 및 결과 매핑을 대신 진행한다. 마이바티스에서는 프로그램에 있는 SQL들을 프로그램 코드와 분리할 수 있어 유지보수성을 향상시켜준다는 장점이 있다. 

 

설명은 장황하지만 그냥 간단하게 말하자면 RDB와 스프링 프로젝트를 연동해주는 프레임워크라고 생각하면 된다.

# Hikari CP(Connection Pool)

 데이터베이스 커넥션을 관리해주는 도구이다. 커넥션 풀은 설정된 풀의 사이즈만큼의 커넥션만을 허용하며 순차적으로 DB에 요청된 커넥션을 처리해준다. 여러 DBCP(Database Connection Pool)가 존재는데 그 중 히카리 CP는 가볍고 빠른 처리속도를 자랑하며 스프링 부트 2.0부터 default DBCP로 지정되었다.

# MyBatis - MySQL - Hikari CP 연동하기

1. build.gradle : JDBC, MyBatis, HikariCP 라이브러리 추가

compile 'mysql:mysql-connector-java:8.0.22'
compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4'
compile 'com.zaxxer:HikariCP:3.4.5'

 

 

2. application.properties : datasource 설정

spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.hikari.username=username
spring.datasource.hikari.password=password
spring.datasource.hikari.pool-name=TestHikariPool

 

 HikariConfig에 등록될 데이터 소스를 설정한다.

 

·spring.datasource.hikari.driver-class-name : JDBC 드라이버 이름

·spring.datasource.hikari.jdbc-url : DB서버 호스트, 포트, 스키마 지정

·spring.datasource.hikari.username : DB 유저명 (ex. root)

·spring.datasource.hikari.password : DB 유저의 비밀번호

·spring.datasource.hikari.pool-name: 히카리풀 이름 지정

 

3. DBConfig 작성

package hello.test.config;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

@Configuration
@PropertySource("classpath:/application.properties")
public class DBConfig {

    @Autowired
    ApplicationContext applicationContext;

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public HikariConfig hikariConfig() {
        return new HikariConfig();
    }

    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(hikariConfig());
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

        bean.setDataSource(dataSource);
        bean.setMapperLocations(applicationContext.getResources("classpath:/sqlmap/*.xml"));
        bean.setTypeAliasesPackage("hello.test.domain");

        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

 

@Configuration : 스프링 컨테이너에 등록할 빈에 대한 설정파일임을 명시

@PropertySource : 설정파일에서 읽어올 설정 정보들의 경로를 지정

@Bean : 스프링 빈으로 등록

@ConfigurationProperties(prefix = "") : 읽어올 설정 정보의 prefix 지정

 

설정에 대한 내용은 다음과 같다.

 

1. application.properties의 설정 정보를 토대로 HikariCP 설정

2. SqlSessionFactory에 HikariCP의 Datasource, Mybatis Mapper 경로, TypeAliase 패키지 경로 설정

   ** Mybatis Mapper : Mybatis의 SqlSession에서 불러올 쿼리 정보가 담겨있다.

   ** TypeAliase : DB 테이블과 매칭될 자바 VO 객체를 지정해준다.

 

모든 설정이 완료되었다. 스프링 부트를 기동하면 다음과 같은 로그를 볼 수 있다.

프로퍼티 파일에서 설정한 히카리풀의 이름으로 잘 나오는 것을 확인할 수 있다.

 

4. 자바 VO 클래스 & MyBatis Mapper(xml) 생성

 먼저 MySQL 클라이언트에 접속하여 테스트용 스키마에 BOARD 테이블을 생성하자.

# 스키마 선택
USE TEST;

# 테이블 생성
CREATE TABLE BOARD(
    BOARD_NO INT AUTO_INCREMENT PRIMARY KEY,
    TITLE VARCHAR(200),
    CONTENT VARCHAR(1000),
    REG_DATE DATETIME DEFAULT CURRENT_TIMESTAMP()
);

 그 다음은 위의 테이블과 매칭될 자바 클래스파일을 TypeAliase로 설정한 패키지(hello.test.domain)에 만들어주자.

package hello.test.domain;

public class Board {

    private int boardNo;
    private String title;
    private String content;
    private String regDate;

    public Board() {};

    public Board(int boardNo, String title, String content, String regDate) {
        this.boardNo = boardNo;
        this.title = title;
        this.content = content;
        this.regDate = regDate;
    }
    
    public int getBoardNo() {
        return boardNo;
    }

    public void setBoardNo(int boardNo) {
        this.boardNo = boardNo;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getRegDate() {
        return regDate;
    }

    public void setRegDate(String regDate) {
        this.regDate = regDate;
    }
    
}

 기본적인 Getter/Setter, Constructor를 함께 작성해주었다.

**cf.lombok 라이브러리을 사용하면 간단한 어노테이션으로 Getter/Setter, Constructor를 만들 수 있다.

 

 다음으로는 위에서 설정한 매퍼 경로('classpath:/sqlmap/*.xml')에 board.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="board">
    <insert id="insertBoard" parameterType="board">
        INSERT INTO BOARD(TITLE, CONTENT)
        VALUES (#{title}, #{content})
    </insert>
    <select id="findBoardAll" resultType="board">
        SELECT BOARD_NO as boardNo
            , TITLE as title
            , CONTENT as content
            , REG_DATE as regDate
        FROM BOARD
    </select>
    <select id="findBoardById" parameterType="int" resultType="board">
        SELECT BOARD_NO as boardNo
            , TITLE as title
            , CONTENT as content
            , REG_DATE as regDate
        FROM BOARD
        WHERE BOARD_NO = #{boardNo}
    </select>
</mapper>

· namespace : 자바의 SqlSession에서 사용할 매퍼의 별칭

· id : 자바의 SqlSession에서 사용할 쿼리문의 별칭

· parameterType : 쿼리에서 사용될 매개변수의 타입 지정

· resultType : 쿼리의 결과를 담을 자바 클래스 지정

 

 SqlSession에서 namespace와 id는 'namespace.id'와 같은 형식으로 사용된다.

** ex. board.insertBoard

 

 parameterType을 지정해준 후 '#{java 변수명}'의 형식으로 쿼리에 넣어주면 된다. 

 

 parameterType과 resultType의 경우 위에서 TypeAliase를 설정해주었기 때문에 자바 클래스 이름의 lowercase만 작성해도 정상적으로 매핑이 된다. 만약 따로 지정을 해주지 않은 경우에는 패키지명까지 전부 명시해주어야 한다. 

 ** ex. board -> hello.test.domain.Board

 

이제 스프링 빈으로 등록된 SqlSession으로 매퍼에 등록된 쿼리를 실행시킬 수 있다.

 

5. Repository 클래스 생성 및 Repository Bean 등록

package hello.test.repository;

import hello.test.domain.Board;

import java.util.List;

public interface JDBCRepository {

    int insertBoard(Board board);

    List<Board> findBoardAll();

    Board findBoardById(int boardNo);

}
package hello.test.repository;

import hello.test.domain.Board;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class JDBCRepositoryImpl implements JDBCRepository{

    @Autowired
    SqlSession sqlSession;

    @Override
    public int insertBoard(Board board) {
        return sqlSession.insert("board.insertBoard", board);
    }

    @Override
    public List<Board> findBoardAll() {
        return sqlSession.selectList("board.findBoardAll");
    }

    @Override
    public Board findBoardById(int boardNo) {
        return sqlSession.selectOne("board.findBoardById", boardNo);
    }

}

 Repository 인터페이스와 그 구현체이다. 구현체에서는 @Autowired를 통한 DI로 빈에 등록한 SqlSession을 불러와 사용한다. 생성된 자바 클래스는 @Repository 를 이용하여 스프링 빈으로 등록한다.

 

이제 등록된 레파지토리를 실제 서비스 로직에서 불러와 사용하면 된다.


Reference

 

- 스프링부트 Mybatis + HikariCP : linked2ev.github.io/gitlog/2019/08/21/springboot-mvc-4-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-MyBatis-+-HikariCP-+-MariaDB-%EC%84%A4%EC%A0%95/

- 히카리CP 소개 : netframework.tistory.com/entry/HikariCP-%EC%86%8C%EA%B0%9C

'Spring > Spring Boot' 카테고리의 다른 글

Spring Boot | IntelliJ로 프로젝트 생성하기  (0) 2020.12.20
Spring | Spring Boot Introduction  (0) 2020.09.20
Comments