You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MyBatis 스프링 연동 모듈이 만들어주는 ItemMapper 의 구현체 덕분에 인터페이스 만으로 편리하게 XML의 데이터를 찾아서 호출할 수 있다.
원래 MyBatis 를 사용하려면 더 번잡한 코드를 거쳐야 하는데, 이런 부분을 인터페이스 하나로 매우 깔끔하고 편리하게 사용할 수 있다.
매퍼 구현체는 예외 변환까지 처리해준다. MyBatis 에서 발생한 예외를 스프링 예외 추상화인 DataAccessException 에 맞게 변환해서 반환해준다. JdbcTemplate 이 제공하는 예외 변환 기능을 여기서도 제공한다고 이해하면 된다.
정리
매퍼 구현체 덕분에 MyBatis 를 스프링에 편리하게 통합해서 사용할 수 있다.
매퍼 구현체를 사용하면 스프링 예외 추상화도 함께 적용된다.
MyBatis 스프링 연동 모듈이 많은 부분을 자동으로 설정해주는데, 데이터베이스 커넥션, 트랜잭션과 관련된 기능도 MyBatis 와 함께 연동하고 동기화해준다.
3️⃣ MyBatis 기능 정리1 - 동적 쿼리
동적 SQL
마이바티스가 제공하는 최고의 기능이자 사용하는 이유는 바로 동적 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 을 사용한다.
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></select>
이 예제의 문제점은 문장을 모두 만족하지 않을 때 발생하고
SELECT*FROM BLOG
WHERE
title 만 만족할 때도 문제가 발생한다.
SELECT*FROM BLOG
WHEREAND title like ‘someTitle’
결국 where 문을 언제 넣어야 할 지 상황에 따라서 동적으로 달라지는 문제가 있다. <where> 을 사용하면 이런 문제를 해결할 수 있다.
<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 를 지운다.
참고로 다음과 같이 trim 이라는 기능으로 사용해도 된다. 이렇게 정의하면 <where> 와 같은 기능을 수행한다.
<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 를 전달하면 된다.
4️⃣ MyBatis 기능 정리2 - 기타 기능
애노테이션으로 SQL 작성
@Select("select id, item_name, price, quantity from item where id=#{id}")
Optional<Item> findById(Long id);
@Insert , @Update , @Delete , @Select 기능이 제공된다.
이 경우 XML 에는 <select id="findById"> ~ </select> 는 제거해야 한다.
동적 SQL 이 해결되지 않으므로 간단한 경우에만 사용한다.
문자열 대체
#{} 문법은 ? 을 넣고 파라미터를 바인딩하는 PreparedStatement 를 사용한다.
때로는 파라미터 바인딩이 아니라 문자 그대로를 처리하고 싶은 경우도 있다. 이 때는 ${} 를 사용하면 된다.
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);
주의 ${} 를 사용하면 SQL 인젝션 공격을 당할 수 있어 가급적 사용하면 안된다. 사용하더라도 매우 주의깊게 사용해야 한다.
결과를 매핑할 때 테이블은 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="user_name"/><result property="password" column="hashed_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 에서는 들어가는 공수도 많고, 성능을 최적화하기도 어렵다.
따라서 해당 기능을 사용할 때는 신중하게 사용해야 한다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
1️⃣ MyBatis 적용2 - 설정과 실행
ItemRepository를 구현해서MyBatisItemRepository생성MyBatisItemRepository는 단순히ItemMapper에 기능을 위임한다.MyBatisConfig
MyBatisConfig는ItemMapper를 주입받고, 필요한 의존관계를 만든다.ItemServiceApplication - 변경
2️⃣ MyBatis 적용3 - 분석
ItemMapper인터페이스의 구현체가 없는데 어떻게 동작한 것일까 ?이 부분은 MyBatis 스프링 연동 모듈에서 자동으로 처리해준다.

1️⃣ 애플리케이션 로딩 시점에 MyBatis 스프링 연동 모듈은
@Mapper가 붙어있는 인터페이스를 조사한다.2️⃣ 해당 인터페이스가 발견되면 동적 프록시 기술을 사용해서
ItemMapper인터페이스의 구현체를 만든다.3️⃣ 생성된 구현체를 스프링 빈으로 등록한다.
MyBatisItemRepository 로그 추가
매퍼 구현체
ItemMapper의 구현체 덕분에 인터페이스 만으로 편리하게 XML의 데이터를 찾아서 호출할 수 있다.DataAccessException에 맞게 변환해서 반환해준다. JdbcTemplate 이 제공하는 예외 변환 기능을 여기서도 제공한다고 이해하면 된다.정리
3️⃣ MyBatis 기능 정리1 - 동적 쿼리
동적 SQL
마이바티스가 제공하는 최고의 기능이자 사용하는 이유는 바로 동적 SQL 기능 때문이다.
동적 쿼리를 위해 제공되는 기능은 다음과 같다.
ifchoose (when, otherwise)trim (where, set)foreachif
choose, when, otherwise
trim, where, set
이 예제의 문제점은 문장을 모두 만족하지 않을 때 발생하고
title 만 만족할 때도 문제가 발생한다.
결국
where문을 언제 넣어야 할 지 상황에 따라서 동적으로 달라지는 문제가 있다.<where>을 사용하면 이런 문제를 해결할 수 있다.<where>사용<where>는 문장이 없으면where을 추가하지 않는다. 문장이 있으면where을 추가한다. 만약and가 먼저 시작된다면and를 지운다.참고로 다음과 같이
trim이라는 기능으로 사용해도 된다. 이렇게 정의하면<where>와 같은 기능을 수행한다.foreach
where in (1,2,3,4,5,6)와 같은 문장을 쉽게 완성할 수 있다.List를 전달하면 된다.4️⃣ MyBatis 기능 정리2 - 기타 기능
애노테이션으로 SQL 작성
@Insert,@Update,@Delete,@Select기능이 제공된다.<select id="findById"> ~ </select>는 제거해야 한다.문자열 대체
#{}문법은 ? 을 넣고 파라미터를 바인딩하는PreparedStatement를 사용한다.때로는 파라미터 바인딩이 아니라 문자 그대로를 처리하고 싶은 경우도 있다. 이 때는
${}를 사용하면 된다.주의
${}를 사용하면 SQL 인젝션 공격을 당할 수 있어 가급적 사용하면 안된다. 사용하더라도 매우 주의깊게 사용해야 한다.재사용 가능한 SQL 조각
<sql>을 사용하면 SQL 코드를 재사용할 수 있다.<include>를 통해서<sql>조각을 찾아서 사용할 수 있다.Result Maps
결과를 매핑할 때 테이블은
user_id이지만, 객체는id이다.이 경우 컬럼명과 객체의 프로퍼티 명이 다르다. 그러면 별칭 (
as) 을 사용하면 된다.별칭을 사용하지 않을 경우
resultMap을 선언해서 사용하면 된다.복잡한 결과매핑
MyBatis 도 매우 복잡한 결과에 객체 연관관계를 고려해서 데이터를 조회하는 것이 가능하다.
이 때는
<association>,<collection>등을 사용한다.이 부분은 성능과 실효성 측면에서 많은 고민이 필요하다.
JPA 는 객체와 관계형 데이터베이스를 ORM 개념으로 매핑하기 때문에 이런 부분이 자연스럽지만, MyBatis 에서는 들어가는 공수도 많고, 성능을 최적화하기도 어렵다.
따라서 해당 기능을 사용할 때는 신중하게 사용해야 한다.
All reactions