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=tracemybatis.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 <= #{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 ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๊ฐ ์๋๋ฐ ์ด๋ป๊ฒ ๋๋ ๊ฑธ๊น?

์ ํ๋ฆฌ์ผ์ด์ ๋ก๋ฉ ์์ ์
MyBatis์คํ๋ง ์ฐ๋ ๋ชจ๋์@Mapper๊ฐ ๋ถ์ด์๋ ์ธํฐํ์ด์ค๋ฅผ ์กฐ์ฌํ๋ค.ํค๋ฉ ์ธํฐํ์ด์ค๊ฐ ๋ฐ๊ฒฌ๋๋ฉด ๋์ ํ๋ก์ ๊ธฐ์ ์ ์ฌ์ฉํด์
ItemMapper์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ฅผ ๋ง๋ ๋ค.์์ฑ๋ ๊ตฌํ์ฒด๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค.
๋ก๊ทธ : itemMapper class=class jdk.proxy3.$Proxy111
๋งคํผ ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ์คํ๋ง ์์ธ ์ถ์ํ๋ ํจ๊ป ์ ์ฉํด ์ฃผ๊ธฐ ๋๋ฌธ์ DataAccessException์ ๋ง๊ฒ ์์ธ ๋ณํ๊น์ง ์ฒ๋ฆฌํด์ค๋ค.
MyBatis ์คํ๋ง ์ฐ๋ ๋ชจ๋์ด DB ์ปค๋ฅ์
, ํธ๋์ญ์
๊ณผ ๊ด๋ จ๋ ๊ธฐ๋ฅ๋ MyBatis์ ํจ๊ป ์ฐ๋ํ๊ณ ๋๊ธฐํ๊น์ง ์๋์ผ๋ก ์ค์ ํด์ค๋ค.
Last updated