본문 바로가기
데이터 접근 기술/MyBatis

MyBatis 소개

by oncerun 2022. 10. 14.
반응형

 

MyBatis

 

MyBatis는 SQL Mapper의 하나로 스프링에서 제공해주는 JdbcTemplate보다 더 많은 기능을 제공해준다. 

 

학원 및 회사에서 접했던 MyBatis의 장점을 꼽으면 SQL을 로직과 분리하는 정책을 삼으면 SQL을 따로 관리할 수 있어 관리성에 있어서 매우 편리했고, 동적 쿼리에 대한 문제를 손쉽게 처리하여 작성할 수 있었다. 

 

MyBatis에 대한 깊은 지식 습득이 목표가 아닌 MyBatis의 간단한 사용법, 사용목적, 장단점을 파악하는 용도로만 공부할 예정이다. 

 

간단히 XML에 작성된 쿼리를 살펴보자

 

<update id = "update">

  update item 
     set item_name = #{itemName},
         price     = #{price},
         quantity  = #{quantity}
   where id        = #{id}
   
</update>

XML에 작성한다는 것은 기존의 String 형식으로 SQL을 작성했던 것보다 안전성을 챙길 수 있다. 

 

또한 MyBatis가 처리하는 동적 쿼리는 다음과 같다. 

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

 

MyBatis를 통해 처리하는 동적 쿼리를 보면 기존 jdbcTemplate을 통해 처리하는 동적 쿼리랑 차이가 존재한다. 

 

도움을 주는 태그들을 이용해 더욱 쉽게 sql문을 작성할 수 있기에 가독성이 뛰어나고 로직에 동적 쿼리를 처리하는 로직이 빠짐으로써 DAO 계층의 로직이 더욱 가독성이 좋아진다. 

 

하지만 처음 MyBatis를 사용하는 사람에게는 추가적인 문법을 공부해야 하고 약간의 설정이 필요하다. 

이와 반대로 JdbcTemplate 같은 경우에는 스프링에 내장된 기능으로 별도의 설정 없이 편리하게 사용할 수 있다는 장점이 있다. 

 

MyBatis – 마이바티스 3 | 소개

 

MyBatis – 마이바티스 3 | 소개

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

mybatis.org

 

 

MyBatis 설정

 

MyBatis는 spring이 공식적으로 관리하지 않는 라이브러리이기에 적절한 버전의 라이브러리를 추가해야 한다.

 

org.mybatis.spring.boot:mybatis-spring-boot-stater:2.2.0

 

  • mybatis-spring-boot-starter : MyBatis를 스프링 부트에서 편리하게 사용할 수 있게 시작하는 라이브러리
  • mybatis-spring-boot-autoconfigure : MyBatis와 스프링 부트 설정 라이브러리
  • mybatis-spring : MyBatis와 스프링을 연동하는 라이브러리
  • mybatis : MyBatis 라이브러리

 

이후 편리하게 사용하기 위해 application.properties에 추가하는 설정이 존재한다. 

 

https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

 

mybatis-spring-boot-autoconfigure – Introduction

Introduction What is MyBatis-Spring-Boot-Starter? The MyBatis-Spring-Boot-Starter help you build quickly MyBatis applications on top of the Spring Boot. By using this module you will achieve: Build standalone applications Reduce the boilerplate to almost z

mybatis.org

 

해당 화면을 참고해 필요한 부분의 설정을 application.properties 할 수 있으니 참고 하자. 

다만 XML을 통한 셋팅을 진행할 때는 다음 doc를 참고하면 된다.

MyBatis – 마이바티스 3 | 매퍼 설정

 

MyBatis – 마이바티스 3 | 매퍼 설정

매퍼 설정 마이바티스 XML 설정파일은 다양한 설정과 프로퍼티를 가진다. 문서의 구조는 다음과 같다.: configuration properties 이 설정은 외부에 옮길 수 있다. 자바 프로퍼티 파일 인스턴스에 설정할

mybatis.org

 

 

XML 사용

 

마이바티스는 XML을 호출해주는 인터페이스가 필요하다. 

이 인터페이스에 @Mapper라는 어노테이션을 붙여주어야 하는데 이래야 Mybatis가 인식할 수 있기 때문이다. 

@Mapper
public interface ItemMapper {

    void save(Item item);

    void update(@Param("id") Long id, @Param("updateParam") ItemUpdateDto updateParam);

    List<Item> findAll(ItemSearchCond itemSearch);

    Optional<Item> findById(Long id);

}

해당 인터페이스의 메서드를 호출하면 다음과 같이 작성된 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 &lt;= #{maxPrice}
 	</if>
	</where>
  </select>
     
</mapper>

 

다만 xml의 위치는 interface가 존재하는 패키지 명에 맞춘 디렉터리 구조로 resource에 만들어주면 된다. 

만약  XML 파일을 원하는 위치에 두고 싶으면 application.properties 에 다음과 같이 설정하면 된다.

 

mybatis.mapper-locations=classpath:mapper/**/*. xml 

 

이렇게 하면 resources/mapper를 포함한 그 하위 폴더에 있는 XML을 XML 매핑 파일로 인식한다.

이 경우 파일 이름은 자유롭게 설정해도 된다.

참고로 테스트의 application.properties 파일도 함께 수정해야 테스트를 실행할 때 인식할 수 있다.

 

 

 

 

MyBatis 스프링 연동 모듈이 구현체를 자동으로 만들어주는 부분의 그림이다.

 

실제로 MyBatis를 사용하면 인터페이스만을 정의하지 실제 구현체를 만들진 않는데, 바로 위와 같은 구조를 띤다. 

 

1. 로딩 시점에 @Mapper가 있는 인터페이스 스캔

2. 해당 인터페이스 발견 시 동적 프록시 기술로 구현체를 생성

3. 생성된 구현체를 빈으로 등록

 

동적 SQL

 

1) if

 

 조건에 따라 값을 추가할지 말지 판단한다. 

 

<if test = 조건>

  and title like #{title}

</if>

 

2) choose, when, otherwise

<select id="findActiveBlogLike"
 resultType="Blog">
 SELECT * FROM BLOG WHERE state = ‘ACTIVE’
 <choose>
 <when test="title != null">
 AND title like #{title}
 </when>
 <when test="author != null and author.name != null">
 AND author_name like #{author.name}
 </when>
 <otherwise>
 AND featured = 1
 </otherwise>
 </choose>
</select>

자바의 swich구문과 비슷하다. 

 

3) <where>

 

<select id="findActiveBlogLike"
 resultType="Blog">
 SELECT * FROM BLOG
 <where>
 <if test="state != null">
 state = #{state}
 </if>
 <if test="title != null">
 AND title like #{title}
 </if>
 <if test="author != null and author.name != null">
 AND author_name like #{author.name}
 </if>
 </where>
</select>

 

<where>는 문장이 없으면 where 를 추가하지 않는다.

문장이 있으면 where 를 추가한다. 만약 and 가 먼저 시작된다면 and를 지운다.

 

4) foreach

 

<select id="selectPostIn" resultType="domain.blog.Post">
 SELECT *
 FROM POST P
 <where>
 <foreach item="item" index="index" collection="list"
 open="ID in (" separator="," close=")" nullable="true">
 #{item}
 </foreach>
 </where>
</select>

컬렉션을 반복 처리할 때 사용한다.

where in (1,2,3,4,5,6) 와 같은 문장을 쉽게 완성할 수 있다.

파라미터로 List 를 전달하면 된다.

 

 

동적 쿼리에 대한 자세한 내용은 다음을 참고하자. 

https://mybatis.org/mybatis-3/ko/dynamic-sql.html

 

MyBatis – 마이바티스 3 | 동적 SQL

동적 SQL 마이바티스의 가장 강력한 기능 중 하나는 동적 SQL을 처리하는 방법이다. JDBC나 다른 유사한 프레임워크를 사용해본 경험이 있다면 동적으로 SQL 을 구성하는 것이 얼마나 힘든 작업인지

mybatis.org

 

자주 사용하는 기능

 

1) XML에 쿼리를 작성하는 것 대신 @Select... 등 어노태이션을 사용해 SQL을 작성할 수 있다. 

 

다만 XML을 사용하여  SQL을 분리하는 목적에는 맞지않아 아주 간단한 경우 아니면 사용하지 않는다.

 

애노테이션으로 SQL 작성에 대한 더 자세한 내용은 다음을 참고하자.

https://mybatis.org/mybatis-3/ko/java-api.html

 

MyBatis – 마이바티스 3 | 자바 API

자바 API 이제 마이바티스를 설정하는 방법과 매핑을 만드는 방법을 알게 되었다. 이미 충분히 잘 사용할 준비가 된 셈이다. 마이바티스 자바 API 는 당신의 노력에 대한 보상을 얻게 할 것이다. JD

mybatis.org

 

 

2) 파라미터의 값을 문자열 그대로 사용하고 싶은경우

 

#{} 문법 대신 ${}을 통해 문자열 그대로를 사용할 수 있다.

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String

 

하지만 이 경우에 SQL 인젝션 공격에 취약해진다.

 

3) Result Maps

 

결과를 매핑할 때 테이블은 user_id이지만 객체는 id이다.

이 경우 칼럼명과 객체의 프로퍼티 명이 다르다. 그러면 다음과 같이 별칭( as )을 사용하면 된다.

 

<select id="selectUsers" resultType="User">
 select
 user_id as "id",
 user_name as "userName",
 hashed_password as "hashedPassword"
 from some_table
 where id = #{id}
</select>

이 경우 별칭을 사용하지 않고 해결할 수 있는데, 그 방법이 resultMap을 통한 방법이다.

 

<resultMap id="userResultMap" type="User">
 <id property="id" column="user_id" />
 <result property="username" column="username"/>
 <result property="password" column="password"/>
</resultMap>
<select id="selectUsers" resultMap="userResultMap">
 select user_id, user_name, hashed_password
 from some_table
 where id = #{id}
</select>

 

복잡한 결과 매핑 MyBatis도 매우 복잡한 결과에 객체 연관관계를 고려해서 데이터를 조회하는 것이 가능하다.

 

이때는 <association>, <collection> 등을 사용한다.

이 부분은 성능과 실효성에서 측면에서 많은 고민이 필요하다.

 

JPA는 객체와 관계형 데이터베이스를 ORM 개념으로 매핑하기 때문에 이런 부분이 자연스럽지만,

MyBatis에서는 들어가는 공수도 많고, 성능을 최적화하기도 어렵다.

따라서 해당 기능을 사용할 때는 신중하게 사용해야 한다. 해당 기능에 대한 자세한 내용은 공식 매뉴얼을 참고하자.

 

결과 매핑에 대한 자세한 내용은 다음을 참고하자.

https://mybatis.org/mybatis-3/ko/sqlmap-xml.html#Result_Maps

 

MyBatis – 마이바티스 3 | 매퍼 XML 파일

Mapper XML 파일 마이바티스의 가장 큰 장점은 매핑구문이다. 이건 간혹 마법을 부리는 것처럼 보일 수 있다. SQL Map XML 파일은 상대적으로 간단하다. 더군다나 동일한 기능의 JDBC 코드와 비교하면

mybatis.org

 

정리

 

Mapper 구현체 덕분에 기존 번잡한 설정 대신 스프링에 편리하게 통합해서 사용할 수 있다. 

이는 스프링 예외 추상화도 함께 적용된다.  

MyBatis 스프링 연동 모듈이 많은 부분을 자동으로 설정해주는데, 커넥션, 트랜잭션 관련 기능도 함께 연동되고 동기화해준다.

 

자동 설정 부분은  MybatisAutoConfiguration 클래스 참고하자.

 

 

MyBatis 공식 매뉴얼:https://mybatis.org/mybatis-3/ko/index.html

 

MyBatis – 마이바티스 3 | 소개

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

mybatis.org

MyBatis 스프링 공식 매뉴얼:https://mybatis.org/spring/ko/index.html

 

mybatis-spring –

소개 MyBatis-Spring 은 무엇일까? 마이바티스 스프링 연동모듈은 마이바티스와 스프링을 편하고 간단하게 연동한다. 이 모듈은 마이바티스로 하여금 스프링 트랜잭션에 쉽게 연동되도록 처리한다.

mybatis.org

 

반응형

댓글