본문 바로가기
Back/DB

[DB] MyBatis

by 오엥?은 2023. 5. 9.
반응형
  • build.gradle -> dependencies 안에 추가
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'

 

  • apploication.properties 에 추가 (test > resoueces > 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

 

  • src > main > java > hello.itemservice > repository > mybatis > ItemMapper 생성 (Interface)
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 updateDto);

    List<Item> findAll(ItemSearchCond itemSearch);
    
    Optional<Item> findById(Long id);
}

 

  • src > main > resources > hello.itemservice.repository.mybatis > itemMapper.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">
    
</mapper>

이렇게 뼈대를 작성해 준다.

 

  • 그 안을 itemMapper Interface 에 맞게 채워준다.
<?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">
        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>

◽ insert - save

- #{} 문법을 사용하면 PreparedStatement 를 사용한다. JDBC의 ? 를 치환한다고 생각하면 된다.

- useGeneratedKeys 는 데이터베이스가 키를 생성해 주는 IDENTITY 전략일 때 사용한다. keyProperty는 생성되는 키의 속성 이름을 지정한다. Insert 가 끝나면 item 객체의 id 속성에 생성된 값이 입력된다.

 

◽ update - update

- 여기서는 파라미터가 Long id, ItemUpdateDto updateParam으로 2개이다. 파라미터가 1개만 있으면 @Param을 지정하지 않아도 되지만, 파라미터가 2개 이상이면 @Param 으로 이름을 지정해서 파라미터를 구분해야 한다.

 

◽ select - findById

- resultType 은 반환타입을 명시하면 된다. 여기서는 결과를 Item 에 매핑한다.

 : 앞서 application.properties에 mybatis.type-aliases-package=hello.itemservice.domain 속성을 지정한 덕분에 모든 패키지 명을 다 적지는 않아도 된다. 그렇지 않으면 모든 패키지명을 적어야 한다,

mybatis.configuration.map-underscore-to-camel-case=true 속성을 지정한 덕분에 언더스코어를 카멜 표기법으로 자동으로 처리해준다. (item_name -> itemName)

 

◽ select - findAll

- <if> 는 해당조건이 만족하면 구문을 추가한다.

- <where> 은 적절하게 where 문장을 만들어준다.

 : 예제에서 <if> 가 모두 실패하게 되면 SQL where 을 만들지 않는다.

  예제에서 <if> 가 하나라도 성공하면 처음 나타나는 and 를 where 로 변환해 준다. 

- $lt;=  이걸 적는 이유는 <= 를 써야하는데 < 가 등호로 인식되지 않고 괄호로 인식되어 충돌이 일어나기 때문이다. 

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

 

 

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>

 

반응형

'Back > DB' 카테고리의 다른 글

[DB] QueryDSL  (0) 2023.05.12
[DB] JPA  (0) 2023.05.12
[DB] JdbcTemplate  (0) 2023.05.08
[DB] H2 데이터베이스 설치  (0) 2023.05.04
[DB] Sharding (샤딩)  (0) 2023.04.27