'mybatis'에 해당되는 글 8건

  1. 2011.10.12 mybatis 쿼리, 쿼리결과 로깅을 위한 log4j.xml 설정
  2. 2011.09.06 mybatis dynamic query 조건에서 in 조건 사용하기
  3. 2011.08.29 mybatis interceptor 를 이용해서 쿼리로그를 디비에다 저장하기 2

mybatis 쿼리, 쿼리결과 로깅을 위한 log4j.xml 설정


<logger name="java.sql.Connection">
	<level value="debug" />
</logger>

<logger name="java.sql.Statement">
	<level value="debug" />
</logger>

<logger name="java.sql.PreparedStatement">
	<level value="debug" />
</logger>

<logger name="java.sql.ResultSet">
	<level value="debug" />
</logger>


요걸 log4j.xml 파일에 설정해 추가해 주면 실행되는 쿼리랑 쿼리 결과를 로깅할 수 있다.



※ java.sql.ResultSet 에 대한 로깅을 하면 Oracle CLOB 같은 스트림성 컬럼을 SELECT 할때  stream has already been closed 익셉션이 날수 있다.

※ java.sql.ResultSet 에 대한 로깅설정을 지우면 쿼리 결과에 대한 로깅은 제외된다.

mybatis dynamic query 조건에서 in 조건 사용하기


dynamic query 에서 조건 태그에 들어가는 비교 연산자 뭐 흔히 사용하는 == ,  != ,  > ,  <  , <=  뭐 이런것들이 있다.

이런 기본적인것 이외에도 in 이라는 연산자가 있는데

이것을 이용하면 기존 or 로 비교구문을 쭉 이어서 썼던것을 단순하게 처리할수 있을것 같았다.

그걸 사용해 볼려고 User Guide를 보니 하니 뭔놈에 설명이 하나도 안되있고

검색어로 넣을 만한 단어거 너무 일반적이라서 구글에게 물어보기도 힘들었다.

처음에는 query 에서 쓰는것 처럼 <if test="param1 in ('a', 'b'. 'c', 'd')">쿼리</if>  요런식으로 해 보니까 에러는 안나지만 정상적으로 비교되지 않았다.



그러다가 문득

    쿼리

요렇게 ( ) 을 { } 으로 바꿔서 해보았다.

잘된다 -_-;;


내가 못찾아서 그런가  mybatis 는 설명이 너무 허약한것 같다.

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

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

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

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

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

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

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


인터셉터(update 성 쿼리가 실행될때 인터셉트!)
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 의 소스를 보면
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

 
prev 1 2 next