새소식

framework/spring

[Spring] 마이바티스(MyBatis)

  • -

마이바티스(MyBatis)

마이바티스(MyBatis)는 SQL을 XML에 편리하게 작성할 수 있는 SQL Mapper이다.

사용 설정

build.gradle에 의존 관계를 추가한다.

dependencies {
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0' 
}

application.yml에 다음 내용을 추가한다.

mybatis:
  type-aliases-package: com.example.dbaccess.domain
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: classpath:mapper/**/*.xml

logging:
  level:
    com.example.dbaccess.repository.mybatis: trace
  • mybatis.type-aliases-package
    • 마이바티스에서 타입 정보를 사용할 때는 패키지 이름을 명시해야 한다.
    • 여기에 패키지 이름을 명시하면 XML에서 패키지 이름을 생략할 수 있다.
    • 지정한 패키지와 그 하위 패키지가 자동으로 인식된다.
    • 여러 위치를 지정하려면 ,, ;로 구분한다.
  • mybatis.configuration.map-underscore-to-camel-case
    • snake_casecamelCase로 자동 변경해주는 기능을 활성화 한다.
  • mybatis.mapper-locations
    • mapper.xml 파일들의 경로를 지정한다.
    • 따로 명시하지 않으면 프로젝트의 XxxMapper 인터페이스와 같은 경로에 위치해야 인식한다.

마이바티스 적용

XxxMapper 인터페이스 작성

마이바티스 매핑 XML을 호출해주는 Mapper 인터페이스를 작성한다.
해당 인터페이스에는 @Mapper 어노테이션을 붙여 마이바티스에서 인식할 수 있도록 해줘야 한다.
@Mapper 어노테이션을 붙여주면 MyBatis 스프링 연동 모듈은 애플리케이션 로딩 시점에 @Mapper 애노테이션이 붙은 인터페이스를 찾아 동적 프록시 기술을 사용하여 구현체를 만들고 스프링 빈으로 등록한다.

@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);
}

XxxMapper.xml 작성

이제 작성한 매퍼 인터페이스에서 어떤 SQL을 실행할 지 지정해야 한다.
XxxMapper.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="com.example.dbaccess.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>

XxxMapper.xml 작성 방법

매퍼 선언

<mapper namespace="com.example.dbaccess.repository.mybatis.ItemMapper">

</mapper>

<mapper> 태그를 선언하고 해당 태그의 namespace 속성에 어떤 매퍼 인터페이스에 사용될지 지정한다.
패키지 이름까지 모두 작성한다.

이후 <mapper> 태그 안에 SQL을 작성하면 된다.

파라미터 매핑

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

파라미터 매핑을 위해서는 #{}를 사용한다.
#{} 내부에 매퍼 인터페이스에서 @Param을 통해 넘긴 파라미터 이름을 지정한다.

예를 들어 다음과 같은 매퍼 인터페이스가 있다고 하자.

@Mapper
public interface ItemMapper {
    void update(@Param("id") Long id, @Param("updateParam") ItemUpdateDto updateParam);
}

해당 매퍼 인터페이스에서는 @Param을 통해 파라미터 이름을 명시해준다.
이를 사용하는 XML에서는 다음과 같이 작성하여 사용할 수 있다.

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

파라미터가 1개라면 @Param을 지정하지 않아도 된다.
파라미터로 객체 하나를 넘긴다면 객체의 프로퍼티 이름을 지정하면 된다.

INSERT

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

Insert SQL은 <insert>를 사용한다.
id 속성에는 매퍼 인터페이스에 설정한 메서드 이름을 지정한다.
useGeneratedKeys 속성은 데이터베이스가 키를 생성해주는 전략일 때 사용한다.
keyProperty 속성은 생성되는 키의 속성 이름을 지정한다.
이렇게 자동 생성 컬럼을 지정해주면 Insert SQL 수행 이후, keyProperty에 지정한 속성에 생성된 값이 입력된다.

UPDATE

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

Update SQL은 <update>를 사용한다.
id 속성에는 매퍼 인터페이스에 설정한 메서드 이름을 지정한다.

SELECT

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

Select SQL은 <select>를 사용한다.
id 속성에는 매퍼 인터페이스에 설정한 메서드 이름을 지정한다.
resultType 속성에는 반환 타입을 명시한다.
application.yml에서 mybatis.type-aliases-package를 지정하지 않았다면 모든 패키지 이름을 함께 작성해야 한다.

동적 쿼리

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

where절 동적 쿼리를 작성하기 위해 <where> 태그와 <if> 태그를 사용한다.
<if> 태그는 test 속성에 작성한 조건이 만족하면 태그 내부에 작성한 구문을 SQL에 추가한다.
<where> 태그는 태그 내부에 작성한 <if>가 모두 만족하지 않으면 where 절을 작성하지 않는다.
하나라도 만족되면 <if> 태그에서 처음 나타나는 andwhere로 변환하여 where절을 만들어 준다.

이 외에도 컬렉션 반복 처리를 위한 <foreach>, 자바의 switch 구문과 유사한 <choose>, <when>, <otherwise> 등이 있다.
마이바티스 동적 쿼리 공식 문서 확인

[Spring] 마이바티스(MyBatis)

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.