最近在重温java知识,了解了这方面的知识
网上收集的一些介绍
1. Statement用于处理静态 SQL 语句, PreparedStatement用于处理动态SQL语句,在执行前会有一个预编译的过程,它是有时间开销的,虽然相对于数据库的操作该时间开销可以忽略不计。但是后者的预编译结果会被缓存,而不论动态值发生什么样的变化。 2. PreparedStatement继承于Statement,通常的JDBC实现中PreparedStatement最终还是通过Statement的相关方法来执行SQL的(可以做少量优化),其最主要的优势在于,可以减少SQL的编译错误(在JDBC中就可以捕获部分异常而不是由数据库服务器执行时返回错误代码)、增加SQL安全性(减少SQL注入的机会)。 3. 两者的性能表现与JDBC的实现有很大关系,个人对于Oracle的ojdbc性能也颇有异议。 以Oracle为例吧 Statement为一条Sql语句生成执行计划, 如果要执行两条sql语句 select colume from table where colume=1; select colume from table where colume=2; 会生成两个执行计划 一千个查询就生成一千个执行计划! PreparedStatement用于使用绑定变量重用执行计划 select colume from table where colume=:x; 通过set不同数据只需要生成一次执行计划,可以重用 是否使用绑定变量对系统影响非常大,生成执行计划极为消耗资源 两种实现 速度差距可能成百上千倍
Oracle 官网对于PreparedStatement 和Statement的解释用例:http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html
JDK文档解释:http://download.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html
public void updateCoffeeSales(HashMap<String, Integer> salesForWeek) throws SQLException { PreparedStatement updateSales = null; PreparedStatement updateTotal = null; String updateString = "update " + dbName + ".COFFEES " + "set SALES = ? where COF_NAME = ?"; String updateStatement = "update " + dbName + ".COFFEES " + "set TOTAL = TOTAL + ? where COF_NAME = ?"; try { con.setAutoCommit(false); updateSales = con.prepareStatement(updateString); updateTotal = con.prepareStatement(updateStatement); for (Map.Entry<String, Integer> e : salesForWeek.entrySet()) { updateSales.setInt(1, e.getValue().intValue()); updateSales.setString(2, e.getKey()); updateSales.executeUpdate(); updateTotal.setInt(1, e.getValue().intValue()); updateTotal.setString(2, e.getKey()); updateTotal.executeUpdate(); con.commit(); } } catch (SQLException e ) { JDBCTutorialUtilities.printSQLException(e); if (con != null) { try { System.err.print("Transaction is being rolled back"); con.rollback(); } catch(SQLException excep) { JDBCTutorialUtilities.printSQLException(excep); } } } finally { if (updateSales != null) { updateSales.close(); } if (updateTotal != null) { updateTotal.close(); } con.setAutoCommit(true); } }
这段代码写的还是比较严谨的,对于我这样的菜鸟来说,要学的很多:
1.事务回滚操作
2.数据库连接资源及时释放