728x90
- 장점
- SQL을 XML에 편리하게 작성할 수 있고, 동적 쿼리를 매우 편리하게 작성할 수 있다.
- 단점
- JdbcTemplate 은 스프링에 내장된 기능이고, 별도의 설정없이 사용할 수 있다.
- MyBatis는 약간의 설정이 필요한다.
설정
mybatis-spring-boot-starter 라이브러리를 사용하면 MyBatis를 스프링과 통합하고, 설정도 아주 간단히 할 수 있다.
//MyBatis 추가
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
- 스프링 부트가 버전을 관리해주는 공식 라이브러리가 아니기 때문에 버전 정보를 붙여야 한다.
- 라이브러리
- mybatis-spring-boot-starter : MyBatis 를 스프링 부트에서 편리하게 사용할 수 있게 시작하는 라이브러리
- mybatis-spring-boot-autoconfigure : MyBatis와 스프링 부트 설정 라이브러리
- mybatis-spring : MyBatis와 스프링을 연동하는 라이브러리
- mybatis : MyBatis 라이브러리
- application.properties
#MyBatis
mybatis.type-aliases-package=hello.itemservice.domain
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.hello.itemservice.repository.mybatis=trace
- MyBatis에서 타입 정보를 사용할 때는 패키지 이름을 사용해야 한다. 이때, mybatis.type-aliases-package 에 명시하면 패키지 이름을 생략할 수 있다. ( 여러 위치 지정시 , ; 로 구분 )
- JdbcTemplate의 BeanPropertyRowMapper 에서 처럼 언더바를 카멜로 자동 변경해주는 기능을 활성화하려면, mybatis.configuration.map-underscore-to-came-case 를 설정한다.
- MyBatis에서 실행되는 쿼리 로그를 확인하려면 logging.level.hello.itemservice.repository.mybatis 를 설정한다.
적용
XML에 작성한다는 점을 제외하고, JDBC 반복을 줄여준다는 점에서 기존 JdbcTemplate과 거의 유사하다.
마이바티스 매핑 XML을 호출해주는 Mapper Interface
- @Mapper
- MyBatis에서 인식할 수 있게해줌
- Interface의 메서드 호출시 xml의 해당 SQL을 실행하고 결과를 돌려준다.
ItemMapper.xml
- namespace : 앞서 만든 Mapper Interface를 지정하면 된다.
- insert- save
void save(Item item);
<insert id="save" useGeneratedKeys="true" keyProperty="id">
insert into item (item_name, price, quantity) values (#{itemName}, #{price}, #{quantity})
</insert>
- Insert SQL
- id에는 Mapper Interface에 설정한 메서드 이름 지정
- 파라미터는 #{} 문법 사용.
- Mapper에서 넘긴 객체의 Property 이름을 적어주기
- PreparedStatement 를 사용한다.
- JDBC의 ?를 치환한다고 생각하면 된다.
- useGeneratedKeys는 데이터베이스가 키를 생성해주는 IDENTITY 전략일때 사용
- keyProperty는 생성되는 키의 속성 이름을 지정
- update - update
void update(@Param("id") Long id, @Param("updateParam") ItemUpdateDto updateParam);
<update id="update">
update item set item_name=#{updateParam.itemName}, price=#{updateParam.price}, quantity=#{updateParam.quantity} where id = #{id}
</update>
- Update SQL은 <update>를 사용하면 된다.
- 파라미터가 2개 이상이면 @Param으로 이름을 지정해서 파라미터를 구분해야 한다.
- select - findById
Optional<Item> findById(Long id);
<select id="findByID" resultType="Item">
select * from item where id = #{id}
</select>
- Select SQL은 <select>를 사용하면 된다.
- resultType은 반환 타입을 명시한다.
- 여기서는 결과를 Item 객체에 매핑한다.
- application.properties 에서 mybatis.type-aliases-package=hello.itemservice.domain 속성을 지정해서 모든 패키지 명을 다 적지 않아도 된다.
- JdbcTemplate의 BeanPropertyRowMapper 처럼 SELECT SQL의 결과를 편리하게 객체로 바로 변환해준다.
- 자바 코드에서 반환 객체가 하나이면 Item, Optional<Item>과 사용
- 반환 객체가 하나 이상이면 컬렉션을 사용
- select - findAll
List<Item> findAll(ItemSearchCond itemSearch);
<select id="findAll" resultType="Item">
select * from item
<where>
<if test="itemName != null and itemName != ''">
and item_name like concat('%',#{itemName},'%')
</if>
<if test="maxPrice != null">
and price <= #{maxPrice}
</if>
</where>
</select>
- Mybatis는 <where>, <if> 같은 동적 쿼리 문법을 통해 편리한 동적 쿼리를 지원한다.
- <if> 는 해당 조건이 만족하면 구문을 추가
- <where> 는 적절하게 where 문장을 만들어준다.
- <if> 모두 실패시 where 절을 만들지 않음
- <if> 하나라도 성공하면 처음 나타나는 and를 where로 변환
- XML 특수문자
- < : <
- > : >
- & : &
- XML CDATA 구문 문법
- 이 안에서는 특수문자 사용가능
- XML TAG 가 단순 문자로 인식되어 <if>, <where> 가 적용되지 않음
<if test="maxPrice != null">
<![CDATA[
and price <= #{maxPrice}
]]>
</if>
분석
ItemMapper Interface 의 구현체가 없는데 동작하는 이유 -> MyBatis 스프링 연동 모듈에서 자동 처리
MyBatis 스프링 연동 모듈이 자동으로 등록해주는 부분은 MybatisAutoConfiguration 클래스를 참고한다.
기능 정리
동적 SQL
- if
- 해당 조건에 따라 값을 추가할지 말지 판단한다.
- 내부 문법은 OGNL을 사용한다.
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
- choose, when, otherwise
- 자바의 switch 구문과 유사한 구문
<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>
- trim, where, set
- <where>는 문장이 없으면 where를 추가하지 않는다.
- 문장이 있으면 where를 추가한다.
- 만약 and 가 먼저 시작된다면 and를 지운다.
- trim이라는 기능을 사용해도 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>
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
- foreach
- 컬렉션 반복 처리시 사용
- where in (1,2,3,4,5,6) 과 같은 문장을 쉽게 완성
- 파라미터로 List를 전달한다.
<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>
728x90
'Tech > 데이터 접근 기술' 카테고리의 다른 글
트랜잭션 매니저 선택 (0) | 2023.03.07 |
---|---|
실용적인 구조 (0) | 2023.03.07 |
스프링 데이터 JPA 소개 (0) | 2023.03.07 |
JPA 소개 (0) | 2023.03.05 |
스프링 JdbcTemplate 소개 (0) | 2023.03.05 |