본문 바로가기

TIL

TIL 3/26 - MyBatis

https://www.elancer.co.kr/blog/detail/231

MyBatis Framework

보다 편리한 CRUD를 위해 xml로 구조화한 Mapper 파일을 가지고 JDBC 과정을 구현한 영속성 프레임워크(Persistence)

빌더 패턴으로 구현돼있어, 차례로 객체를 생성해야한다.

https://refactoring.guru/ko/design-patterns/builder

VS JDBC

기존 JDBC 코드의 상당 부분을 차지했던 파라미터 바인딩(? 채우기), 결과 매핑(Resultset → DTO)을 xml을 통해 쉬운 구현 가능

동적 쿼리 기능 지원( 쿼리 작성 xml에서 제어문 작성 가능 )

public int insertMenu(Connection conn, MenuDTO menu) {
        PreparedStatement pstmt = null;
        int result = 0;
        try {
            pstmt = conn.prepareStatement(prop.getProperty("insertMenu"));
            pstmt.setString(1, menu.getMenuName());
            pstmt.setInt(2, menu.getMenuPrice());
            pstmt.setInt(3, menu.getCategoryCode());
            pstmt.setString(4, menu.getOrderableStatus());
            result = pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;
    } // JDBC의 삽입 함수
public int InsertMenu(SqlSession sqlSession, MenuDto menuDto) {
        return sqlSession.insert("Menu.insert", menuDto);
}

Environment

DB 접속 환경 설정 정보를 가지는 인스턴스

MyBatis 환경설정 객체(Configuration) 생성에 사용

생성자 - new Environment(환경정보이름, 트랜잭션매니저종류, 커넥션풀사용여부);

  1. 환경 정보 이름 : 생성 해당 환경 정보 이름 결정(운영환경, 개발환경, 테스트환경 등 각각 이름 지정 및 분리시 사용)
  2. 트랜잭션 매니저 종류 : 트랜잭션 처리를 담당하는 객체
    • JdbcTransactionFactory : 수동 커밋(권장)
    • ManagedTransactionFactory : 오토 커밋
  3. 커넥션 풀 사용여부
    • PooledDataSource : Connection pool 사용
    • UnpooledDataSource : “ 미사용

Configuration

MyBatis 환경 설정 객체

DB접속 관련 정보, Mapper 등록, Alias 등록 등

MyBatis 전역 설정 정보 담음

생성자 - new Configuration(현재 사용 환경인 Environmen객체)

configuration.addMapper(), .setJdbcTypeForNull() 등 설정 가능

SqlSessionFactory

인터페이스임

→ 구현체인 SqlSessionFactoryBuilder를 통해 생성

SqlSessionFacoty ssf = new SqlSessionFalctoryBuilder().build( Config객체 | cofig 파일과 연결된 InputStream객체);

애플리케이션 기동 중에 여러번 빌드되지 않게 싱글톤 패턴 권장

SqlSession

MyBatis 기능을 통한 sql문 실행, 트랜잭션 처리, 자원 반납 메소드를 제공하는 객체

사용자 요청시마다 생성하고 요청 처리 완료시 close 권장

SqlSessionFactory객체.openSession(autoCommit여부)로 생성

XML 파일로 환경 구성하기

https://mybatis.org/mybatis-3/ko/getting-started.html

xml로 사용하기 전, 예제 확인을 위해 해당 사이트를 참고하자.

configuration 내 사용 가능 타입들엔 위와같은 내용들이 있고, 다 복수형인것을 볼 수 있다.

해당 태그 내에 세부적인 것들을 세세히 설정 가능하다.

<typeAliases>
	<typeAlias type=""> // 이런 형태로!
</typeAliases>

setting : MyBatis setting

mappers : 매퍼파일(sql문이 작성된 xml 파일)등록

sqlSession은 트랜잭션 처리를 위해, 사용하고 닫고를 반복해야함.

but SqlSessionFactory의 경우 재사용하는게 좋음 → singleton 적용시 효율적이다.

따라서

public class Template {

    private static SqlSessionFactory sqlSessionFactory;

    public static SqlSession getSqlSession() {
        if (sqlSessionFactory == null) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("section01/xml/mybatis-config.xml");
                // classPath 위치(resources)로부터의 경로 작성
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        SqlSession sqlSession = sqlSessionFactory.openSession(false);
        return sqlSession;
    }
}

이렇게 코드를 구성해주자.

XML 탬플릿 구성

File → Settings → Editor → File and Code Templates

템플릿 만들어주기

이렇게 눌러서 생성하면 된다!

MyBatis-Config.xml 작성 방법

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/menudb"/>
                <property name="username" value="ino"/>
                <property name="password" value="ino"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="section01/xml/menu-mapper.xml"/>
    </mappers>
</configuration>

Mapper 작성 방법

<!--
    ## Mapper 파일 작성 ##

    *  주요 태그 종류
    1. <select> : select문 작성
    2. <insert> : insert문 작성
    3. <update> : update문 작성
    4. <delete> : delete문 작성
    5. <resultMap> : 조회된 한 행을 매핑시킬 타입 지정
                     주로 DTO에 매핑시킬때 사용

    *  주요 속성 종류
    1. id : 해당 sql문의 식별자 (필수)
    2. parameterType : 해당 sql문으로 전달되는 파라미터 타입 (선택)
        ex) parameterType="_int"
            parameterType="string"
            parameterType="map"
            parameterType="com.kangbroo.model.dto.MenuDto" (Alias 미등록시)
            parameterType="MenuDto" (Alias 등록시)
    3. resultType : select문 실행 결과 한 row에 대한 타입 (dml문일 경우 미작성)
        ex) 위의 parameterType과 유사
    4. resultMap  : select문 실행 결과 한 row에 대해 어떤 resultMap을 참조시킬껀지 resultMap의 id작성 (dml문일 경우 미작성)

    *  주요 MyBatis 내장 별칭
         자바   |   마이바티스
       ========================
         int    |    _int
        String  |   string
         List   |    list
         Map    |     map

    *  파라미터 바인딩 (#{}, ${})
       만일 sql문으로 전달된 데이터가 있을 경우 파라미터 설정하기

    1. #{} : ?와 같은 역할을 수행하며 내부적으로 PreparedStatement 방식으로 값 처리함
             해당 값의 타입에 맞춰 값이 바인딩됨

           case 1. code 변수(10)에 숫자가 담겨 넘어올 경우  => #{변수}
                    #{code}  ==  10
           case 2. Map{name:"홍길동", age:17}이 넘어올 경우 => #{키}
                    #{name}  ==  '홍길동'
                    #{age}   ==  17
           case 3. MenuDto{menuCode:12, menuName:"음식"} 이 넘어올 경우 => #{필드}
                    #{menuCode} == 12
                    #{menuName} == '음식'

    2. ${} : sql문의 메타데이터(테이블명, 컬럼명, sql자체)를 처리할 때 사용함
             실제 데이터 값을 바인딩할 때 사용하면 SQL Injection에 취약함

            ex) Map{tableName:"tbl_menu", columnName:"menu_name"} 이 넘어올 경우
                    SELECT * FROM ${tableName} WHERE ${columnName} = '열무'
                    => SELECT * FROM tbl_menu WHERE menu_name = '열무'   로 완성됨

-->

MyBatis 방식으로 xml 파일에 작성된 sql문 실행

sqlSession.sql문종류별메소드(”실행sql문지칭”[, sql문 실행시 필요 데이터] )

sql문 종류별 메소드

selectList : 해당 sql문 실행 결과를 list<E> 반환, 조회결과 없을 경우 텅 빈 리스트

selectOne : 해당 sql문의 실행 결과를 T로 반환 ( 조회 결과 없을 경우 null)

insert|update|delete : 해당 sql문의 실행 결과를 int 반환

실행 sql문 : “Mapper파일명.sql문의id”

Mapper파일명 == xml의 namespace값

sql문의 id == 해당 xml 내의 id값

sql문 실행시 필요 데이터

무조건 한 개만 전달 가능(AnyType)

→ 다수 데이터의 경우 Map | DTO에 담아서 전달