MyBatis는 앞서 설명한 JdbcTemplate보다 더 많은 기능을 제공하는 SQL Mapper 이다. 기본적으로 JdbcTemplate이 제공하는 대부분의 기능을 제공한다.
JdbcTemplate과 비교해서 MyBatis의 가장 매력적인 점은 SQL을 XML에 편리하게 작성할 수 있고 또 동적 쿼리를매우 편리하게 작성할 수 있다는 점이다.
MyBatis는 ORM에 비해 살짝 사장되는 분위기라,, 동적쿼리를 많이 쓴다면 ORM을 쓰면되고, native한 쿼리를 쓰고 싶으면 JdbcTemplate를 쓰면 되기에,, 어떻게 쓰는지 깊게는 안다루고!! 이런 SQL Mapper가 있다 정도만 다뤄볼 생각이다!
나중에 필요할 때가 오면 사용법은 더 깊게 다뤄보자!
MyBatis 의존성을 build.gradle에 추가한후, application.properties에 아래처럼 추가해주면 된다!
#MyBatis
mybatis.type-aliases-package=hello.itemservice.domain // 적용할 패키지
mybatis.configuration.map-underscore-to-camel-case=true // 언더바를 카멜표기법으로 자동 변환
logging.level.hello.itemservice.repository.mybatis=trace // 로그 trace로 남기겠음
package hello.itemservice.repository.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);
}
마이바티스 매핑 XML을 호출해주는 매퍼 인터페이스이다.
이 인터페이스에는 @Mapper 애노테이션을 붙여주어야 한다. 그래야 MyBatis에서 인식할 수 있다.
이 인터페이스의 메서드를 호출하면 다음에 보이는 xml 의 해당 SQL을 실행하고 결과를 돌려준다.

<?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 <= #{maxPrice}
            </if>
        </where>
    </select>
</mapper>
#으로 매핑하고 XML로 동적쿼리를 적어놓을 수 있는 것이 간단(?)한 포인트네!! <if/>, <when> 등등 OGRN이라는 문법을 이용해서 동적쿼리를 작성한다고 함! → 필요하면 그때 더 깊게 알아보자!
인터페이스에 해당하는 쿼리문을 위처럼 XML에 저장중이다!
아래는 @Mapper가 달려있는 itemMapper를 쓰고 있는 MyBatisItemRepository이다!
package hello.itemservice.repository.mybatis;
@Slf4j
@Repository
@RequiredArgsConstructor
public class MyBatisItemRepository implements ItemRepository {
    private final ItemMapper itemMapper;
    @Override
    public Item save(Item item) {
        log.info("itemMapper class={}", itemMapper.getClass());
        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);
    }
}