2013-04-22 18 views
6

Projemde sql sorguları gerçekleştirmek için mybatis kullanıyorum. Dinamik olarak değiştirilmiş bazı uygulamak için yürütmeden önce sql sorgusunu engellemem gerekir. Böyle @Interseptors hakkında okudum:Mybatis'te sql sorgusu dinamik olarak nasıl engellenir ve değiştirilir

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

Ve gerçekten infaz karşılar, ancak uygun alan yazılabilir değil çünkü sql sorgusunu değiştirmek için bir yolu yoktur. Yalnızca sql sorgusunu değiştirmek için tüm nesnenin yeni örneğini oluşturmalı mıyım? Dinamik olarak değiştirmek için sorgu yürütme engellemek için doğru yer neresidir? Teşekkür.

cevap

0

Sen, hatta MyBatis-Hız (http://mybatis.github.io/velocity-scripting/) bulunmaktadır sql için komut oluşturmanız yardımcı olmak için size bugüne kadar itibariyle

yardımcı olacak bir dize şablon kitaplığı (örn Hız, Gidon, Bıyık) kullanmayı düşünebilirsiniz .

0

Yapmak istediğiniz değişikliklere bağlı olarak, sen mybatis ait dynamic sql özelliğini kullanmak isteyebilirsiniz 3

4

Sana yardım umuyoruz:

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