쿼리 검수를 위해 mybatis 플러그인에 아래 interceptor를 추가
- 바인딩 변수에 값이 맵핑되어 있는 쿼리문 출력가능
@Intercepts({ @Signature(type = StatementHandler.class, method = "update", args = { Statement.class }), | |
@Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class }) }) | |
public class MybatisSqlLogInterceptor implements Interceptor { | |
private static Logger sqlLog = LoggerFactory.getLogger("MYBATIS_SQL_LOG"); | |
@Override | |
public Object intercept(Invocation invocation) throws Throwable { | |
StatementHandler handler = (StatementHandler) invocation.getTarget(); | |
String sql = bindSql(handler); // SQL 추출 | |
sqlLog.info("====================================================================="); | |
sqlLog.info("{} ", sql); | |
sqlLog.info("====================================================================="); | |
return invocation.proceed(); | |
} | |
/** | |
* <pre> | |
* bindSql | |
* | |
* <pre> | |
* | |
* @param boundSql | |
* @param sql | |
* @param param | |
* @return | |
* @throws NoSuchFieldException | |
* @throws IllegalAccessException | |
*/ | |
@SuppressWarnings("rawtypes") | |
private String bindSql(StatementHandler handler) throws NoSuchFieldException, IllegalAccessException { | |
BoundSql boundSql = handler.getBoundSql(); | |
// 쿼리실행시 맵핑되는 파라미터를 구한다 | |
Object param = handler.getParameterHandler().getParameterObject(); | |
// 쿼리문을 가져온다(이 상태에서의 쿼리는 값이 들어갈 부분에 ?가 있다) | |
String sql = boundSql.getSql(); | |
// 바인딩 파라미터가 없으면 | |
if (param == null) { | |
sql = sql.replaceFirst("\\?", "''"); | |
return sql; | |
} | |
// 해당 파라미터의 클래스가 Integer, Long, Float, Double 클래스일 경우 | |
if (param instanceof Integer || param instanceof Long || param instanceof Float || param instanceof Double) { | |
sql = sql.replaceFirst("\\?", param.toString()); | |
} | |
// 해당 파라미터의 클래스가 String인 경우 | |
else if (param instanceof String) { | |
sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
} | |
// 해당 파라미터의 클래스가 Map인 경우 | |
else if (param instanceof Map) { | |
List<ParameterMapping> paramMapping = boundSql.getParameterMappings(); | |
for (ParameterMapping mapping : paramMapping) { | |
String propValue = mapping.getProperty(); | |
Object value = ((Map) param).get(propValue); | |
if (value == null) { | |
continue; | |
} | |
if (value instanceof String) { | |
sql = sql.replaceFirst("\\?", "'" + value + "'"); | |
} else { | |
sql = sql.replaceFirst("\\?", value.toString()); | |
} | |
} | |
} | |
// 해당 파라미터의 클래스가 사용자 정의 클래스인 경우 | |
else { | |
List<ParameterMapping> paramMapping = boundSql.getParameterMappings(); | |
Class<? extends Object> paramClass = param.getClass(); | |
for (ParameterMapping mapping : paramMapping) { | |
String propValue = mapping.getProperty(); | |
Field field = paramClass.getDeclaredField(propValue); | |
field.setAccessible(true); | |
Class<?> javaType = mapping.getJavaType(); | |
if (String.class == javaType) { | |
sql = sql.replaceFirst("\\?", "'" + field.get(param) + "'"); | |
} else { | |
sql = sql.replaceFirst("\\?", field.get(param).toString()); | |
} | |
} | |
} | |
// return sql | |
return sql; | |
} | |
@Override | |
public Object plugin(Object target) { | |
return Plugin.wrap(target, this); | |
} | |
@Override | |
public void setProperties(Properties properties) { | |
} | |
} |
[SQL Map Config]
<?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="cacheEnabled" value="false" />
<setting name="useGeneratedKeys" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
</settings>
<plugins>
<plugin interceptor="com.test.common.mybatis.MybatisSqlLogInterceptor"/>
</plugins>
</configuration>
[Logback Config]
<appender name="MYBATIS_SQL_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>/home/test/${SERVER_NAME}/tomcat/logs/sql/mybatis_sql.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/home/test/${SERVER_NAME}/tomcat/logs/sql/mybatis_sql.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>%m%n</Pattern>
</encoder>
</appender>
<logger name="MYBATIS_SQL_LOG" level="info" additivity="false">
<appender-ref ref="MYBATIS_SQL_LOG_FILE" />
</logger>'프로그래밍' 카테고리의 다른 글
Spring Controller 테스트 하기 (MockMvc 사용) (0) | 2016.05.18 |
---|---|
Thread 생성 비용이 큰 이유 (0) | 2016.04.06 |
CronExpression Test 하기 (0) | 2016.03.17 |
jedis returnBrokenResource 메서드에 대한 오해 (0) | 2016.03.09 |
비트단위의 논리곱을 이용한 데이터 활용 방법 - 논리곱(and) & (1) | 2016.01.31 |
진수 변환 (0) | 2016.01.26 |
MyBatis 샾(#) 달러($) 차이 (4) | 2016.01.21 |
tag 라이브러리 동작 원리에 대해서 생각해 보자 (0) | 2016.01.18 |