MyBatis

JdbcTemplate๋ณด๋‹ค ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” SQL Mapper์ด๋‹ค. SQL์„ XML์— ์ž‘์„ฑํ•˜์—ฌ ๋™์  ์ฟผ๋ฆฌ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์„ค์ • build.gradle

implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'

MyBatis๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ณต์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋’ค์— ๋ฒ„์ „ ์ •๋ณด๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

  • ์„ค์ • application.properties(ํ…Œ์ŠคํŠธ ํฌํ•จ)

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์—์„œ ํƒ€์ž… ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ ์–ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ ์—ฌ๊ธฐ์— ๋ช…์‹œํ•˜๋ฉด ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ์ง€์ •ํ•œ ํŒจํ‚ค์ง€์™€ ๊ทธ ํ•˜์œ„ ํŒจํ‚ค์ง€ ์ž๋™ ์ธ์‹. ,,;๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์—ฌ๋Ÿฌ ์œ„์น˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • mybatis.configuration.map-underscore-to-camel-case : ์–ธ๋”๋ฐ”๋ฅผ ์นด๋ฉœ๋กœ ์ž๋™ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•œ๋‹ค.

  • logging.level.hello.itemservice.repository.mybatis=trace : MyBaits์—์„œ ์‹คํ–‰ํ•˜๋Š” ์ฟผ๋ฆฌ ๋กœ๊ทธ ํ™•์ธ

  • ItemMapper ์ธํ„ฐํŽ˜์ด์Šค

@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์„ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋Œ๋ ค์ค€๋‹ค.

  • XMLํŒŒ์ผ(src/main/resources ํ•˜์œ„์— ํŒจํ‚ค์ง€ ์œ„์น˜๋ฅผ ๋งž์ถฐ์•ผ ํ•œ๋‹ค.)

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

namespace์— ์•ž์„œ ๋งŒ๋“  ๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค(ItemMapper)๋ฅผ ์ง€์ •ํ•œ๋‹ค.

  • Config

@Configuration
@RequiredArgsConstructor
public class MyBatisConfig {

    private final ItemMapper itemMapper;

    @Bean
    public ItemService itemService() {
        return new ItemServiceV1(itemRepository());
    }

    @Bean
    public ItemRepository itemRepository() {
        return new MybatisItemRepository(itemMapper);
    }
}

@Slf4j
@Import(MyBatisConfig.class)
@SpringBootApplication(scanBasePackages = "hello.itemservice.web")
public class ItemServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ItemServiceApplication.class, args);
    }
}

ItemMapper ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๊ฐ€ ์—†๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ๋˜๋Š” ๊ฑธ๊นŒ?

img.png
  1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๋”ฉ ์‹œ์ ์— MyBatis ์Šคํ”„๋ง ์—ฐ๋Œ ๋ชจ๋“ˆ์€ @Mapper๊ฐ€ ๋ถ™์–ด์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์กฐ์‚ฌํ•œ๋‹ค.

  2. ํ—ค๋”ฉ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋ฐœ๊ฒฌ๋˜๋ฉด ๋™์  ํ”„๋ก์‹œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ด์„œ ItemMapper ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

  3. ์ƒ์„ฑ๋œ ๊ตฌํ˜„์ฒด๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค.

๋กœ๊ทธ : itemMapper class=class jdk.proxy3.$Proxy111

๋งคํผ ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํ”„๋ง ์˜ˆ์™ธ ์ถ”์ƒํ™”๋„ ํ•จ๊ป˜ ์ ์šฉํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— DataAccessException์— ๋งž๊ฒŒ ์˜ˆ์™ธ ๋ณ€ํ™˜๊นŒ์ง€ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

MyBatis ์Šคํ”„๋ง ์—ฐ๋™ ๋ชจ๋“ˆ์ด DB ์ปค๋„ฅ์…˜, ํŠธ๋žœ์žญ์…˜๊ณผ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ๋„ MyBatis์™€ ํ•จ๊ป˜ ์—ฐ๋™ํ•˜๊ณ  ๋™๊ธฐํ™”๊นŒ์ง€ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ด์ค€๋‹ค.

MyBatis ๋™์  ์ฟผ๋ฆฌ

Last updated