티스토리 뷰

Mybatis

mybatis interceptor를 이용 한 rowbounds 쿼리 확장

코더와개발자사이 2016. 7. 22. 13:53

mybati의 rowbounds 만 쓴다면 원하는 페징 처리를 할 수 있지만 토탈값은 가져 올 수 없어 따로 토탈 카운트를 갖기 위한 쿼리를 수행 한다든지 다른 작업을 해줘야 할 것 이다 여러 처리 방법이 있겠지만 메타 핸들러를 이용한 처리 방법도 있다

방법은 단순하다 중간에 쿼리를 가로 채어 필요한 커버 쿼리를 붙여 주는 작업을 하고

쿼리를 실행한다

 

--datasource-context.xml

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="mapperLocations" value="classpath*:query/*-query.xml" />
  <property name="plugins">
            <array>
                <bean class="com.youjin.interceptor.MybatisInterCepter"/>
            </array>
        </property>
 </bean>

 

 

--java 소스

package com.youjin.interceptor;

import java.sql.Connection;
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;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.youjin.menu.HomeController;

@Intercepts({
 @Signature(type = StatementHandler.class, method = "prepare", args= {Connection.class})
})
public class MybatisInterCepter implements Interceptor {
 
 private static final Logger logger = LoggerFactory.getLogger(MybatisInterCepter.class);
 
 private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
 private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();

 @Override
 public Object intercept(Invocation invocation) throws Throwable {
  StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
  MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
  String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
  RowBounds rb = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");

//rowbounds 유무 확인
  if(rb == null || rb == rb.DEFAULT){
   logger.debug(originalSql);
   return invocation.proceed();
  }


  StringBuffer sb = new StringBuffer();
  sb.append("select * from ( \n");
  sb.append("select @RNUM:=@RNUM+1 as rownum, one.*, tt.* from ( \n");
  sb.append(originalSql+") one, (SELECT @RNUM := 0) R, (select count(seq) AS tt_count from menutable) tt \n");
  sb.append(") two \n");
  sb.append("where ").append(rb.getOffset()).append(" < two.rownum \n");
  sb.append("limit ").append(rb.getLimit());
  
  metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
        metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
  metaStatementHandler.setValue("delegate.boundSql.sql", sb.toString());
  logger.debug(sb.toString());
  
  return invocation.proceed();
 }

 @Override
 public Object plugin(Object target) {
  return Plugin.wrap(target, this);
 }

 @Override
 public void setProperties(Properties arg0) {
 }

}

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함