본 글에서는 String Boot 프로젝트에 MyBatis 와 log4jdbc-log4j2 를 설정하는 방법에 대하여 정리합니다.
MyBatis 설정
pom.xml 수정
- org.mybatis:mybatis, org.mybatis:mybatis-spring을 설정하여 관련 라이브러리를 추가합니다.
데이터베이스 연결 Pool을 위해 com.zaxxer:HikariCP를 추가합니다.(옵션으로 추가하지 않아도 상관없으며 환경설정에서 잃어오는 방법이 약간 다릅니다.)Spring Framework 3.x 이상에서는 자동으로 HikariCP가 기본으로 적용되었습니다.
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.0</version>
</dependency>
jdbc 연결정보 수정
여러 개의 데이터베이스 연결을 가능하도록 처리하기 위해 prefix를 추가하였습니다. 일반적인 상황이라면 추가하지 않아도 됩니다.
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.oauth.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.oauth.jdbc-url=jdbc:mysql://host:port/dbname?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.oauth.username=user
spring.datasource.oauth.password=password
mybatis-congif.xml 설정
데이터베이스 컬럼이름의 _에 해당하는 문자열이 있으며 자동으로 대문자처리하도록 mapUnderscoreToCamelCase 옵션을 추가합니다. 예를 들어 데이터베이스 컬럼이 user_name 이라면 연결되는 java의 변수명은 userName와 자동매핑되도록 처리됩니다.
<?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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
</configuration>
DatabaseConfig.java 생성하기
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@PropertySource("classpath:/application.properties")
public class DatabaseConfig {
private static final Logger log = LoggerFactory.getLogger(DatabaseConfig.class);
@Bean
@ConfigurationProperties(prefix = "spring.datasource.oauth")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() {
DataSource dataSource = new HikariDataSource(hikariConfig());
log.info("datasource : {}", dataSource);
return dataSource;
}
@Autowired
private ApplicationContext applicationContext;
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:/mapper/**/*.xml"));
//Mybatis config파일 위치
Resource myBatisConfig = new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml");
sqlSessionFactoryBean.setConfigLocation(myBatisConfig);
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
mapper 작성
src/main/resources에 mapper 디렉토리리를 생성하고 그 위치에 user_sql.xml 과 같은 파일들을 생성하여 mybatis에서 자동으로 데이터베이스 질의문이 읽혀질 수 있도록 합니다. 파일의 맨 상단의 2줄(<?xml 구문과 <!DOCTYPE 구문)이 없으면 해당 파일을 정상적으로 처리하지 못하니 반드시 추가해야 합니다.
<?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="user">
<select id="selectUserById" resultType="User">
<![CDATA[
SELECT
*
FROM
oauth_user_details
WHERE
username = #{username}
]]>
</select>
</mapper>
Sample Code 작성
SqlSessionTemplate 객체를 사용하여 mapper에 설정된 데이터베이스 질의문를 수행합니다.
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("userDAO")
public class UserDAO {
@Autowired
private SqlSessionTemplate sqlSession;
public User getUserById(String id) {
return sqlSession.selectOne("user.selectUserById", id);
}
}
log4jdbc 설정
본 설정은 개발시에 데이터베이스 질의문과 결과를 여러 줄로 나눠서 예쁘게 로그를 출력하기 위한 라이브러리 설정입니다.
pom.xml 수정
로그출력을 위한 라이브러리를 추가합니다.
<!-- MyBatis sql pretty -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
logback-spring.xml 설정
출력되는 로그를 설정합니다. /src/main/resources/logback-spring.xml 파일을 신규로 생성하고 아래의 코드를 추가합니다. 실제 운영상태에서는 하단의 <logger name="jdbc" level="OFF" />부분을 수정하여 로그가 다르게 쌓일 수 있도록 설정해야 합니다.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--로그 파일 저장 위치-->
<property name="LOGS_PATH" value="./logs"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm} %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<appender name="DAILY_ROLLING_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS_PATH}/logback.log</file>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOGS_PATH}/logback.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>5MB</maxFileSize>
<!-- kb, mb, gb -->
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<logger name="com.nextday.gateway" level="INFO">
<appender-ref ref="DAILY_ROLLING_FILE_APPENDER" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
<logger name="jdbc" level="OFF"/>
<logger name="jdbc.sqlonly" level="OFF"/>
<logger name="jdbc.sqltiming" level="DEBUG"/>
<logger name="jdbc.audit" level="OFF"/>
<logger name="jdbc.resultset" level="OFF"/>
<logger name="jdbc.resultsettable" level="DEBUG"/>
<logger name="jdbc.connection" level="OFF"/>
</configuration>
log4j. log4jdbc.log4j2.properties 생성하기
log4jdbc.spylogdelegator.name = net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength = 0
#Disable - Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
log4jdbc.auto.load.popular.drivers = false
jdbc 연결정보 수정
- driver-class-name 을 net.sf.log4jdbc.sql.jdbcapi.DriverSpy로 변경합니다.
- 데이터베이스 연결을 jdbc:mysql:// 을 jdbc:log4jdbc:mysql:// 로 변경합니다.
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.oauth.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.oauth.jdbc-url=jdbc:mysql://host:port/dbname?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.oauth.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.oauth.jdbc-url=jdbc:log4jdbc:mysql://host:port/dbname?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.oauth.username=user
spring.datasource.oauth.password=password
설정 이후 아래와 같은 경고메시지가 출력됩니다. 실행하는 데는 문제 없으나 아직(2019년 11월 20일 현재)까지 본 오류를 해제하는 방법을 찾지 못했습니다.
log4jdbc.auto.load.popular.drivers = false로 설정하면 아래의 메시지를 출력하지 않습니다. (댓글을 주신 jk님 감사합니다. 2020년 05월 27일)
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
설정완료 후 실행 예
참고자료
- spring-boot에서 mybatis로 mysql 연동하기
https://taetaetae.github.io/2019/04/21/spring-boot-mybatis-mysql-xml/ - MyBatis 문서 루트 요소 "mapper"은(는) DOCTYPE 루트 "null"과(와) 일치해야 합니다.
https://febdy.tistory.com/49 - Spring Boot + Mybatis에서 쿼리 로그 확인하기
https://smallgiant.tistory.com/59 - [SPRING BOOT] MYBATIS SQL 로그 찍기 - LOG4JDBC
https://romeoh.tistory.com/entry/Spring-boot-mybatis-SQL-%EB%A1%9C%EA%B7%B8-%EC%B0%8D%EA%B8%B0-log4jdbc - [JAVA/Spring] SQL 로그 출력하기
https://freehoon.tistory.com/113
'Tips, Tricks > Java, Spring Framework' 카테고리의 다른 글
Create a File Hash in Java(자바로 파일 해쉬 만들기) (0) | 2020.11.13 |
---|---|
Converting Java ImageIO.write to ImageWriter(Java ImageIO.write를 ImageWriter로 전환하기) (0) | 2020.11.09 |
Spring Boot 프로젝트에 외부 jar 추가 방법(method of including external jar on spring boot maven project) (2) | 2020.04.23 |
TCP Socket Forwarding(Tunneling) by Java Socket (0) | 2020.02.18 |
Spring Boot - MyBatis, 다중 Database 연결 (0) | 2020.02.13 |