1.  MyBatis 

스프링 프레임워크의 중요한 특징 중 하나는 다른 프레임워크들을 쉽게 결합해서 사용할 수 있다는 점이다. 이것은 스프링 프레임워크가 웹이나 데이터베이스와 같이 특정한 영역을 구애받지 않고 시스템의 객체지향 구조를 만드는데 이용된다는 성격 때문.

 

데이터베이스와 관련해서 스프링 프레임워크는 자체적으로 'spring-jdbc'와 같은 라이브러리를 이용해서구현할 수도 있고, MyBatisJPA 프레임워크를 이용하는 방식도 존재


💫  MyBatis는 'Sql Mapping Framework'라고 표현

  • 'Sql Mapping'이라는 단어가 의미하는 바는 SQL의 실행 결과를 객체지향으로 '매핑'해 준다는 뜻
  •  MyBatis를 이용하면 기존의 SQL을 그대로 사용할 수 있고 다음과 같은 점들이 편리해짐
  PreparedStatement / ResultSet의 처리 : 기존에 프로그램을 작성해서 하나씩 처리해야 하는 파라미터나 ResultSet의 getXXX()를 MyBatis가 알아서 처리해 주기 때문에 기존에 비해서 많은 양의 코드를 줄일 수 있음
  Connection / PreparedStatement / ResultSet의 close() 처리 : MyBatis와 스프링을 연동해서 사용하는 방식을 이용하면 자동으로 close() 처리할 수 있음
  SQL의 분리 : MyBatis를 이용하면 별도의 파일이나 어노테이션 등을 이용해서 SQL을 선언함. 파일을 이용하는 경우에는 SQL을 별도의 파일로 분리해서 운영이 가능  ➡️ 자바 코드에 쿼리문을 넣지 않아도 됨

 

1)  MyBatis와 스프링의 연동 방식


👻  MyBatis는 단독으로도 실행이 가능한 완전히 독립적인 프레임워크이지만, 스프링 프레임워크는 MyBatis와 연동을 쉽게 처리할 수 있는 라이브러리와 API들을 제공
👻  스프링에서 제공하는 라이브러리를 이용하는지 여부에 따라서 다음과 같은 방식 중에 하나로 개발이 가능

  • MyBatis를 단독으로 개발하고 스프링에서 DAO를 작성해서 처리하는 방식
    ➡️  기존의 DAO에서 SQL의 처리를 MyBatis를 이용하는 구조로써 완전히 MyBatis와 스프링 프레임워크를 독립적인 존재로 바라보고 개발하는 방식
  • MyBatis와 스프링을 연동하고 Mapper 인터페이스만 이용하는 방식
    ➡️  스프링과 MyBatis 사이에 'mybatis-spring'이라는 라이브러리를 이용해서 스프링이 데이터베이스 전체에 대한 처리를 하고
    MyBatis는 일부 기능 개발에 활용하는 방식. 개발 시에는 Mapper 인터페이스라는 방식을 이용해서 인터페이스만으로 모든 개발이 가능

 

2) MyBatis를 위한 라이브러리들


👻  MyBatis를 이용하려면 다음과 같은 라이브러리들이 필요

스프링 관련 : spring-jdbc, spring-tx
MyBatis 관련 : mybatis, mybatis-spring
  ➡️  다른 스프링 관련 라이브러리들과 버전이 같도록 통일해서 추가


    📌  MyBatis 관련 라이브러리는 검색을 이용해서 추가. MyBatis 버젼과 mybatis-spring 라이브러리의 버전은 일치하지 않으므로 주의해서 사용

 



3) MyBatis를 위한 스프링 설정 - SqlSessionFactory


👻  MyBatis를 이용하기 위해서는 스프링에 설정해둔 HikariDataSource를 이용해서 SqlSessionFactory라는 빈을 설정
👻  root-context.xml에 'mybatis-spring' 라이브러리에 있는 클래스를 이용해서 <bean>을 등록

 

 


2. Mapper 인터페이스 활용하기

MyBatis는 SQL 파일을 별도로 처리할 수 있지만 인터페이스와 어노테이션으로도 처리가 가능

 

📌  프로젝트에 mapper라는 이름의 패키지를 구성하고 현재 시간을 처리하는 TimeMapper 인터페이스를 선언

 


🎃  TimeMapper는 데이터베이스의 현재 시각을 문자열로 처리하도록 구성

🎃  MyBatis에는 @Select 어노테이션을 이용해서 쿼리를 작성할 수 있는데, JDBC와 마찬가지로 ";"을 이용하지 않으므로 주의

 

 

 

🎃  작성된 인터페이스를 매퍼(Mapper) 인터페이스라고 하는데 마지막으로 어떠한 매퍼 인터페이스를 설정했는지 root-context.xml에 등록해 주어야 함
🎃 root-context.xml에는 <mybatis:scan> 태그를 이용해서 매퍼 인터페이스의 설정을 추가
🎃  root-context.xml 파일 상단의 xmlns, xsi 설정에 mybatis-spring 관련 설정이 추가 되어야 함.




 

1)  테스트 코드를 통한 확인


👾  test 폴더에 mapper 패키지와 TimeMapperTests 테스트 클래스를 작성해서 확인

import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.junit.jupiter.api.Assertions.*;

@Log4j2
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/root-context.xml")
class TimeMapperTest {
    @Autowired(required = false)
    private TimeMapper timeMapper;

    @Test
    public void testGetTimer() {
        log.info(timeMapper.getTime());
    }

}


  📍  테스트 코드에서는 @Autowired 내에 required 속성을 지정
      ✓  @Autowired(required = false)로 지정하면 해당 객체를 주입 받지 못하도라도 예외가 발생하지 않는데 인텔리제이의 경우@Service, @Repository 와 같이 직접 스프링의 빈으로 등록된 경우가 아니라면 경고가 발생하므로 이를 방지하기 위해서 사용

 


3.  XML로 SQL 분리하기

👩🏻‍💻  MyBatis를 이용할 때 SQL은 @Select와 같은 어노테이션을 이용해서 사용하기도 하지만 대부분은 SQL을 별도의 파일로 분리하는 것을 권장
👩🏻‍💻  XML을 이용하는 이유는 SQL이 길어지면 이를 어노테이션으로 처리하기가 복잡해지고, 어노테이션이 나중에 변경되면 프로젝트 전체를 다시 빌드하는 작업이 필요하기 때문에 단순 파일로 사용하는 것이 편리

 

XML과 매퍼 인터페이스를 같이 결합할 때는 다음과 같은 과정으로 작성
  1. 매퍼 인터페이스를 정의하고 메소드를 선언
  2. 해당 XML 파일을 작성 (파일 이름과 매퍼 인터페이스 이름을 같게)하고 <select>와 같은 태그를 이용해서 SQL을 작성
  3. <select>, <insert> 등의 태그에 id 속성 값을 매퍼 인터페이스의 메소드 이름과 같게 작성



🎃  TimeMapper2 매퍼 인터페이스를 정의
🎃  어노테이션이 없는 getNow() 메서드만을 작성

 

 

 

🎃  main/resources 폴더에 mapper 폴더를 추가

 

🎃  TimeMapper2.xml을 다음과 같이 작성 (매퍼 인터페이스와 같은 이름으로 대소문자 주의)
  ➡️ 스프링 버전이 업그레이드 되면서 인터페이스와 xml의 이름을 똑같이 하지 않아도 됨

  ➡️ 하지만 관리상의 목적으로 매퍼 인터페이스와 xml의 이름을 같게 하기도 함
🎃  <mapper> 태그의 namespace 속성에서 매퍼 인터페이스를 맞게 지정하면 됨
  ➡️ <mapper> 태그의 namespace 속성을 반드시 매퍼 인터페이스의 이름과 동일하게 지정

 

  🎃  <select> 태그는 반드시 resultType이나 resultMap이라는 속성을 지정
         ➡️  resultType은 말 그대로 select 문의 결과를 어떤 타입으로 처리할지에 대한 설정으로 java.lang.String과 같이 전체 이름을 써야 하지만 자주 사용하는 타입은 string과 같이 사용할 수 있음

 


🎃  마지막으로 root-context.xml에 있는 MyBatis 설정에 XML 파일들을 인식하도록 설정을 추가

 

  🎃  추가된 mapperLocations는 말 그대로 'XML 매퍼 파일들의 위치'를 의미
  🎃  resources의 경우 'classpath:' 접두어를 이용해서 인식되는 경로이고 mapper 폴더 밑에 폴더가 있어도 관계없도록 '**'와 모든 '.xml'을 의미라는 '*.xml'을 지정

 

 

📌  XML 설정이 정상적인지 테스트를 통해서 확인. 기존에 만들어진 TimeMapperTests를 이용.



 

 

 

[ 내용 참고 : IT 학원 강의 ]

 

 

+ Recent posts