[Spring] MyBatis Configuration

배창민·2025년 10월 20일
post-thumbnail

MyBatis Configuration


1) Configuration by JAVA

1-1. Environment

  • 역할: DB 접속/트랜잭션/데이터소스 환경을 담는 객체

  • 생성

    Environment env = new Environment(
        "dev",
        new JdbcTransactionFactory(),             // 권장: 수동 커밋
        new PooledDataSource(DRIVER, URL, USER, PASSWORD) // 권장: 커넥션풀
    );
  • 트랜잭션 매니저

    • JdbcTransactionFactory: 코드로 commit/rollback 제어(권장)
    • ManagedTransactionFactory: 컨테이너가 관리(자동 커밋)
  • DataSource

    • PooledDataSource: 커넥션 풀 사용(속도/메모리 효율 ↑)
    • UnpooledDataSource: 매 호출마다 새 커넥션

1-2. Configuration

  • 역할: 전역 설정 컨테이너(환경, 매퍼 등록, 별칭 등)

  • 사용

    Configuration conf = new Configuration(env);
    conf.addMapper(Mapper.class);

1-3. SqlSessionFactory / SqlSession

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(conf);
try (SqlSession session = factory.openSession(false)) { // auto-commit=false 권장
  // ... CRUD
  session.commit();
}
  • Factory: 앱 스코프 싱글톤 추천(여러 번 빌드 금지)

  • Session:

    • Thread-unsafe → 요청 단위 생성/종료
    • 반드시 close() (try-with-resources 추천)
  • openSession 주요 오버로드

    • openSession(): 기본
    • openSession(boolean autoCommit)
    • openSession(Connection)
    • openSession(ExecutorType)SIMPLE/REUSE/BATCH
  • SqlSession CRUD

    메서드설명
    selectOne(String, Object)단일 행
    selectList(String, Object)리스트
    selectMap(String, Object, String mapKey)
    insert/update/delete(String, Object)DML(반환: 영향 행 수)

2) Configuration by XML

2-1. 기본 구조

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  ...
</configuration>

2-2. 주요 태그 한눈 정리

<properties>

  • 공통 속성 정의/외부 파일 로딩, ${key} 참조
<properties resource="config/db.properties"/>

<settings>

  • 세부 동작 옵션
<settings>
  <setting name="jdbcTypeForNull" value="NULL"/>
  <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<typeAliases>

  • 클래스 별칭 등록으로 resultType/parameterType 간결화
<typeAliases>
  <typeAlias type="com.example.Member" alias="Member"/>
</typeAliases>

<environments>

  • DB 연결/트랜잭션/데이터소스
<environments default="dev">
  <environment id="dev">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

<mappers>

  • 매퍼 XML/인터페이스 등록
<mappers>
  <mapper resource="member/model/mapper/member-mapper.xml"/>
  <!-- 또는 <mapper class="com.example.MemberMapper"/> -->
  <!-- 또는 <package name="com.example.mapper"/> -->
</mappers>

그 외

  • <typeHandler>: 타입 변환(ENUM, 암복호화 등 특수 케이스)
  • <objectFactory>: 결과 객체 생성 커스터마이징(희소)
  • <plugins>: 실행 시점 가로채기(로깅/검증) — AOP 유사

3) Mapper by JAVA(Annotation)

3-1. 사용

Mapper mapper = session.getMapper(Mapper.class);
var date = mapper.selectSysdate();

3-2. 애노테이션 샘플

@Results(id = "menuRM", value = {
  @Result(id = true, property = "code", column = "MENU_CODE"),
  @Result(property = "name", column = "MENU_NAME"),
  @Result(property = "price", column = "MENU_PRICE"),
  @Result(property = "categoryCode", column = "CATEGORY_CODE"),
  @Result(property = "orderableStatus", column = "ORDERABLE_STATUS")
})
@Select("""
  SELECT MENU_CODE, MENU_NAME, MENU_PRICE, CATEGORY_CODE, ORDERABLE_STATUS
    FROM TBL_MENU
   WHERE ORDERABLE_STATUS='Y' AND MENU_CODE = #{code}
""")
@ResultMap("menuRM")
MenuDTO selectMenuByCode(int code);

@Insert("""
  INSERT INTO TBL_MENU (MENU_NAME, MENU_PRICE, CATEGORY_CODE, ORDERABLE_STATUS)
  VALUES (#{name}, #{price}, #{categoryCode}, 'Y')
""")
int insertMenu(MenuDTO m);

@Update("""
  UPDATE TBL_MENU
     SET MENU_NAME=#{name}, MENU_PRICE=#{price}, CATEGORY_CODE=#{categoryCode}
   WHERE MENU_CODE=#{code}
""")
int updateMenu(MenuDTO m);

@Delete("DELETE FROM TBL_MENU WHERE MENU_CODE = #{code}")
int deleteMenu(int code);

4) Mapper by XML

4-1. 작성 규칙

  • 인터페이스와 동일 패키지/이름(resources 하위 경로 매칭)
  • <mapper namespace="풀클래스명(인터페이스)"> 필수
  • 인터페이스 메서드명 ↔ <select|insert|update|delete id> 일치
  • 반환 타입/파라미터 일치

4-2. 핵심 태그

resultMap

<resultMap id="MemberRM" type="Member">
  <id     property="userId"   column="USER_ID"/>
  <result property="password" column="PASSWORD"/>
  <result property="userName" column="USER_NAME"/>
</resultMap>
  • 하위: <id>, <result>, <constructor>, <association>, <collection>, <discriminator>

select

<select id="findById" parameterType="string" resultMap="MemberRM">
  SELECT USER_ID, PASSWORD, USER_NAME
    FROM MEMBER
   WHERE USER_ID = #{userid}
</select>
  • 바인딩: #{}(권장) vs ${}(그대로 치환, 인젝션 위험)
  • resultType(직접 타입) 또는 resultMap(매핑 규칙)

insert / update / delete

<insert id="insertMember" parameterType="Member" useGeneratedKeys="true">
  INSERT INTO MEMBER (...) VALUES (#{...})
</insert>

<update id="updateMember" parameterType="Member">
  UPDATE MEMBER SET ... WHERE ID = #{id}
</update>

<delete id="deleteMember" parameterType="string">
  DELETE FROM MEMBER WHERE ID = #{userid}
</delete>
  • 반환: 영향 행 수(int)
  • 공통 속성: flushCache, timeout, statementType

cache / cache-ref

<cache eviction="LRU" flushInterval="1000" size="512" readOnly="true"/>
  • 기본 동작: 모든 select 캐시, insert/update/delete 시 캐시 삭제
  • 제약: 로컬 캐시(다중 서버는 분산 캐시 고려)

sql + include (SQL 조각 재사용)

<sql id="columns">
  MENU_CODE, MENU_NAME, MENU_PRICE, CATEGORY_CODE, ORDERABLE_STATUS
</sql>

<select id="selectSqlTest" resultMap="menuRM">
  SELECT <include refid="columns"/> FROM TBL_MENU WHERE ORDERABLE_STATUS='Y'
</select>

핵심 요약

  • 환경Environment + Configuration으로 구성하고, Factory 싱글톤, Session은 요청 단위 생성/종료.
  • auto-commit=false 로 열고 비즈니스 트랜잭션에서 명시적 commit/rollback.
  • 매퍼는 Annotation(가벼운 CRUD/샘플) + XML(복잡 매핑/재사용/캐시) 상황 맞춤 혼용.
  • XML에선 resultMap으로 명시 매핑, 파라미터 바인딩은 #{} 우선.
  • 성능은 PooledDataSource, 필요 시 2nd 레벨 캐시 조정.
profile
개발자 희망자

0개의 댓글