簡體   English   中英

mybatis中如何攔截子查詢

[英]How to intercept subqueries in mybatis

我想記錄sql語句的執行時間。 為此,我使用了攔截器插件。 然而,它只“捕獲”外部語句並打印執行整個語句所需的組合時間,包括@Result包含的子查詢。 為什么它不單獨記錄所有語句,是否有任何解決方案?

這是重現我的場景的代碼:

阿道:

@Select({
        "select * from a",
        "where id = #{id,jdbcType=INTEGER}"
    })
@Results({
        @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
        @Result(column="id", property="bs", javaType=List.class, many=@Many(fetchType=FetchType.EAGER, select = "org.BDao.selectByAId")),
        @Result(column="id", property="cs", javaType=List.class, many=@Many(fetchType=FetchType.EAGER, select = "org.CDao.selectByAId"))
})
A selectByPrimaryKey(Integer id);

道:

@Select({
    "select * from b",
    "where a_id = #{aId,jdbcType=INTEGER}"
})
@Results({
    ...
})
List<B> selectByAId(Integer aId);

光盤:

@Select({
    "select * from c",
    "where a_id = #{aId,jdbcType=INTEGER}"
})
@Results({
    ...
})
List<C> selectByAId(Integer aId);

攔截器:

@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
public class LogTimeQueryExecutePlugin implements Interceptor {

    static int MAPPED_STATEMENT_INDEX = 0;
    static int PARAMETER_INDEX = 1;
    static int ROWBOUNDS_INDEX = 2;
    static int RESULT_HANDLER_INDEX = 3;

    static Logger logger = LoggerFactory.getLogger(LogTimeQueryExecutePlugin.class);

    public Object intercept(Invocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = invocation.proceed();
        MappedStatement ms = (MappedStatement) invocation.getArgs()[MAPPED_STATEMENT_INDEX];

        logger.info("Execution time "+ms.getId()+" : "+(System.currentTimeMillis() - start)+" ms");

        return proceed;
    }

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

    public void setProperties(Properties properties) {

    }
}

日志:

執行時間 org.ADao.selectByPrimaryKey : 59033 ms

嘗試StatementHandler.class而不是Executor.class

@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class }),
        @Signature(type = StatementHandler.class, method = "update", args = { Statement.class })
})
public class StatementHandlerPlugin implements Interceptor {

    @Override
    public Object intercept(final Invocation invocation) throws Throwable {
        // just for simplification, use safer way
        val stmt = (StatementHandler) invocation.getTarget();
        val boundSql = stmt.getBoundSql(); // contains sql, parameterObject, parameterMappings ...
        // rest of implementation
    }
 
    // omitted
    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM