@Mapper 사용법

2023. 11. 27. 14:28Project/멍뭉케어

우리는 이전 교육 과정에서 DAO 계층에서 sqlSession을 주입받아서 DB에 접근을 하였다. 하지만, @Mapper를 통해 더욱 편리하게 DB에 접근할 수 있는 방법이 있어 팀원들에게 공유하고자 글을 남긴다.

 

 

1. ItemMapper 생성

package hello.itemservice.repository.mybatis;

import hello.itemservice.domain.Item;
import hello.itemservice.repository.ItemSearchCond;
import hello.itemservice.repository.ItemUpdateDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Optional;

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

 

🔹우리가 sqlSession을 의존 주입해서 사용했던 것을 ItemMapper가 대신 해준다고 생각하면 된다. 그리고 여기에 추가적으로 굉장히 편리한 기능을 제공한다. 사용하면서 직접 느껴보도록 하자.

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

🔹위의 인터페이스에는 @Mapper 애노테이션을 붙여야한다. 그래야 MyBatis에서 인식할 수 있다.

🔹위의 인터페이스의 메서드를 호출하면 다음에 보이는 xml의 해당 sql을 실행하고 결과를 돌려준다.

 

2. ItemMapper.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>

🔹namespace는 앞서 만든 매퍼 인터페이스를 지정하면 된다.

🔹id를 @Mapper 인터페이스의 메서드와 일치 시켜야한다.

 

3. @Repository 계층에 적용

package hello.itemservice.repository.mybatis;

import hello.itemservice.domain.Item;
import hello.itemservice.repository.ItemRepository;
import hello.itemservice.repository.ItemSearchCond;
import hello.itemservice.repository.ItemUpdateDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;

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

🔹참고로, @Mapper 어노테이션을 사용하면 빈으로 등록된다고 한다. 직접 테스트를 해보지 않아서, 해본 사람이 잘 되나 체크해주길 바란다.

 

 

4. @Mapper 설정 원리

 

1️⃣ 애플리케이션 로딩 시점에 MyBatis 스프링 모듈은 @Mapper가 붙어있는 인터페이스를 조사한다.

2️⃣ 해당 인터페이스가 발견되면 동적 프록시 기술을 사용해서 ItemMapper 인터페이스의 구현체를 만든다.

3️⃣ 생성된 구현체를 스프링 빈으로 등록한다.

'Project > 멍뭉케어' 카테고리의 다른 글

EC2-MySQL-workbench 연동  (0) 2023.11.23
OAuth2.0  (0) 2023.11.16
INT vs VARCHAR  (1) 2023.11.11
Rest API  (0) 2023.11.08