JDBC AS / 400 FETCH FIRST [x] ROWS仅用于区分preparedStatement缓存

时间:2017-07-05 20:14:13

标签: java jdbc jt400

我正在使用连接池连接到AS / 400。我试图用准备好的语句获取动态数量的订单。当我使用statement参数来定义要获取的最大订单数时,似乎发生了某种类型的缓存。在第一次通话时,我得到正确的订单数量,但在接下来的通话中,即使我更改了要获取的最大订单数量,我也会获得与第一次通话相同的计数。如果我在每次通话时打开一个新连接,一切正常。如果我在数据源上调用setReuseConnections(false),一切正常。如果我删除“FETCH FIRST [x] ROWS ONLY”语句的参数并在SQL文本中使用占位符替换为每次调用时要获取的最大订单数,那么一切正常。

正在进行什么样的缓存?我可以用另一种方式绕过它吗?这是一个错误吗?

这是一个示例应用程序,您只需要连接的AS / 400数据库!

package com.richelieu.web.test.as400;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;

public class CachingPreparedStatement {

    // Database connection info
    private static final String SERVER_NAME = "<server ip address>";
    private static final String LIBRAIRIES = "<library name>";
    private static final String USER = "<user name>";
    private static final String PASSWORD = "<password>";

    // Query parameters
    private static final BigDecimal DATE_FROM = new BigDecimal("20170701000000"); //(format: YYYMMDDHHMMSS)
    private static final int MAX_ORDER_COUNT_1 = 1;
    private static final int MAX_ORDER_COUNT_2 = 2;
    private static final int MAX_ORDER_COUNT_3 = 3;

    private static final String SELECT_WITH_ORDER_COUNT_PARAM =
            "SELECT <column> FROM <table> WHERE <tsinsert> >= ? ORDER BY SCCONO FETCH FIRST ? ROWS ONLY";

    public static void main(String[] args) {
        DataSource ds = initDataSource();
        System.out.println("Test with param:");
        testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_1); 
        testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_2);
        testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_3);
        testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_1);
        testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_2);
        testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_3);
    }

    private static void testFetchOrdersWithMaxOrderCountParam(DataSource ds, int maxOrderCount) {
        try (Connection connection = ds.getConnection()) {
            int actualOrderCount = fetchOrdersWithMaxOrderCountParam(connection, DATE_FROM, maxOrderCount);
            System.out.println(String.format("Order count: %d", actualOrderCount));
        } catch (SQLException pEx) {
            throw new RuntimeException(pEx.getMessage(), pEx);
        }
    }

    public static int fetchOrdersWithMaxOrderCountParam(Connection pConnection, BigDecimal dateFrom, int maxOrderCount) {
        try (PreparedStatement statement = pConnection.prepareStatement(SELECT_WITH_ORDER_COUNT_PARAM)) {
            statement.setBigDecimal(1, dateFrom);
            statement.setInt(2, maxOrderCount);
            int orderCount = 0;
            try (ResultSet rs = statement.executeQuery()) {
                while(rs.next()) {
                    orderCount++;
                }
            }
            return orderCount;
        } catch (SQLException pEx) {
            throw new RuntimeException(pEx.getMessage(), pEx);
        } 
    }

    private static AS400JDBCManagedConnectionPoolDataSource initDataSource() {
        AS400JDBCManagedConnectionPoolDataSource ds = new AS400JDBCManagedConnectionPoolDataSource(SERVER_NAME, USER, PASSWORD);
        ds.setLibraries(LIBRAIRIES);
        ds.setMinPoolSize(1);
        ds.setMaxPoolSize(2);
        //ds.setBlockCriteria(0);
        //ds.setBlockSize(0);
        //ds.setBlockCriteria(0);
        //ds.setExtendedDynamic(false);
        //ds.setReuseConnections(false); // only setting I found to resolve my "caching" problem
        return ds;
    }
}

提前致谢。

0 个答案:

没有答案