我使用Axis2和Apache Tomcat。我需要的Web服务的客户端能够查询数据库,所以我认为,通过将下面的资源到Tomcat的情况下,它会自动创建一个连接池在互联网上找到:PreparedStatement和Axis2
Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" removeAbandoned="true" removeAbandonedTimeout="30" maxActive="80" maxIdle="30" maxWait="10000" username="user" password="" driverClassName="org.postgresql.Driver" url = "jdbc:postgresql://localhost:5432/mydb" useUnicode="true" characterEncoding="utf-8" characterSetResults="utf8" validationQuery="/* ping */ SELECT 1"
它似乎正在工作,但现在我想要做的是重复使用相同的PreparedStatement,因此每次客户端发出请求时都不会进行分析。所以,我使PreparedStatement对所有客户端连接都是静态的,当我创建它时,我调用statement.setPoolable(true),据我所知,这是多余的(PreparedStatement已经可用)。我希望通过这种方式,PreparedStatement不会绑定到单个连接上。仍然出现错误:
java.sql.SQLException:org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement with address * is closed。
奇怪的是,如果我在做任何设置之前调用statement.isClosed(),它将返回false。然后,我设置了一些东西,并抛出异常。
的代码是:
try {
Connection conn;
Context envCtx = (Context) new InitialContext().lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
conn = ds.getConnection();
if(statement == null){
//statement is static, so it won't be null at the second call
statement = conn.prepareStatement(query);
statement.setPoolable(true);
}
if(statement.isClosed()){
statement = conn.prepareStatement(query);
//it never gets here
}
else{
Logger.getLogger(HelloAxisWorld.class.getName()).log(Level.INFO, "STATEMENT IS NOT CLOSED", new Object());
//it always gets here
}
statement.setString(1, par1); //here, the second call throws an exception
ResultSet rs = statement.executeQuery();
while (rs.next()) {
cur_value = rs.getInt("cur_value");
}
rs.close();
conn.close();
}catch (Exception ex) {
Logger.getLogger(HelloAxisWorld.class.getName()).log(Level.SEVERE, null, ex);
}
我不明白为什么statement.isClosed返回false,但随后的异常说,它是封闭的。也许这不是重用预处理语句的方式,但那我该怎么做呢?我读过,如果我在同一个查询中调用conn.prepareStatement,jdbc将从缓存中返回PreparedStatement(它不会再被解析),但我不确定它是否属实。