java多次_JAVA如何做到一次解析多次执行

如果是循环处理某种数据,这个比较容易实现。其实对于不是这种情况,Oracle也提供了很好的方式来实现这一点。下面是一个例子(例子代码文件为TestStmtCache.java)。import java.sql.*;

import oracle.jdbc.driver.OracleConnection;

public class TestStmtCache {

public static Connection getConnection() throws Exception {

String driver = "oracle.jdbc.driver.OracleDriver";

String url = "jdbc:oracle:thin:@localhost:1521:xj11g";

Class.forName(driver);

return DriverManager.getConnection(url, "test", "test");

}

public static void main(String args[]) {

Connection conn = null;

try {

conn = getConnection();

conn.setAutoCommit(false);

((OracleConnection)conn).setStatementCacheSize(0);

for (int i=0; i <200; i++) {

testNoCache(conn);

}

((OracleConnection)conn).setStatementCacheSize(20);

((OracleConnection)conn).setImplicitCachingEnabled(true);

for (int i=0; i <200; i++) {

testCache(conn);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

public static void testCache(Connection conn) {

PreparedStatement pstmt = null;

try {

pstmt = conn.prepareStatement("select /*cache_test1 */ * from t1 where rownum<=1");

pstmt.execute();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

pstmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

public static void testNoCache(Connection conn) {

PreparedStatement pstmt = null;

try {

pstmt = conn.prepareStatement("select /*nocache_test1 */ * from t1 where rownum<=1");

pstmt.execute();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

pstmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

编译上述代码文件TestStmtCache.java,并运行:E:\JavaCode>set CLASSPATH=.;ojdbc14.jar

E:\JavaCode>d:\works\Java\jdk1.5.0_21\bin\javac TestStmtCache.java

E:\JavaCode>d:\works\Java\jdk1.5.0_21\jre\bin\java TestStmtCache

在数据库中进行查询:SYS@xj11g> select sql_id,parse_calls,executions,sql_text from v$sqlarea where sql_text like '%cache_test%' and sql_text not like '%v$%';

SQL_ID        PARSE_CALLS  EXECUTIONS SQL_TEXT

------------- ----------- ----------- ------------------------------------------------------------

3nbu9qp40ptjk         200         200 select /*nocache_test1 */ * from t1 where rownum

47hja0fwmmb6c           1         200 select /*cache_test1 */ * from t1 where rownum<=1

可以看到,这两条SQL语句,都执行了200次,但是标记为"nocache_test1"的SQL没有进行语句缓存,其parse calls为200次,即解析了200次,其中一次是硬解析。而标记为"cache_test1"的SQL语句,使用了语句缓存,但是parse calls只有1次,即只有一次硬解析,执行了200次。这里关键的代码在于:((OracleConnection)conn).setStatementCacheSize(20);

((OracleConnection)conn).setImplicitCachingEnabled(true);

上述第一行代码设置语句缓存大小,当然20比较偏小,对于比较大型的系统来说,设到200-300比较合适,不过这会耗用一定数量的JAVA内存。这个数值表示一个连接能够缓存多少语句。第二行代码是设置隐式打开语句缓存,也即自动会对PreparedStatement的SQL语句进行缓存。

那么,上述的方式无疑是比较简单的,但是这种方式有一个问题就是,缓存的利用效率可能不高,因为JAVA会将不常用的SQL语句也进行了缓存。Oracle的JDBC驱动也提供了一种手工控制的方式:

将测试代码中的第22行替换为:((OracleConnection)conn).setExplicitCachingEnabled(true);

第40行替换为:pstmt = ((OracleConnection)conn).getStatementWithKey ("cache_test1");

if (pstmt==null)

第46行替换为:((OraclePreparedStatement)pstmt).closeWithKey ("cache_test1");

这样通过手工编码的方式控制哪些语句需要缓存,哪些不需要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值