2010-04-14 29 views
18

有什么方法可以让我执行查询iBatis?我想重复查询一个UNION查询。iBatis得到执行sql

例如:

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

当我通过

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

执行查询,我希望得到SELECT username, password FROM table WHERE id=1

有什么办法,我可以得到查询?

谢谢。

回答

2

大多数SQL引擎允许您“记录”所有执行的查询(通常包含有关查询花费的时间,返回的结果数量等信息)。你有权访问你的引擎的日志,你可以配置它,以便记录你所需要的一切吗?

+0

这可能是可能的(日志查询,然后读取它),但假设用户正在使用系统同时,我不知道我需要什么查询(查询是根据用户需求执行的)。我需要获取查询,因为我将重复使用它作为UNION查询(使用值) – qaxi 2010-04-14 05:30:50

1

您可以使用p6spyjdbcdslog

+0

感谢jdbcdslog正是我所期待的。 – 2012-05-22 15:47:59

10

它可以显示此信息.iBatis使用一些日志框架,包括Log4J
要使用Log4J在类path.You've创建文件log4j.properties把下一行的文件中,例如:

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 

对于其他日志框架和细节信息看this link

+0

太棒了!谢谢:) – agpt 2015-01-29 07:14:41

+0

看起来像是你的答案中的错误,在文档中提到了属性'log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = DEBUG',但在你的答案中你正在使用' log4j.logger.com.ibatis.SQL Map.engine.impl.SQL MapClientDelegate = DEBUG'这似乎不是一个有效的log4j配置。 – dhblah 2016-03-23 11:06:05

9

此加入你的log4j.xml文件,你可以在控制台上看到输出。

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

您将看到正在传递的参数,正在执行的查询以及查询的输出。

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; 
      } 
     } 

    } 

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

6

SqlSessionFactory获取Configuration对象,则:

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

使用这篇文章的信息来调试DefaultSqlSession的selectList(),其中MappedStatement是和使用表达式: ms.getBoundSql(parameter).getSql(); – jp093121 2015-02-27 15:44:01