MyBatis를 Springboot에서 사용해보자

Hyun-jin Won·2020년 12월 14일
1

Spring-boot

목록 보기
1/1

작성 계기

연동미스 때문에 사러저버린 내 주말 8+시간 히힣히힣ㅎ힣히히히힣힣힣

처음에는 구글검색을 통해서 블로그에서 설명한 방식을 그대로 따라하여 연동을 시도해보았고 시작 4시간만에 성공했지만, 조금만 설정을 바꾸어도 문제가 일어나서 직접 여러가지 방법을 테스트해보았고 나중에 까먹지 않기 위해서 기록을 하기로 하였다.

나처럼 Mybatis를 많이 사용해보지 않았거나, 좀 더 깔끔한 방법으로 설정을 원하는 사람들에게 이 글이 도움이 되었으면 한다.

사용방법

Mybatis를 사용하려면 크게 4가지를 정의해야 한다.

  • 쿼리문을 정의한 mapper.xml 파일
  • mapper.xml를 자바코드에서 실행시키는 Mapper Class or interface (Mapper.java)
  • 쿼리의 결과데이터를 담는 중간 매개 Class (VO)
  • 위의 3개의 위치를 알려주는 설정

여기서 xml 쿼리문 작성은 다른 블로그에서도 많이 나와있는 내용이니 제외한다.
해당 항목을 제외하고는 여기서 2개의 항목이 선택사항으로서 주어진다.

  1. Mapper를 클래스로 정의할 것인가, 인터페이스로 정의할 것인가?
  2. 설정을 어떻게 잡을 것인가?

이 글에서는 Mapper를 interface로 정의하고 설정을 application.properties를 이용한다.
이유는 후술한다.

선행지식

  • Mapper.xml와 Mapper.java를 연결해주는 방식은 NameSpace와 각 쿼리문의 id의 조합이다.
  • VO는 위와 같은 방법이 없기에 위치를 알려주는 설정이 필요하다.

사용한 Dependency

mybatis-spring.boot-starter, spring-boot-starter-jdbc, 사용할 jdbc, 이렇게 3개를 사용하면 된다.
필자는 mysql를 사용하며, VO작성의 편의성을 위해 lombok를 추가로 사용할 것이다.

Mapper 정의

Mapper.java는 interface 또는 Class로 정의해서 사용할 수 있다.
각각에 대해 장단점이 존재하는데

1. 살펴보기

class 사용

- 장점

  • 쿼리문 실행 전에 넣어줄 매개변수와 쿼리 결과값의 변형을 정의할 수 있다.
  • Namespace를 내마음대로 둘 수 있다.
  • .xml 파일의 쿼리문 id와 mapper 메소드명을 일치시킬 필요가 없다.

- 단점

  • sqlsession 객체를 주입받아야 하며, 쿼리문 실행 시 항상 호출해야 한다.
  • 쿼리문 호출 시 sqlsession에 .xml 파일의 namespace와 쿼리문 id을 매개변수로 넘겨야 한다.

interface 사용

- 장점

  • 메소드의 내부 구현이 불필요하다.
  • sqlsession 객체 주입이 불필요하다.
  • .xml 파일의 쿼리문 id와 mapper 메소드 명이 일치한다.

- 단점

  • .xml의 Namespace가 실제 Mapper.java위치를 가르켜야 한다.
  • 메소드 내부 정의가 불가능하다.

유지 보수의 측면을 생각하면 interface가 더 낫다고 생각한다.
선언도 간단하고, .xml 쿼리문의 id와 메소드 명이 일치하기에 연관된 쿼리문을 찾기도 편하다.

2. 정의하기

  • 코드 부분
/*Mapper.java 코드*/
@Repository
@Mapper
public interface LookupMapper {
   List<CountOfPeriodVO> getConnectionCountMonthly(Map<String, String> map);
  ...
  }
<!-- Mapper.xml 코드 -->
<mapper namespace="com.mumuni.springboot_web.dao.LookupMapper">
    <select id="getConnectionCountMonthly" 
    		parameterType="map" 
    		resultType="CountOfPeriodVO">
        select A.date, COUNT(*) as count from
        (
        SELECT distinct DATE_FORMAT(CREATE_DATE,'%Y-%m') date, USERID
        FROM RequestHistory
        WHERE CREATE_DATE>= #{startDate} AND #{endDate} > CREATE_DATE
        ) as A
        group by A.date;
    </select>
  • 경로 부분

이미지를 보면 LookupMapper.java의 경로가 connectionMapper.xml의 namespace에 정의되어 있고, 각 쿼리의 id가 Mapper.java의 메소드 명과 일치 하는 것을 확인할 수있다.

MyBatis tool를 설치하는 것을 추천한다.
Intellij의 경우 해당 툴을 설치하면 연관된 메소드와 쿼리문에 mybatis 마스코트 아이콘을 표기하여 연결을 표시해주거나 자동 생성을 도와준다.

VO 정의

이건 조금만 찾아봐도 누구라도 알 것이라 생각한다.
코드 부분만 올리고 생략한다.

@Getter @Setter
public class CountOfPeriodVO {
    int count;
    String date;
}

설정 정의

이 부분이 가장 고생했던 부분이였다.
여러 블로그에서 Config 클래스를 정의하여 정의하는 방식을 추천하였으나 내 마음에 들지 않았다. properties에서 설정을 끝마치고 싶었고 mybatis-spring-boot-starter를 사용하여 이를 사용하기로 했다.

#appliction.propertis
#mybatis 설정
mybatis.type-aliases-package=com.mumuni.springboot_web.**.vo
mybatis.mapper-locations=/mapper/**/*.xml

각 기능을 설명하면 이렇다.

  • mybatis.type-aliases-package : VO 파일 경로
  • mybatis.mapper-locations : mapper.xml 파일 경로

Mapper.java의 경우 @Mapper 어노테이션을 통해서 이 객체가 myBaties Mapper라는 것을 알려준다. 하지만 VO, mapper.xml에는 특별한 어노테이션이나 정보가 들어가지 않는다. 이러한 설정을 위해서 해당 설정을 추가해주는 것이다.

mybatis.type-aliases-package 는 설정하지 않아도 되지만, 추가하지 않으면 mapper.xml파일에서 vo를 사용시 resultType에 해당경로를 전부 넣어줘야 한다.

resultType="com.mumuni.springboot_web.rest_lookup.vo.CountOfPeriodVO"

번외) hikariCP 와의 연동

만약 hikariCP를 쓰고 싶다면
1. datasource를 hikari로 변경하고,
2. dataSource 부분을 Bean으로 추가해 HikariDatasource를 넣어주고 사용하면 된다.

  • 자바 코드
    @Configuration
    @PropertySource("classpath:/application.properties")
    public class DatabaseConfiguration {
       @Bean
       @ConfigurationProperties(prefix = "spring.datasource.hikari")
       public HikariConfig hikariConfig() {
           return new HikariConfig();
       }
       @Bean
       public DataSource dataSource() {
           DataSource dataSource = new HikariDataSource(hikariConfig());
           return dataSource;
       }
    }

#application.properties 코드
#datasource 설정
spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://127.0.0.1:3306/ComentoDB?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.hikari.username=whj
spring.datasource.hikari.password=hello1234

DataSource를 저렇게 Bean으로 등록하지 않으면 Mybatis가 datasource를 찾지 못해 sqlSessionFactory를 생성할 수 없어 에러가 뜬다.

마치며...

설정을 내가 원하는 방식으로 최대한 간소화했으나 이거 하나로 하루를 날려먹었다.
보람차긴 하나 현자타임이 몰려오는 것은 어쩔수가 없다. 내 주말 돌려줘....

참고 사이트

https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
https://github.com/brettwooldridge/HikariCP
https://taetaetae.github.io/2019/04/21/spring-boot-mybatis-mysql-xml/

profile
삽질을 주체하지 못하는 잉간

0개의 댓글