2013-04-22 22 views
6

Uso mybatis per eseguire query SQL nel mio progetto. Devo intercettare la query SQL prima dell'esecuzione per applicare alcune modifiche dinamiche. Ho letto su @Interseptors come questo:Come intercettare e modificare dinamicamente la query sql in 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) { 
    } 
} 

Ed intercetta davvero esecuzioni, ma non c'è modo di cambiare query SQL dal campo appropriato non è scrivibile. Dovrei creare una nuova istanza di tutto l'oggetto manualmente per sostituire semplicemente sql query? Dov'è il posto giusto per intercettare l'esecuzione della query per cambiarla in modo dinamico? Grazie.

risposta

0

Si può considerare l'utilizzo di una libreria di template di stringa (ad esempio velocità, manubri, Baffo) per aiutarvi a

Dal ad oggi, c'è anche MyBatis-Velocity (http://mybatis.github.io/velocity-scripting/) per aiutarvi a fare di scripting per l'sql .

0

A seconda delle modifiche che si desidera fare, si consiglia di utilizzare la funzione di dynamic sql mybatis 3

4

Spero che vi aiuterà a:

@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) 
    { 
    } 
} 
Problemi correlati