Java JDBC AS/400仅获取第一[x]行不用于区分preparedStatement缓存
我正在使用连接池连接到AS/400。我试图用一个准备好的语句获取动态数量的订单。当我使用语句参数定义要获取的最大订单数时,似乎发生了某种缓存。在第一次调用中,我得到了正确的订单数量,但是在接下来的调用中,即使我更改了要获取的最大订单数量,我也得到了与第一次调用相同的数量。如果我在每次通话中都打开一个新的连接,一切都正常。如果在数据源上调用setReuseConnections(false),则一切正常。如果我删除“fetchfirst[x]ROWS ONLY”语句的参数,并在SQL文本中使用占位符,替换为每次调用获取的最大顺序数,则一切正常 发生了什么样的缓存?我可以换一种方式吗?这是虫子吗 这是一个示例应用程序,您只需连接一个AS/400数据库即可Java JDBC AS/400仅获取第一[x]行不用于区分preparedStatement缓存,java,jdbc,jt400,Java,Jdbc,Jt400,我正在使用连接池连接到AS/400。我试图用一个准备好的语句获取动态数量的订单。当我使用语句参数定义要获取的最大订单数时,似乎发生了某种缓存。在第一次调用中,我得到了正确的订单数量,但是在接下来的调用中,即使我更改了要获取的最大订单数量,我也得到了与第一次调用相同的数量。如果我在每次通话中都打开一个新的连接,一切都正常。如果在数据源上调用setReuseConnections(false),则一切正常。如果我删除“fetchfirst[x]ROWS ONLY”语句的参数,并在SQL文本中使用占位
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;
}
}
package com.richeliu.web.test.as400;
导入java.math.BigDecimal;
导入java.sql.Connection;
导入java.sql.PreparedStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入javax.sql.DataSource;
导入com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
公共类CachingPreparedStatement{
//数据库连接信息
私有静态最终字符串服务器_NAME=“”;
私有静态最终字符串libraries=“”;
私有静态最终字符串USER=“”;
私有静态最终字符串密码=”;
//查询参数
私有静态最终BigDecimal日期_FROM=新的BigDecimal(“20170701000000”);/(格式:YYYYMMDDHHMMSS)
私有静态最终整数最大顺序计数1=1;
私有静态最终整数最大顺序计数2=2;
私有静态最终整数最大顺序计数3=3;
私有静态最终字符串选择带有顺序计数参数的=
“从其中选择>=?按SCCONO订购?仅获取第一行”;
公共静态void main(字符串[]args){
DataSource ds=initDataSource();
System.out.println(“使用参数进行测试:”);
testFetchOrdersWithMaxOrderCountParam(ds,最大订单计数1);
testFetchOrdersWithMaxOrderCountParam(ds,最大订单计数2);
testFetchOrdersWithMaxOrderCountParam(ds,最大订单计数3);
testFetchOrdersWithMaxOrderCountParam(ds,最大订单计数1);
testFetchOrdersWithMaxOrderCountParam(ds,最大订单计数2);
testFetchOrdersWithMaxOrderCountParam(ds,最大订单计数3);
}
私有静态void testFetchOrdersWithMaxOrderCountParam(数据源ds,int-maxOrderCount){
try(Connection=ds.getConnection()){
int actuallordercount=fetchOrdersWithMaxOrderCountParam(连接、日期、maxOrderCount);
System.out.println(String.format(“订单计数:%d”,actualOrderCount));
}捕获(SQLException pEx){
抛出新的运行时异常(pEx.getMessage(),pEx);
}
}
公共静态int-fetchOrdersWithMaxOrderCountParam(连接pConnection、BigDecimal-dateFrom、int-maxOrderCount){
try(PreparedStatement语句=pConnection.prepareStatement(选择带有顺序计数参数的语句)){
语句。setBigDecimal(1,dateFrom);
语句.setInt(2,maxOrderCount);
int orderCount=0;
try(ResultSet rs=statement.executeQuery()){
while(rs.next()){
orderCount++;
}
}
退货订单数量;
}捕获(SQLException pEx){
抛出新的运行时异常(pEx.getMessage(),pEx);
}
}
私有静态AS400JDBCManagedConnectionPoolDataSource initDataSource(){
AS400JDBCManagedConnectionPoolDataSource ds=新的AS400JDBCManagedConnectionPoolDataSource(服务器名称、用户、密码);
ds.setLibraries(图书馆);
ds.setMinPoolSize(1);
ds.setMaxPoolSize(2);
//ds.标准(0);
//ds.大小(0);
//ds.标准(0);
//ds.setExtendedDynamic(false);
//ds.setReuseConnections(false);//我找到的唯一解决“缓存”问题的设置
返回ds;
}
}
提前感谢。如果我理解正确,您准备一个maxOrderCount等于10的语句,执行该语句并返回10个Results,但是如果您再次准备语句并指定5,您仍然返回10个Reslut?完全正确!这就像不考虑语句的“fetchfirst…ROWS ONLY”部分来判断第二条语句与第一条语句是否不同。所以它认为第一句话很好。。。