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
동적 쿼리
MyBatis가 제공하는 최고의 기능이자 MyBatis를 사용하는 이유는 바로 동적 SQL 기능 때문이다. 동적 쿼리를 위해 제공되는 기능은 다음과 같다.
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
if
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
- 해당 조건에 따라 값을 추가할지 말지 판단한다.
- 내부의 문법은 OGNL을 사용한다. 자세한 내용은 OGNL을 검색해보자.
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>
- 자바의 switch 구문과 유사한 구문도 사용할 수 있다.
trim, where, set
<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 구문을 그냥 사용하게 된다면 검색조건이 없을 경우 BadSqlGrammer 예외가 발생하므로 <Where>, <trim>을 사용하면 이를 해결할 수 있다.
- <where>는 문장이 없으면 where를 추가하지 않는다. 문장이 있으면 where를 추가한다. 만약 and 가 먼저 시작된다면 and를 지운다.
- 참고로 다음과 같이 trim이라는 기능으로 사용해도 된다. 이렇게 정의하면 <where>와 같은 기능을 수행한다
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
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
기타 기능
애노테이션으로 SQL 작성
@Select("select id, item_name, price, quantity from item where id=#{id}")
Optional<Item> findById(Long id);
- XML대시 어노테이션에 SQL을 작성할 수 있다(잘 사용 X)
- @Insert , @Update , @Delete , @Select 기능이 제공된다.
- XML이랑 중복되게 메서드를 만들면 안 된다(어노테이션을 쓸 경우 XML을 메서드는 주석처리)
- 동적 SQL이 해결되지 않으므로 간단한 경우에만 사용한다.
- https://mybatis.org/mybatis-3/ko/java-api.html
MyBatis – 마이바티스 3 | 자바 API
자바 API 이제 마이바티스를 설정하는 방법과 매핑을 만드는 방법을 알게 되었다. 이미 충분히 잘 사용할 준비가 된 셈이다. 마이바티스 자바 API 는 당신의 노력에 대한 보상을 얻게 할 것이다. JD
mybatis.org
문자열 대체(String Substitution)
#{} 문법은 ?를 넣고 파라미터를 바인딩하는 PreparedStatement를 사용한다.
때로는 파라미터 바인딩이 아니라 문자 그대로를 처리하고 싶은 경우도 있다. 이때는 ${}를 사용하면 된다
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);
- ${}를 사용하게 되면 SQL 인젝션 공격을 당할 수 있다. 따라서 가급적 사용하면 안 된다. 사용하더라도 매우 주의 깊게 사용해야 한다
재사용 가능한 SQL 조각
<sql>을 사용하면 SQL 코드를 재사용할 수 있다.
<sql id="userColumns">
${alias}.id,${alias}.username,${alias}.password
</sql>
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/></include>,
<include refid="userColumns"><property name="alias" value="t2"/></include>
from some_table t1
cross join some_table t2
</select>
- <include>를 통해서 <sql> 조각을 찾아서 사용할 수 있다.
<sql id="sometable">
${prefix}Table
</sql>
<sql id="someinclude">
from
<include refid="${include_target}"/>
</sql>
<select id="select" resultType="map">
select
field1, field2, field3
<include refid="someinclude">
<property name="prefix" value="Some"/>
<property name="include_target" value="sometable"/>
</include>
</select>
- 프로퍼티 값을 전달할 수 있고, 해당 값은 내부에서 사용할 수 있다.
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
'스프링 DB 2편(데이터 접근 활용 기술)' 카테고리의 다른 글
| Ch05. JPA - JPA 설정 (0) | 2022.06.29 |
|---|---|
| Ch05. JPA - JPA 시작 (0) | 2022.06.29 |
| Ch04. MyBatis - MyBatis 적용 (0) | 2022.06.27 |
| Ch04. MyBatis - MyBatis 설정 (0) | 2022.06.27 |
| Ch04. MyBatis - MyBatis 소개 (0) | 2022.06.27 |