2013-04-22 15 views
6

mybatisを使用してプロジェクトでSQLクエリを実行します。動的に変更されたものを適用するために実行する前にSQLクエリをインターセプトする必要があります。私はこのような@Interseptorsについて読んだ:mybatisでSQLクエリを動的にインターセプトして変更する方法

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

そして、それは本当に実行をインターセプトしますが、適切なフィールドが書き込み可能ではないので、SQLクエリを変更する方法はありません。 SQLクエリを置き換えるために、オブジェクト全体の新しいインスタンスを手動で構築する必要がありますか?クエリの実行を傍受して動的に変更する場所はどこですか?感謝。

答えて

0

あなたがあなたの日付までのよう

を支援するために(例えば速度、ハンドルバー、口ひげ)文字列のテンプレートライブラリを使用して検討することもMyBatisの-速度(http://mybatis.github.io/velocity-scripting/)は、SQLのスクリプトを実行するためにあなたを助けるためにそこにあります。

0

あなたがしたいの変化に応じて、私はそれはあなたを助けることを願っていますMyBatisの3

4

dynamic sql機能を使用することもできます。

@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) 
    { 
    } 
} 
関連する問題