ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [김영한 스프링] 10. MyBatis - 소개 & 설정
    Spring/스프링 DB 2편 - 데이터 접근 활용 기술 2024. 1. 9. 14:55

    MyBatis 소개

     

     

    MyBatis는 앞서 설명한 JdbcTemplate보다 더 많은 기능을 제공하는 SQL Mapper이다.

    기본적으로 JdbcTemplate이 제공하는 대부분의 기능을 제공한다.

    JdbcTemplate과 비교해서 MyBatis의 가장 매력적인 점은 SQL을 XML에 편리하게 작성할 수 있고 또 동적 쿼리를 매우 편리하게 작성할 수 있다는 점이다.

     

    먼저 SQL이 여러 줄에 걸쳐 있을 때 둘을 비교해 보자.

     

     

    JdbcTemplate - SQL 여러 줄

    String sql = "update item " +
        "set item_name=:itemName, price=:price, quantity=:quantity " +
        "where id=:id";

     

     

    MyBatis - SQL 여러 줄

    <update id="update">
        update item
           set item_name = #{itemName}
             , price = #{price}
             , quantity = #{quantity}
         where id = #{id}
    </update>

    MyBatis는 XML에 작성하기 때문에 라인이 길어져도 문자 더하기에 대한 불편함이 없다.

     

    다음으로 상품을 검색하는 로직을 통해 동적 쿼리를 비교해 보자.

     

    JdbcTemplate - 동적 쿼리

    String sql = "select id, item_name, price, quantity from item";
    
    //동적 쿼리
    if (StringUtils.hasText(itemName) || maxPrice != null) {
        sql += " where";
    }
    
    boolean andFlag = false;
    if (StringUtils.hasText(itemName)) {
        sql += " item_name like concat('%',:itemName,'%')";
        andFlag = true;
    }
    
    if (maxPrice != null) {
        if (andFlag) {
            sql += " and";
        }
        
        sql += " price <= :maxPrice";
    }
    
    log.info("sql={}", sql);
    
    return template.query(sql, param, itemRowMapper());

     

     

    MyBatis - 동적 쿼리

    <select id="findAll" resultType="Item">
        select id, item_name, price, quantity
          from item
         <where>
          <if test="itemName != null and itemName != ''">
           and item_name like concat('%',#{itemName},'%')
          </if>
          <if test="maxPrice != null">
           and price &lt;= #{maxPrice}
          </if>
         </where>
    </select>

    JdbcTemplate은 자바 코드로 직접 동적 쿼리를 작성해야 한다. 반면에 MyBatis는 동적 쿼리를 매우 편리하게 작성할 수 있는 다양한 기능들을 제공해 준다.

     

     

    설정의 장단점

    JdbcTemplate은 스프링에 내장된 기능이고, 별도의 설정 없이 사용할 수 있다는 장점이 있다. 반면에 MyBatis는 약간의 설정이 필요하다.

     

     

    정리

    프로젝트에서 동적 쿼리와 복잡한 쿼리가 많다면 MyBatis를 사용하고, 단순한 쿼리들이 많으면 JdbcTemplate을 선택해서 사용하면 된다. 물론 둘을 함께 사용해도 된다. 하지만 MyBatis를 선택했다면 그것으로 충분할 것이다.

     

     

    참고
    강의에서는 MyBatis의 기능을 하나하나를 자세하게 다루지는 않는다. MyBatis를 왜 사용하는지, 그리고 주로 사용하는 기능 위주로 다룰 것이다. 그래도 이 강의를 듣고 나면 MyBatis로 개발을 할 수 있게 되고 추가로 필요한 내용을 공식 사이트에서 찾아서 사용할 수 있게 될 것이다.
    MyBatis는 기능도 단순하고 또 공식 사이트가 한글로 잘 번역되어 있어서 원하는 기능을 편리하게 찾아볼 수 있다.

    공식 사이트
    https://mybatis.org/mybatis-3/ko/index.html

     

     

    MyBatis 설정

     

     

    mybatis-spring-boot-starter 라이브러리를 사용하면 MyBatis를 스프링과 통합하고, 설정도 아주 간단히 할 수 있다.

    mybatis-spring-boot-starter 라이브러리를 사용해서 간단히 설정하는 방법을 알아보자.

     

     

    build.gradle

    //MyBatis 추가
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
    • 참고로 뒤에 버전 정보가 붙는 이유는 스프링 부트가 버전을 관리해 주는 공식 라이브러리가 아니기 때문이다. 스프링 부트가 버전을 관리해 주는 경우 버전 정보를 붙이지 않아도 최적의 버전을 자동으로 찾아준다.

     

    참고 - 스프링 부트 3.0 이상
    스프링 부트 3.0 이상을 사용한다면 mybatis-spring-boot-starter 버전을 2.2.0 대신에 3.0.1을 사용해야 한다.
    // MyBatis 스프링 부트 3.0 추가
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.1'

     

     

    build.gradle - 의존관계 전체

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        
        //JdbcTemplate 추가
        implementation 'org.springframework.boot:spring-boot-starter-jdbc'
        //MyBatis 추가
        implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
        
        //H2 데이터베이스 추가
        runtimeOnly 'com.h2database:h2'
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        
        //테스트에서 lombok 사용
        testCompileOnly 'org.projectlombok:lombok'
        testAnnotationProcessor 'org.projectlombok:lombok'
    }
    • mybatis-spring-boot-starter : MyBatis를 스프링 부트에서 편리하게 사용할 수 있게 시작하는 라이브러리
    • mybatis-spring-boot-autoconfigure : MyBatis와 스프링 부트 설정 라이브러리
    • mybatis-spring : MyBatis와 스프링을 연동하는 라이브러리
    • mybatis : MyBatis 라이브러리

     

     

    설정

    application.properties에 다음 설정을 추가하자. #MyBatis를 참고하면 된다.

     

    주의!
    웹 애플리케이션을 실행하는 main, 테스트를 실행하는 test 각 위치의 application.properties를 모두 수정해주어야 한다. 설정을 변경해도 반영이 안 된다면 이 부분을 꼭! 확인하자.

     

     

    main - application.properties

    spring.profiles.active=local
    spring.datasource.url=jdbc:h2:tcp://localhost/~/test
    spring.datasource.username=sa
    
    logging.level.org.springframework.jdbc=debug
    
    #MyBatis
    mybatis.type-aliases-package=hello.itemservice.domain
    mybatis.configuration.map-underscore-to-camel-case=true
    logging.level.hello.itemservice.repository.mybatis=trace

     

     

    test - application.properties

    spring.profiles.active=test
    #spring.datasource.url=jdbc:h2:tcp://localhost/~/testcase
    #spring.datasource.username=sa
    
    logging.level.org.springframework.jdbc=debug
    
    #MyBatis
    mybatis.type-aliases-package=hello.itemservice.domain
    mybatis.configuration.map-underscore-to-camel-case=true
    logging.level.hello.itemservice.repository.mybatis=trace
    • mybatis.type-aliases-package
      • 마이바티스에서 타입 정보를 사용할 때는 패키지 이름을 적어주어야 하는데, 여기에 명시하면 패키지 이름을 생략할 수 있다.
      • 지정한 패키지와 그 하위 패키지가 자동으로 인식된다.
      • 여러 위치를 지정하려면 ,와 ;로 구분하면 된다.
    • mybatis.configuration.map-underscore-to-camel-case
      • JdbcTemplate의 BeanPropertyRowMapper에서 처럼 언더바를 카멜로 자동 변경해 주는 기능을 활성화한다. 바로 다음에 설명하는 관례의 불일치 내용을 참고하자.
    • logging.level.hello.itemservice.repository.mybatis=trace
      • MyBatis에서 실행되는 쿼리 로그를 확인할 수 있다.

     

     

    관례의 불일치

    자바 객체에는 주로 카멜(camelCase) 표기법을 사용한다. itemName처럼 중간에 낙타 봉이 올라와 있는 표기법이다.

    반면에 관계형 데이터베이스에서는 주로 언더스코어를 사용하는 snake_case 표기법을 사용한다. item_name처럼 중간에 언더스코어를 사용하는 표기법이다.

    이렇게 관례로 많이 사용하다 보니 map-underscore-to-camel-case 기능을 활성화하면 언더스코어 표기법을 카멜로 자동 변환해 준다. 따라서 DB에서 select item_name으로 조회해도 객체의 itemName(setItemName()) 속성에 값이 정상 입력된다.

    정리하면 해당 옵션을 켜면 snake_case는 자동으로 해결되니 그냥 두면 되고, 컬럼 이름과 객체 이름이 완전히 다른 경우에는 조회 SQL에서 별칭을 사용하면 된다.

     

    예)

    • DB select item_name
    • 객체 name

     

    별칭을 통한 해결방안

    select item_name as name

     

     

    출처 :  https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-2/dashboard

     

    스프링 DB 2편 - 데이터 접근 활용 기술 강의 - 인프런

    백엔드 개발에 필요한 DB 데이터 접근 기술을 활용하고, 완성할 수 있습니다. 스프링 DB 접근 기술의 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 백엔드 개발자

    www.inflearn.com

Designed by Tistory.