mybatis interceptor 를 이용해서 쿼리로그를 디비에다 저장하기

시스템에서 실행되는 update, insert 등의 쿼리에 대해서 실행된 쿼리를 로그쌓기 전용 데이터베이스에 넣어 주세요~ 라는 요구사항을 받았다.

 뭐 Log4j 같은 것으로 DB로 로깅하는걸 문득 떠올려 보긴 했지만 고건 쫌 안될것 같고..

생각하다 보니 문득 mybatis 설정파일 설명에서 어렴풋이 보았던 plugin 태그가 생각났다. 고걸 이용하는 방법이다. 

plugin 이란게 보니까 spring 의 interceptor 랑 비스무리한것 같다. 여러가지 경우가 미리 정의되 있고 특정 경우를 처리할 Interceptor 를 구현하면 되는것 같다.

이것저것 설명하는 것 보다 일단 실제 설정파일의 설정부분과 소스부분을 보자.

mybatis 설정 xml 중 plugin 설정 부분
1
2
3
<plugins>
    <plugin interceptor="com.tistory.stove99.UpdateInterceptor"/>
</plugins>


인터셉터(update 성 쿼리가 실행될때 인터셉트!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.tistory.stove99;
 
import java.sql.Statement;
import java.util.Properties;
 
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
 
@Intercepts({@Signature(type=StatementHandler.class, method="update", args={Statement.class})})
public class UpdateInterceptor implements Interceptor{
     
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler handler = (StatementHandler)invocation.getTarget();
         
        // 쿼리
        String sql = handler.getBoundSql().getSql();
         
        // 쿼리실행시 맵핑되는 파라메터들
        String param = handler.getParameterHandler().getParameterObject()!=null ?
                             handler.getParameterHandler().getParameterObject().toString() : "";
         
        // DB에다 로그 insert
        /////////////////
        ////////////////
         
        return invocation.proceed();
    }
 
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
 
    @Override
    public void setProperties(Properties properties) {
    }
}

org.apache.ibatis.plugin.Interceptor 인터페이스를 implements 해서 intercept, plugin, setProperties 메소드를 구현해 주면 된다.
그리고 상단에 @Signature 어노테이션은 아마도 인터셉트할 시점에 대한 설정인것 같다. 


@Signature 설정시 type으로 설정할수 있는것은

Executor.class, ParameterHandler.class, ResultSetHandler.class, StatementHandler.class 요렇게

4가지가 있고 어떤것인가는 각자의 필에 따라~~ 대충 이해하면 된다.




method 에 설정할 수 있는것은 예제소스에서 type으로 설정한 StatementHandler.class 의 소스를 보면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface StatementHandler {
 
  Statement prepare(Connection connection)
      throws SQLException;
 
  void parameterize(Statement statement)
      throws SQLException;
 
  void batch(Statement statement)
      throws SQLException;
 
  int update(Statement statement)
      throws SQLException;
 
  List query(Statement statement, ResultHandler resultHandler)
      throws SQLException;
 
  BoundSql getBoundSql();
 
  ParameterHandler getParameterHandler();
 
}

요런 인터페스이다. 짐작할 수 있겠지만 @Signature 어노테이션에서 method와 args 에 설정한 것은 요 인터페이스에 있는 메소드중 하나에 대해서
정의를 한것이다.


대충 눈치로 이해를 해 보자면

@Signature(type=StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})

요래 설정을 하면 실행되는 쿼리들중 select 쿼리가 실행됬을때 고것을 인터셉트 할것이다.




다른 type 들에 어떤 메소드들이 있는지는 소스를 보면 된다 -_-

mybatis API 문서를 봐도 될것 같은데 나의 검색범위 내에서는 API 문서를 못 찾겠다.
분명 어딘가에 있을건데 이상하게 잘 검색이 안되네 -_-;;

공식 문서는 아닌것 같고 아쉬운데로 요기라도~~



※ 첨부파일로 첨부된 User Guide 17 페이지를 보면 자세한 설명은 없고 쥐똥만큼은 설명이 되 있다~ 참고할 사람은 참고하길~~~

MyBatis-3-User-Guide.pdf

 


Article Category

분류 전체보기 (223)
이클립 (28)
maven (9)
Spring (7)
Java (26)
mybatis (8)
jQuery Plugi.. (8)
Javascript (14)
Javascript 예.. (12)
CSS (2)
잡다구리 샘플 (4)
쓸만한지식 (81)
Ubuntu serve.. (22)
쇼핑물건 평가 (1)

Recent Article