2010-04-14 37 views
18

¿Hay alguna forma en que pueda obtener la consulta ejecutada de iBatis? Quiero reutilizar la consulta para una consulta UNION.iBatis se ejecuta sql

Por ejemplo:

<sqlMap namespace="userSQLMap"> 
    <select id="getUser" resultClass="UserPackage.User"> 
     SELECT username, 
       password 
     FROM table 
     WHERE id=#value# 
    </select> 
</sqlMap> 

Y cuando yo haga la consulta a través

int id = 1 
List<User> userList = queryDAO.executeForObjectList("userSQLMap.getUser",id) 

quiero conseguir SELECT username, password FROM table WHERE id=1

¿Hay alguna manera de que pudiera conseguir la consulta?

Gracias.

Respuesta

2

La mayoría de los motores SQL le permiten "registrar" todas las consultas ejecutadas (generalmente junto con información sobre el tiempo que tomó la consulta, el número de resultados que devolvió y similares). ¿Tiene acceso a los registros de su motor y puede configurarlo para que registre todo lo que necesita?

+0

que podría ser posible (log la consulta y luego leerlo), pero se supone que los usuarios están utilizando el sistema al mismo tiempo, no sabré qué consulta necesito obtener (las consultas se ejecutan según la demanda del usuario). Necesito obtener la consulta porque la reutilizaré para una consulta UNION (con los valores) – qaxi

1

Puede usar p6spy o jdbcdslog para eso.

+0

Gracias jdbcdslog es exactamente lo que estaba buscando. –

10

Es posible mostrar esta información. IBatis utiliza un poco del marco de trabajo de registro que incluye Log4J.
Para utilizar Log4J crear el archivo log4j.properties en el path.You've clase para poner las siguientes líneas en el archivo, por ejemplo:

log4j.logger.com.ibatis=DEBUG 
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG 
     
log4j.logger.com.ibatis=DEBUG 
log4j.logger.java.sql.Connection=DEBUG 
log4j.logger.java.sql.Statement=DEBUG 
log4j.logger.java.sql.PreparedStatement=DEBUG 
log4j.logger.java.sql.ResultSet=DEBUG 

Por otro marco de registro y la información de detalle ver this link

+0

¡Genial! Gracias :) – agpt

+0

parece que es un error en su respuesta, en la documentación se menciona la propiedad 'log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = DEPURACIÓN', pero en su respuesta está usando' log4j.logger.com.ibatis.SQL Map.engine.impl.SQL MapClientDelegate = DEBUG' que no parece ser una configuración de log4j válida. – dhblah

9

añadir esto a su archivo log4j.xml y puede ver el resultado en la consola.

<logger name="java.sql" additivity="false"> 
    <level value="debug" /> 
    <appender-ref ref="console" /> 
</logger> 

Verá los parámetros que se pasan, la consulta se está ejecutando y el resultado de la consulta.

3
import java.util.Properties; 
    import org.apache.ibatis.executor.Executor; 
    import org.apache.ibatis.mapping.BoundSql; 
    import org.apache.ibatis.mapping.MappedStatement; 
    import org.apache.ibatis.mapping.MappedStatement.Builder; 
    import org.apache.ibatis.mapping.SqlSource; 
    import org.apache.ibatis.plugin.Interceptor; 
    import org.apache.ibatis.plugin.Intercepts; 
    import org.apache.ibatis.plugin.Invocation; 
    import org.apache.ibatis.plugin.Plugin; 
    import org.apache.ibatis.plugin.Signature; 
    import org.apache.ibatis.session.ResultHandler; 
    import org.apache.ibatis.session.RowBounds; 

    import com.gm.common.orm.mybatis.dialect.Dialect; 
    import com.gm.common.utils.PropertiesHelper; 

    /** 
    * 为Mybatis提供基于方言(Dialect)的分页查询的插件 
    * 
    * 将拦截Executor.query()方法实现分页方言的插入. 
    * 
    * 配置文件内容: 
    * 
    * <pre> 
    * &lt;plugins> 
    * &lt;plugin interceptor="com.gm.common.orm.mybatis.plugin.OffsetLimitInterceptor"> 
    *  &lt;property name="dialectClass" value="com.gm.common.orm.mybatis.dialect.MySQLDialect"/> 
    * &lt;/plugin> 
    * &lt;/plugins> 
    * </pre> 
    */ 

    @Intercepts({@Signature(type=Executor.class,method="query",args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})}) 
    public class OffsetLimitInterceptor implements Interceptor { 
     static int MAPPED_STATEMENT_INDEX = 0; 
     static int PARAMETER_INDEX = 1; 
     static int ROWBOUNDS_INDEX = 2; 
     static int RESULT_HANDLER_INDEX = 3; 

     Dialect dialect; 

     public Object intercept(Invocation invocation) throws Throwable { 
      processIntercept(invocation.getArgs()); 
      return invocation.proceed(); 
     } 

     void processIntercept(final Object[] queryArgs) { 
      // queryArgs = query(MappedStatement ms, Object parameter, RowBounds 
      // rowBounds, ResultHandler resultHandler) 
      MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX]; 
      Object parameter = queryArgs[PARAMETER_INDEX]; 
      final RowBounds rowBounds = (RowBounds) queryArgs[ROWBOUNDS_INDEX]; 
      int offset = rowBounds.getOffset(); 
      int limit = rowBounds.getLimit(); 

      if (dialect.supportsLimit() 
        && (offset != RowBounds.NO_ROW_OFFSET || limit != RowBounds.NO_ROW_LIMIT)) { 
       BoundSql boundSql = ms.getBoundSql(parameter); 
       String sql = boundSql.getSql().trim(); 
       if (dialect.supportsLimitOffset()) { 
        sql = dialect.getLimitString(sql, offset, limit); 
        offset = RowBounds.NO_ROW_OFFSET; 
       } else { 
        sql = dialect.getLimitString(sql, 0, limit); 
       } 
       limit = RowBounds.NO_ROW_LIMIT; 

       queryArgs[ROWBOUNDS_INDEX] = new RowBounds(offset, limit); 
       BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), 
         sql, boundSql.getParameterMappings(), boundSql 
           .getParameterObject()); 
       MappedStatement newMs = copyFromMappedStatement(ms, 
         new BoundSqlSqlSource(newBoundSql)); 
       queryArgs[MAPPED_STATEMENT_INDEX] = newMs; 
      } 
     } 

     // see: MapperBuilderAssistant 
     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()); 
      builder.keyProperty(ms.getKeyProperty()); 

      // setStatementTimeout() 
      builder.timeout(ms.getTimeout()); 

      // setStatementResultMap() 
      builder.parameterMap(ms.getParameterMap()); 

      // setStatementResultMap() 
      builder.resultMaps(ms.getResultMaps()); 
      builder.resultSetType(ms.getResultSetType()); 

      // setStatementCache() 
      builder.cache(ms.getCache()); 
      builder.flushCacheRequired(ms.isFlushCacheRequired()); 
      builder.useCache(ms.isUseCache()); 

      return builder.build(); 
     } 

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

     public void setProperties(Properties properties) { 
      String dialectClass = new PropertiesHelper(properties) 
        .getRequiredString("dialectClass"); 
      try { 
       dialect = (Dialect) Class.forName(dialectClass) 
         .newInstance(); 
      } catch (Exception e) { 
       throw new RuntimeException(
         "cannot create dialect instance by dialectClass:" 
           + dialectClass, e); 
      } 
      System.out.println(OffsetLimitInterceptor.class.getSimpleName() 
        + ".dialect=" + dialectClass); 
     } 

     public static class BoundSqlSqlSource implements SqlSource { 
      BoundSql boundSql; 

      public BoundSqlSqlSource(BoundSql boundSql) { 
       this .boundSql = boundSql; 
      } 

      public BoundSql getBoundSql(Object parameterObject) { 
       return boundSql; 
      } 
     } 

    } 

Mi referencia: https://www.java2s.com/Open-Source/Java-Document-2/UnTagged/gmc/com/gm/common/orm/mybatis/plugin/OffsetLimitInterceptor.java.htm

6

obtener el objeto Configuration de su SqlSessionFactory, entonces:

MappedStatement ms = configuration.getMappedStatement("MyMappedStatementId"); 
BoundSql boundSql = ms.getBoundSql(parameters); // pass in parameters for the SQL statement 
System.out.println("SQL" + boundSql.getSql()); 
+2

Utilicé la información de esta publicación para depurar la lista de selección de DefaultSqlSession() donde MappedStatement está y usé la expresión: ms.getBoundSql (parameter) .getSql(); – jp093121

Cuestiones relacionadas