BackEnd/Database

MyBatis

연향동큰손 2025. 2. 8. 16:12

MyBatis는 Java에서 SQL을 보다 쉽게 다룰 수 있도록 도와주는 ORM 프레임워크이다.

 

MyBatis는 기존의 JDBC보다 간편하게 데이터베이스와 연동할 수 있도록 SQL 매핑을 지원하며, XML 또는 애노테이션을 사용해 SQL을 작성할 수 있다.

 

MyBatis의 장단점

 

장점

  • 동적 쿼리를 편리하게 작성할 수 있다.
  • 커넥션,트랜잭션과 관련된 기능을 MyBatis 스프링 연동 모듈이 자동으로 설정해준다.

단점

  • 설정이 다소 복잡할 수 있다.

 

MyBatis 사용

 

 

1. ItemMapper 생성

 

ItemMapper는 마이바티스 매핑 XML을 호출해주는 매퍼 인터페이스이다.

 

SQL을 XML로 작성하면 @Mapper가 있는 인터페이스에 SQL을 자동으로 매핑시켜준다.

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); //파라미터가 2개이상인 경우 @Param사용

    List<Item> findAll(ItemSearchCond itemSearchCond);

    Optional<Item> findById(Long id);

}

 

 

2. SQL 작성

 

주의 : 자바 코드가 아니기 때문에  src/main/resources 하위에 만들되, 패키지 위치는 맞추어 주어야 한다.

 

단, XML 파일을 원하는 곳에 두고 싶으면 application.properties에 다음과 같이 수정해주면 된다.

mybatis.mapper-locations=classpath:mapper/**/*.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>

 

XML에서는 비교 연산자와 같은 특수 문자를 사용할 수 없다.

 

따라서 XML에서 지원하는 CDATA 구문 문법을 사용하면 된다.

< : &lt;
 > : &gt;
 & : &amp;

 

 

3. 리포지토리 인터페이스 구현체 생성

 

이 클래스는 단순히 리포지토리의 기능을 ItemMapper에 위임하는 역할을 한다.

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

 

코드를 보면 JdbcTemplate를 사용할 때 보다 훨씬 더 코드가 간결해진 것을 확인할 수 있다.

 

 

 

3. ItemMapper를 빈으로 등록

package hello.itemservice.config;


import hello.itemservice.repository.ItemRepository;
import hello.itemservice.repository.jdbcTemplateIte.JdbcTemplateRepositoryV3;
import hello.itemservice.repository.mybatis.ItemMapper;
import hello.itemservice.repository.mybatis.MyBatisItemRepository;
import hello.itemservice.service.ItemService;
import hello.itemservice.service.ItemServiceV1;
import lombok.RequiredArgsConstructor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
@RequiredArgsConstructor
@MapperScan(basePackages = "hello.itemservice.repository.mybatis")
public class MyBatisConfig {

    private final ItemMapper itemMapper;

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

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

 

 

애노테이션 기반 SQL 작성

 

XML 대신 애노테이션에 SQL을 작성하는 것도 가능하다.

 @Select("select id, item_name, price, quantity from item where id=#{id}")
 Optional<Item> findById(Long id);

 

주의 : XML의 SQL에 동일한 쿼리가 존재하면 충돌이 발생하므로 제거해야 한다.

 

애노테이션 기반 SQL은 동적 SQL이 해결되지 않으므로 간단한 SQL에만 적용하는 것이 좋다.

 

 

 

MyBatis 관련 자세한 기술은 메뉴얼 참고

마이바티스 3 | 소개 – mybatis

 

마이바티스 3 | 소개 – mybatis

마이바티스는 무엇인가? 마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다. 마이바티스는 JDBC로 처리하는 상당부분의 코드와

mybatis.org

 

 

'BackEnd > Database' 카테고리의 다른 글

QueryDSL  (1) 2025.02.10
Spring Data JPA  (0) 2025.02.10
DB Test[@Transactional, 임베디드 모드 DB]  (0) 2025.02.07
JdbcTemplate  (0) 2025.02.07
JDBC를 이용한 반복문제 해결 - JdbcTemplate  (0) 2025.02.04