2013-04-22 16 views
6

Używam mybatis do wykonywania zapytań sql w moim projekcie. Muszę przechwycić kwerendę sql przed wykonaniem, aby zastosować niektóre zmienione dynamicznie. Czytałem o @Interseptors tak:Jak przechwytywać i zmieniać zapytania sql dynamicznie w mybatis

@Intercepts({@Signature(type= Executor.class, method = "query", args = {...})}) 
public class ExamplePlugin implements Interceptor { 
    public Object intercept(Invocation invocation) throws Throwable { 
    return invocation.proceed(); 
    } 
    public Object plugin(Object target) { 
    return Plugin.wrap(target, this); 
    } 
    public void setProperties(Properties properties) { 
    } 
} 

I to naprawdę przechwytuje egzekucje, ale nie ma sposobu, aby zmienić zapytanie sql ponieważ odpowiednie pole nie jest zapisywalny. Czy muszę utworzyć nową instancję całego obiektu, aby zastąpić zapytanie sql? Gdzie jest właściwe miejsce do przechwytywania wykonania kwerendy, aby zmienić ją dynamicznie? Podziękować.

Odpowiedz

0

Można rozważyć przy użyciu biblioteki szablonów string (np Velocity, Kierownice, wąsy), aby pomóc Ci

As z do tej pory, nie ma nawet MyBatis-Velocity (http://mybatis.github.io/velocity-scripting/), aby pomóc zrobić włączony do sql .

0

zależności od zmian, które chcesz zrobić, można użyć dynamic sql cechę mybatis 3

4

Mam nadzieję, że to pomoże:

@Intercepts({ @Signature(type = Executor.class, method = "query", args = { 
     MappedStatement.class, Object.class, RowBounds.class, 
     ResultHandler.class 
    }) 
}) 
public class SelectCountSqlInterceptor2 implements Interceptor 
{ 
    public static String COUNT = "_count"; 
    private static int MAPPED_STATEMENT_INDEX = 0; 
    private static int PARAMETER_INDEX = 1; 
    @Override 
    public Object intercept(Invocation invocation) throws Throwable 
    { 
     processCountSql(invocation.getArgs()); 
     return invocation.proceed(); 
    } 
    @SuppressWarnings("rawtypes") 
    private void processCountSql(final Object[] queryArgs) 
    { 
     if (queryArgs[PARAMETER_INDEX] instanceof Map) 
     { 
      Map parameter = (Map) queryArgs[PARAMETER_INDEX]; 
      if (parameter.containsKey(COUNT)) 
      { 
       MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX]; 
       BoundSql boundSql = ms.getBoundSql(parameter); 
       String sql = ms.getBoundSql(parameter).getSql().trim(); 
       BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), 
                getCountSQL(sql), boundSql.getParameterMappings(), 
                boundSql.getParameterObject()); 
       MappedStatement newMs = copyFromMappedStatement(ms, 
             new OffsetLimitInterceptor.BoundSqlSqlSource(newBoundSql)); 
       queryArgs[MAPPED_STATEMENT_INDEX] = newMs; 
      } 
     } 
    } 
    // see: MapperBuilderAssistant 
    @SuppressWarnings({ "unchecked", "rawtypes" }) 
    private MappedStatement copyFromMappedStatement(MappedStatement ms, 
      SqlSource newSqlSource) 
    { 
     Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms 
       .getId(), newSqlSource, ms.getSqlCommandType()); 
     builder.resource(ms.getResource()); 
     builder.fetchSize(ms.getFetchSize()); 
     builder.statementType(ms.getStatementType()); 
     builder.keyGenerator(ms.getKeyGenerator()); 
     // setStatementTimeout() 
     builder.timeout(ms.getTimeout()); 
     // setParameterMap() 
     builder.parameterMap(ms.getParameterMap()); 
     // setStatementResultMap() 
     List<ResultMap> resultMaps = new ArrayList<ResultMap>(); 
     String id = "-inline"; 
     if (ms.getResultMaps() != null) 
     { 
      id = ms.getResultMaps().get(0).getId() + "-inline"; 
     } 
     ResultMap resultMap = new ResultMap.Builder(null, id, Long.class, 
       new ArrayList()).build(); 
     resultMaps.add(resultMap); 
     builder.resultMaps(resultMaps); 
     builder.resultSetType(ms.getResultSetType()); 
     // setStatementCache() 
     builder.cache(ms.getCache()); 
     builder.flushCacheRequired(ms.isFlushCacheRequired()); 
     builder.useCache(ms.isUseCache()); 
     return builder.build(); 
    } 
    private String getCountSQL(String sql) 
    { 
     String lowerCaseSQL = sql.toLowerCase().replace("\n", " ").replace("\t", " "); 
     int index = lowerCaseSQL.indexOf(" order "); 
     if (index != -1) 
     { 
      sql = sql.substring(0, index); 
     } 
     return "SELECT COUNT(*) from (select 1 as col_c " + sql.substring(lowerCaseSQL.indexOf(" from ")) + ") cnt"; 
    } 
    @Override 
    public Object plugin(Object target) 
    { 
     return Plugin.wrap(target, this); 
    } 
    @Override 
    public void setProperties(Properties properties) 
    { 
    } 
} 
Powiązane problemy