如何在MyBatis中选择动态fetchSize

时间:2019-05-30 00:05:45

标签: java sql select dynamic mybatis

我们想动态地对特定查询设置fetchSize,以便可以在运行时根据诸如打开的总线程数之类的前提条件来传递大小值。

当前,我们正在使用MyBatis 3.4 ilbrary。

下面是我们在应用程序中使用的查询的快照。

<select id="fetchDetails" resultType="ItemInformation" useCache="true" timeout="100000" fetchSize="50" statementType="PREPARED">

  SELECT * FROM PR_STAGE
  where 1=1
    AND release_date &gt;= sys_extract_utc(FROM_TZ(cast(TO_DATE(#{fromDate}, 'DD-MON-YYYY HH24:MI:SS')as timestamp),'America/Los_Angeles') )
    AND release_date &lt;= sys_extract_utc(FROM_TZ(cast(TO_DATE(#{toDate}, 'DD-MON-YYYY HH24:MI:SS')as timestamp),'America/Los_Angeles') )

</select>

1 个答案:

答案 0 :(得分:0)

您可以编写一个插件。

import java.sql.Statement;
import java.util.Properties;

import org.apache.ibatis.executor.statement.StatementHandler;
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;

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

  private static final ThreadLocal<Integer> FETCH_SIZE = 
      ThreadLocal.withInitial(() -> 100);

  public static void setFetchSize(int fetchSize) {
    FETCH_SIZE.set(Integer.valueOf(fetchSize));
  }

  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    Statement statement = (Statement) invocation.getArgs()[0];
    statement.setFetchSize(FETCH_SIZE.get());
    return invocation.proceed();
  }

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

  @Override
  public void setProperties(Properties properties) {
  }
}

要注册插件,请将以下条目添加到XML配置中...

<plugins>
  <plugin interceptor="pkg.FetchSizePlugin" />
</plugins>

...或致电org.apache.ibatis.session.Configuration#addInterceptor()

注册了插件后,您可以在执行查询之前调用FetchSizePlugin.setFetchSize()来设置获取大小。

  • 如果不调用该方法,将使用通过withInitial()设置的值。
  • 由于它使用ThreadLocal,因此除非您重新设置另一个值,否则您设置的提取大小将应用于同一线程中的所有后续查询。