SpringBoot - Mybatis MapperInterface 방식 설정

devdo·2022년 7월 17일
0

SpringBoot

목록 보기
26/34
post-thumbnail

Mybatis란

Mybatis는 꼭 스프링이 아니더라도 스프링 뿐만아니라 다른 언어와도 결합할 수 있는 프레임워크이기 때문에 배워둔다면 스프링 프레임워크가 아닌 다른언어로 웹 어 플리케이션을 제작할때도 활용할수 있는 추가 프레임워크이다.

기본적으로 JDBC 객체들을 개발자가 직접 관여하지 않고 내부적으로 관리해져
sql문에만 집중할 수 있게 해 아주 편하다.

예전 스프링버전 3.0이전일 때는
SqlSessionTemplate을 사용해서 Mybatis를 사용하였다.

하지만 스프링버전 3.0버전부터 인터페이스 Mapper 어노테이션을 활용한
MapperInterface 방식을 사용할 수 있다.

마이바티스를 사용했을때 어떠한 방식에 구해받지않고 공통적인 장점을 두가지를 나열해 보겠습니다.

  1. 쿼리문을 수행해주는 PreparedStatement를 직접생성하지않고 해당 기능이 내부적으로 자동으로 처리됩니다.
    ?처리마저도 #{필드명} 매핑을통해서 자동으로 처리가 됩니다
  2. RowMapper로 익명클래스를쓰느니 내부클래스를 쓰느니 했던것들을 mybatis가 내부적으로 다 처리해줘서 간편함을 얻을 수 있습니다.

설정

gradle dependency

implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'

application.yml

# mybatis xml파일 경로 설정 경로설정
mybatis:
  mapper-locations: classpath:mapper/*.xml

Mybatis sql문이 들어있는 xml 파일 경로를 설정해주는 것이다.
resources 내에서 만드는 것이니 이 경로대로 mapper xml 파일을 잘 만들어주자.


resources > mapper > XXX.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="com.example.dsg_lms.admin.mapper.CategoryMapper">

    <select id="select" resultType="com.example.dsg_lms.admin.dto.CategoryDto">
        select c.*
        ,   (select count(*) from course where category_id = c.id) as course_count
        from category c
        where 1=1
        and using_yn = 1
        order by sort_value desc
    </select>

</mapper>

👀 참고) <ResultMap>

ResultMap으로 mybatis-config.xml에 미리 선언된 객체를 참조하여 다시한번 객체 별칭화를 시켜주며, Mapper NameSpace와 일치하는 인터페이스와 연결해줄 수 있다. DAO클래스역할을 Mapper xml파일이 대신 해주는것과 함께 Java Beans 파일의 프로퍼티와 DB table 컬럼들을 확실하게 매핑하기 위함이 크다.

예시

    <resultMap id="boardVO" type="com.example.board_springboot.domain.BoardVO">
        <result property="id" column="id" javaType="Long" jdbcType="BIGINT"/>
        <result property="category" column="category" javaType="String" jdbcType="VARCHAR"/>
        <result property="password" column="password" javaType="String" jdbcType="VARCHAR"/>
        <result property="title" column="title" javaType="String" jdbcType="VARCHAR"/>
        <result property="content" column="content" javaType="String" jdbcType="VARCHAR"/>
        <result property="writer" column="writer" javaType="String" jdbcType="VARCHAR"/>
        <result property="hit" column="hit" javaType="int" jdbcType="INTEGER"/>
        <result property="fileYN" column="file_yn" javaType="boolean" jdbcType="INTEGER"/>
        <result property="createdAt" column="created_at" javaType="java.sql.Timestamp" jdbcType="TIMESTAMP"/>
        <result property="updatedAt" column="updated_at" javaType="java.sql.Timestamp" jdbcType="TIMESTAMP"/>
    </resultMap>

src > main > java > com.example.dsg

mapper > XXXMapper 파일

@Mapper 어노테이션을 붙여서 DAO역할의 Mapper 인터페이스 파일을 만들어준다.
이 mapper 파일이 DAO, Repository 파일이라고 생각하면 된다.

예시

@Mapper
public interface CategoryMapper {

    List<CategoryDto> select(CategoryDto parameter);

}

호출

예시
Service

    @Override
    public List<CategoryDto> frontList(CategoryDto parameter) {
        return categoryMapper.select(parameter);
    }

log4jdbc 쿼리 로그 설정

gradle dependency

implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'

src/main/resources 패키지 경로에 log4jdbc.log4j2.properties

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

application.yml
-> driver-class-name, url 변경

driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://접속정보~~~~

디테일 log옵션 설정

설정파일은 logback or log4j2.xml 아니면 application.yml 에 설정할 수 있다.

1) logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 로그 경로 변수 선언 -->
    <property name="LOG_DIR" value="${user.home}/logs/app" />
    <property name="LOG_PATH" value="${LOG_DIR}/app.log"/>

    <!-- log4jdbc 옵션 설정 -->
    <logger name="jdbc" level="OFF"/>
    <!-- connection open close 로깅 여부 -->
    <logger name="jdbc.connection" level="OFF"/>
    <!-- SQL문만 로깅할지 여부 -->
    <logger name="jdbc.sqlonly" level="OFF"/>

    <!-- 쿼리문 수행에 걸린 시간 로깅 -->
    <logger name="jdbc.sqltiming" level="DEBUG"/>

    <!-- ResultSet외 모든 JDBC 호출 정보를 로깅할지 여부   -->
    <logger name="jdbc.audit" level="OFF"/>

    <!-- ResultSet 포함 모든 JDBC 호출 정보를 로깅 -->
    <logger name="jdbc.resultset" level="OFF"/>
    <logger name="jdbc.resultsettable" level="INFO"/>

    <!-- use Spring default values -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 콘솔 출력 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. -->
    <logger name="jdbc.resultsettable" level="ON" additivity="false">
        <appender-ref ref="CONSOLE"/>
    </logger>

    <!-- Rolling File Appender -->
    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 파일 경로 -->
        <file>${LOG_PATH}</file>
        <!-- 출력패턴 -->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}[%-5level] : %msg%n</pattern>
        </encoder>
        <!-- Rolling 정책 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- .gz,.zip 등을 넣으면 자동으로 일자별 로그파일 압축 -->
            <fileNamePattern>${LOG_DIR}/app_%d{yyyy-MM-dd}_%i.log.gz</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 파일당 최고 용량 10MB -->
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- 일자별 로그파일 최대 보관주기(일단위) 만약 해당 설정일 이상된 파일은 자동으로 제거-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
    </appender>

    <root level="INFO"> <!-- DEBUG -->
        <appender-ref ref="CONSOLE"/> <!-- 콘솔 출력 -->
        <appender-ref ref="ROLLING_FILE"/> <!-- 파일 출력 -->
    </root>
</configuration>

2) application.yml

# log4jdbc, Mybatis Console Log
logging:
  level:
    com:
      zaxxer:
        hikari: INFO
    javax:
      sql:
        DataSource: OFF
    jdbc:
      audit: OFF
      resultset: OFF
      resultsettable: INFO  #SQL 결과 데이터 Table을 로그로 남긴다.
      sqlonly: OFF     #SQL만 로그로 남긴다.
      sqltiming: INFO    #SQL과 소요시간을 표기한다.
      connection : OFF  # 커넥션 확인가능
    org:
      hibernate:
        SQL: DEBUG
        type:
          descriptor:
            sql:
              BasicBinder: TRACE

옵션 설명

  • jdbc.sqlonly - SQL 문을 보여준다.
  • jdbc.sqltiming - SQL 문과 이 SQL 문을 수행하는 시간(ms)을 같이 보여준다.
  • jdbc.audit - ResultSet 을 제외한 모든 JDBC 호출 정보를 로그로 보여준다. 상당히 많은 양의 로그가 나오기 때문에 권장하지 않음.
  • jdbc.resultset - ResultSet 을 포함한 모든 JDBC 호출 정보를 로그로 보여준다. audit 처럼 많은 로그가 나오기 때문에 권장하지 않음.
  • jdbc.resultsettable - SQL 의 결과로 조회된 데이터를 table 형태로 로그를 보여준다.
  • jdbc.connection - DB 연결, 연결 해제와 관련된 로그를 보여준다


참고

profile
배운 것을 기록합니다.

0개의 댓글