Springboot에서 Mybatis 사용하기

 

 

저번 게시물에서 JDBC를 이용해서 데이터베이스와 통신하는 방법에대해서 알게되었다

JDBC로 프로젝트를 만들어보면 알겠지만 매번 데이터베이스와 연결하는 작업은 귀찮고 번거로운 일이다

거의 중복코드만 70% 이상발생하는 거같다 그외에 예외처리를 하다보면 별거없는 코드도 정말 난잡해져서 유지보수하기 귀찮아진다

 

 

이를 저번게시글에서 만든 코드들을 최대한 덜어내고 Mybatis를 이용해서 정말 간단하게 데이터베이스와 통신하는 방법에대해서 알아보도록하자

참고로 Gradle로 프로젝트를 진행한다

 

 

시작하기 앞서 Mybatis 버젼 3.x.x이상 버전을 꼭! 설치해주길 바란다

 

    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.0'

 

자기 Mybatis 버전을 확인하고 싶으면 build.gradle로 들어가서 버전 3이상인지 꼭 확인해주길 바란다

아니면 설정방법들이 달라서 제대로 진행이 안될수있다

 

 

 

 

 

 

 

 

JDBC 중복코드 제거하기


 

 

먼저 저번게시물에서 완성된 최종 JDBC 코드이다 알다싶이 study라는 테이블에서 데이터를 받아와 출력하는 간단한 로직인데도 중복코드들이 많다

 

만약 insert 해야되는 로직을 구현해야되는 일이생긴다면 또 접속정보넣고, 연결하고, SQL보내고, 연결닫아주고를 반복해야된다

지금이야 간단한 예제니깐 괜찮은데? 라고 생각할수있지만 만약 실제 프로젝트에서 JDBC를 사용할려면 한숨부터 나올것이다

우선 처음으로 중복코드들을 제거해보자

 

 

 

main -> resource -> application.properties 파일에 들어가서 위와같이 설정해주자

 

 

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbasic?
&serverTimezone=UTC&autoReconnect=true&allowMultiQueries=true&characterEncoding=UTF-8
spring.datasource.username=Hyeonchul
spring.datasource.password=dbslfjqm11

 

우리가 JDBC를 이용해서 데이터베이스와 통신할때 쓰던 접속정보를 application.properties 파일로 따로 뺀것이다

@Bean을 이용해서 빈컨테이너에 datasource를 넣어서 주입해줄수있지만 위처럼 따로 설정파일로 빼는것이 보기편한거같다

 

참고로 driver-class 오류가 나는사람이 있을수도있는데 mysql driver 의존성이 설정안될거일수도 있으니 확인해보길 바란다

 

 

 

 

설정정보를 프로퍼티 파일에 따로뺀결과 코드가 쫌 간결해진것을 확인할수있다

Datasource는 필드주입을 통해서 넣어주었고 만약 Autowired가 뭔지 모르겠다 하는사람들은 Spring DI를 확인해보자

어려운건 아니고 DataSource의 구현체를 new 연산자로 받아야하는데 그것을 그냥 스프링이 대신해준것이다

 

datasource안에는 이제 데이터베이스와 통신하기위한 설정정보들이 있기떄문에 바로 getConnetion()을 통해서 연결할수있다

 

참고로 데이터베이스 안에 값을 뺄때는 .next()를 무조건 해줘야한다 아니면 nullpointexception 예외가 발생할수도있다

자세한건 여기를 클릭해서 보도록하자

 

 

 

이제 본격적으로 코드를 최적화 해보자 아마 여러과정을 거치다보면 정말 코드가 깔끔해지는것을 실시간으로 느낄수있을것이다

 

 

 

 

 

 

 

 

 

Mybatis는 무엇일까?


시작하기앞서 mybatis에 대해서 알아보도록 하자

mybatis는 실무에서 SQL을 보다 효율적으로 다루기위해 따로 파일(xml, interface)로 빼내서 유지보수에 용이함을 줄수있다

위에서 보다싶이 조금만 SQL이 길어져도 +로 줄바꿈하고 개행해주고 그러다보니깐 불편함도 불편함이지만 오타가 날가능성이 매우매우높다

 

그리고 일일이 setString을 해주는것도 정말 귀찮은 일이라고 볼수있고 가장큰건 한 소스파일안에 SQL과 로직들이 있다는것이다

객체지향에서 중요한건 각자 파일들의 역할이 분명해야 한다는것이다 SQL은 SQL문법만, 회원가입로직은 오로지 회원가입만 담당한다

변경하는 포인트가 2개이상이 되면 유지보수도 힘들어지도 하나의 파일이 담당하는 기능들이 많아져서 오류가 날가능성이높다

 

이외에 장점으로는 구조적인 강점을 이용한 성능향상(join mapping) 최적화된 쿼리구현 등 다양한 이점이있어서 굳이 안쓸이유는 없을것이다

 

물론 컴파일시점에 오류를 잡아낼수 없다거나 DTO가 변경되면 맵핑정보도 수정해야되는 등 다른단점들도 존재하지만 생산성이 크게 올라가기때문에 trade-off 를 잘 따져보도록 하자

 

 

 

 

 

 

 

 

 

 

Mybatis 사용하기


mybatis를 사용하기앞서 여러가지 방법이 존재한다

dao를 직접 작성해서 맵핑하거나 interface를 통해서 맵핑하는 방법이 있는데 여기서는 interface를 통해서 맵핑하는 방법에 대해서 알아보도록 할것이다

 

sqlSessionfactorybean을 빈으로 등록하고 template도 따로 만들어줘야하지만 스프링부트는 이것을 자동으로 해주기때문에 굳이 설정하는 방법에 대해서 알아보진않을것이다

 

만약 궁금한 사람이 있다면 구글에 정보가 많으니 한번 확인해보길 바란다

그리고 꼭 확인해야할것은 mybatis 3.x.x 버전 이상부터 지원하는 방식이기떄문에 그아래버전은 제대로 작동하지 않을수있다

그런경우에는 오류를 읽어보고 sqlSessionfactorybean이나 mapper를 만들어주면 될것이다 버전을 꼭 확인해주도록 하자

 

먼저 Mybatis를 사용하기위해서는 DAO, DTO에 관한 개념을 아는것이 이해하는데 편할것이다 만약 모른다면 여기를 클릭하도록 하자

 

 

 

 

가장 먼저 할것은 DTO를 작성해주는것이다 DTO에 관한 내용은 따로 설명하지 않겠다

자기가 만든 테이블과 꼭 1:1 매칭을 시켜줘야하며, 칼럼에 이름과 타입이 모두 같아야한다

 

이전 JDBC강의떄 만들어둔 study 라는 테이블안에 id, username, password 이렇게 3개의 칼럼이 있었으니 똑같은 private 변수를 만들어준다

 

 

 

 

그다음 Lombok을 이용해서 Getter와 Setter를 열어주고 데이터값 확인을위해 toString을 오버라이딩해줬다 그다음 기본생성자를 만들어준다 

 

 

 

DTO를 만들었으니 이제 쿼리가 들어갈 mapper를 작성해줄 차례다

application.properties에 들어간뒤 mapper위치를 지정해줄건데 나같은경우는 resoures에 mapper라는 폴더를 만들어주고 그아래에 있는 모든 xml파일을 맵퍼로 설정해주었다

 

mapper폴더 안에있는 xml로 쿼리를 다룰것이다

 

 

 

 

이제 인터페이스를 만들어주겠다 인터페이스이름이 UserDao이긴하지만 실제로 Dao를 구현하는 방법은 사용하지않을것이다

interface와 class로 직접구현하는 방법 둘다 장단점이있지만 interface로 구현하는게 좀더 장점이 크다고 생각되는거같다

우선 Dao를 직접구현하려면 sqlsession을 계속해서 주입받아야하고 쿼리문호출시에 sqlsession에 지정한 매개변수를 넘겨야한다

 

그에반해 interface는 알아보기쉽고 간편하게 설정되며 무엇보다 메소드명과 xml파일 id가 일치해서 찾아보기도 쉽다

 

 

@Mapper
public interface UserDao {

    User findUser(int id);

}

 

 

UserDao 인터페이스를 생성해주고 여기서 중요한건 @Mapper를 꼭 붙혀주도록 하자

UserDao를 맵퍼로 인식해주는 역할을 한다

그다음 주의깊게 볼것은 반환타입, 메소드명, 매개변수의 타입이다

반환타입은 User, 메소드명은 findUser, 매개변수로는 int 타입의 변수 id를 가진다

 

id를 넘기면 데이터베이스에서 해당되는 id를 가진 User 데이터를 객체로 반환해준다

그다음 이제 mapper폴더에 들어가서 xml 파일을 작성해주도록 하자 그리어렵진 않고 진짜 간단하다

 

 

 

 

 

mapper 폴더안에 User.xml이라는 파일을 만들어주고 기본적으로 넣어야할것이있다

mybatis Mapping xml을 사용하기위한 DOC를 선언해줘야하는데 위 사진처럼 똑같이 작성해주면 된다

 

<?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">

 

 

이제 작성할 준비가 끝났다 본격적으로 SQL을 만들어보도록 하자

 

 

 

가장처음 @Mapper 에노테이션이 붙은 interface를 찾아서 namespace에 정의를 해줘야한다

위에서 보면 @mapper가 붙은 인터페이스는 UserDao이기 떄문에 패키지 경로로 전부 적어주도록 하자

 

해당 되는 패키지 경로 인터페이스 이름도 끝에 꼭 붙혀주도록 하자

 

 

 

 

 

 

이제 안에 SQL문을 작성할것인데 우선 나는 select를 이용해서 study에 든 데이터값을 가져오되, 매개변수로 넘어온 id값에 해당하는 데이터만 데이터로 받아올것이다

 

select 태그를 만들어주고 이제 여기서 중요한건 id는 메소드명, resultType은 반환타입 나같은 경우는 DTO이름이 User니깐 User객체를 받을것이다

User에 패키지경로까지 전부 적어줘야하니깐 이점 유의해주길 바란다

그다음 parameterType으로는 int로 받을것이다

 

 

 

 

이제 select 태그안에 SQL을 작성해주도록 하자 study 테이블에 매개변수로 넘어온 id를 가진 데이터를 User로 넘겨주는것이다

 

여기서 id = #{id}는 자기 매개변수에 변수이름으로 적어주도록 하자

 

 

 

 

 

이제 테스트를 해보도록 하자 @mapper가 있는 인터페이스를 주입받고 인터페이스안에 findUser 1번 인덱스에 있는 값을 user에 담아서 반환한다

그리고 출력하면 정상적으로 출력되는것을 확인할수있다

 

 

 

 

한번 mybatis를 사용하기 전하고 비교해보도록 하자

 

 

 

 

 

눈에띄게 코드양이 엄청 줄어든것을 확인할수있다

간단한 SQL 작성한뒤 인터페이스로 맵핑만 시켜주는 작업만해도 이렇게 간편하게 데이터베이스와 통신할수있다는것이 놀랍다

 

mybatis 는 SQL Mapping기술인데 요즘 떠오르는 대세인 JPA라는 ORM 기술도 있다 이것은 Entity를 코드짜듯이 쉽게 테이블을 만들고 persist, find 등의 메소드를 통해서 CRUD를 엄청 간편하게 할수있는데

 

이건 나중에 시간이되면 올리도록 하겠다

 

이제 mybaits 사용법을 알았으니 우리도 재미있게 프로젝트를 만들어보도록 하자