이 영역을 누르면 첫 페이지로 이동
시간의화살 블로그의 첫 페이지로 이동

시간의화살

페이지 맨 위로 올라가기

시간의화살

행복하세요

[Spring Database] MyBatis

  • 2022.09.09 14:39
  • Spring/Spring Database

 

 

 

MyBatis는 JdbcTemplate가 제공하는 대부분의 기능을 제공한다.

SQL을 XML을 통해 관리하고, 동적 쿼리 문제를 쉽게 해결할 수 있다는 장점이 있다.

 

프로젝트에서 동적 쿼리와 복잡한 쿼리가 많이 사용된다면 MyBatis를 사용하는 편이 합리적이고, 단순한 쿼리가 대부분이면 JdbcTemplate을 사용하는 것도 괜찮다.

 

 

#MyBatis
mybatis.type-aliases-package=hello.itemservice.domain
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.hello.itemservice.repository.mybatis=trace

 

application.properties에 MyBatis 관련 내용을 추가해주자.

패키지 정보로 타입 정보를 사용하고, 표기 관례를 맞춰주는 설정이다.

 

 

@Mapper
public interface ItemMapper {

    void save(Item item);
    void update(@Param("id") Long id, @Param("updateParam") ItemUpdateDto updateParam);
    
    Optional<Item> findById(Long id);
    List<Item> findAll(ItemSearchCond itemSearch);
}

 

 

MyBatis 매핑 XML을 호출해주는 매퍼 인터페이스이다.

 

@Mapper 애너테이션을 붙여서 MyBatis가 인식 할 수 있도록 하고, 인터페이스의 메서드를 호출하면 xml의 해당 SQL을 실행한다. 

 

인터페이스의 구현체는 @Mapper 애너테이션이 붙어있으면 알아서 만들어진다.

 

여기서 객체를 하나만 가져올 때는 @Param 애너테이션을 생략해도 되지만, update 메서드처럼 두 개 이상을 가져올 때는 생략할 수 없다.

 

 

해당 인터페이스의 디렉토리와 동일한 방식으로 resources에 디렉토리를 생성하고, xml 파일도 생성한다.

 

xml 파일을 원하는 위치에 두려면 application.properties 파일을 수정해야 한다.

mybatis.mapper-locations=classpath:mapper/**/*.xml

이렇게 설정 해 주면 resources/mapper 하위 폴더의 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="hello.itemservice.repository.mybatis.ItemMapper">

    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into item (item_name, price, quantity)
        values (#{itemName}, #{price}, #{quantity})
    </insert>

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

    <select id="findById" resultType="Item">
        select id, item_name, price, quantity
        from item
        where id = #{id}
    </select>

    <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>
    
</mapper>

 

 

MyBatis는 SQL을 xml 형식으로 관리한다.

 

namespace에는 아까 만든 인터페이스를 지정해주고 인터페이스의 메서드에 해당하는 SQL을 하나하나 작성하자.

 

insert SQL은 <insert> 태그를 사용해서 구현한다.

SQL의 파라미터들은 #{} 문법과 ItemMapper 인터페이스에서 넘긴 객체의 프로퍼티 이름을 사용해 처리한다.

(#{} 문법은 내부적으로 PreparedStatement를 사용한다)

 

#바인딩과 $바인딩이 있는데..

 

#바인딩 시 SQL Injection 공격을 막을 수 있고 소프트파싱을 사용할 수 있어 성능이 최적화 할 수 있으니 특별한 경우가 아니면 #바인딩을 사용하는 편이 합리적이다.

 

useGeneratedKeys는 데이터베이스가 키를 생성해야 할 때 사용하고, keyProperty는 생성되는 키의 이름을 지정 할 때 사용한다.

 

 

update SQL은 <update> 태그를 사용하고, select SQL은 <select> 태그를 사용해서 구현한다.

 

resultType으로 반환 타입을 명시할 때 사용하는데, application.properties 파일에 패키지 관련 정보를 추가해 줘서 모든 패키지 명을 다 적지 않아도 된다.

결과 반환 시 RowMapper 처럼 select SQL의 결과를 객체로 바로 변환해준다.

 

findAll을 구현 할 때는 동적 쿼리를 사용한다.

 

<if> 태그는 해당 조건이 만족하면 구문을 추가하고, <where> 태그는 SQL 문법에 맞도록 where 문장을 만들어준다.

 

xml을 작성할 때는 태그와 특수문자를 구분하기 위해 $lt 와 같은 이스케이프 문자를 사용하거나 CDATA 문법을 사용한다.

 

 

@Repository
@RequiredArgsConstructor
public class MyBatisItemRepository implements ItemRepository {
    private final ItemMapper itemMapper;
    @Override
    public Item save(Item item) {
        itemMapper.save(item);
        return item;
    }
    @Override
    public void update(Long itemId, ItemUpdateDto updateParam) {
        itemMapper.update(itemId, updateParam);
    }
    @Override
    public Optional<Item> findById(Long id) {
        return itemMapper.findById(id);
    }
    @Override
    public List<Item> findAll(ItemSearchCond cond) {
        return itemMapper.findAll(cond);
    }
}

 

MyBatisItemRepository 는 ItemMapper의 구현체에 기능을 위임한다.

 

 

 

 

 

 

@Mapper 애너테이션으로 구현체를 만드는 과정을 자세히 살펴보자.

 

애플리케이션이 로딩 될 때 MyBatis 스프링 연동 모듈은 @Mapper 애너테이션이 붙어있는 인터페이스를 조사하고, 동적 프록시 기술을 사용해 ItemMapper 인터페이스의 구현체를 만든다.

(구현체는 스프링 빈으로 등록되고, 예외 변환도 처리해준다)

 

Mapper 구현체 덕분에 MyBatis를 스프링에 통합해서 사용할 수 있다.

 

이 외에도 MyBatis를 사용하면 동적 쿼리를 쉽게 설계하거나 애너테이션으로 간단한 SQL을 설계하는 등 여러 가지 편리한 기능을 사용할 수 있다.

반응형
저작자표시 (새창열림)

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

[Spring Database] JPA 적용  (0) 2022.09.10
[Spring Database] JPA  (1) 2022.09.09
[Spring Database] 데이터베이스 테스트  (2) 2022.09.07
[Spring Database] JdbcTemplate  (0) 2022.09.06
[Spring Database] 데이터베이스 예외 처리  (0) 2022.09.05

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Spring Database] JPA 적용

    [Spring Database] JPA 적용

    2022.09.10
  • [Spring Database] JPA

    [Spring Database] JPA

    2022.09.09
  • [Spring Database] 데이터베이스 테스트

    [Spring Database] 데이터베이스 테스트

    2022.09.07
  • [Spring Database] JdbcTemplate

    [Spring Database] JdbcTemplate

    2022.09.06
다른 글 더 둘러보기

정보

시간의화살 블로그의 첫 페이지로 이동

시간의화살

  • 시간의화살의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (605)
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • Java (19)
      • JavaScript (15)
      • C (25)
      • C++ (12)
      • Python (1)
      • PHP (2)
    • Computer Science (68)
      • Operating System (18)
      • Computer Network (16)
      • System Programming (22)
      • Universial Programming Lang.. (8)
      • Computer Architecture (4)
    • Database (21)
      • Database (7)
      • MySQL (3)
      • Oracle (3)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Github Actions (0)
      • Amazon Web Service (8)
    • Machine Learning (28)
      • AI Introduction (28)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • Solutions (13)
    • Life Logs (0)
    • 낙서장 (25)

최근 글

나의 외부 링크

메뉴

  • 홈

정보

13months의 시간의화살

시간의화살

13months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © 13months.

티스토리툴바