首先關於Statement和PreparedStatement的基本概念我就不再敘述了,可以參考這篇文章,下面我們來看幾個測試例子吧。
測試場景
現在我們向數據庫中的一張表中插入100000(10萬)條數據,測試使用Statement和PreparedStatement及PreparedStatement的Batch方式所需要的時間。
Dao基類
/**
*
* Description: 數據庫操作基類
*
* @author: crane-yuan
* @date: 2016年9月27日 下午1:40:04
*/
public class BaseDao {
protected Connection connection; // 訪問數據庫的句柄
public void openConnection() throws Exception {
if (this.connection == null || this.connection.isClosed()) {
try {
DbInfo dbinfo = DbInfo.instance();
Class.forName(dbinfo.getDbdriver()); // 加載oracle的驅動
connection = DriverManager.getConnection(dbinfo.getUrl(),
dbinfo.getUser(), dbinfo.getPassword());
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("請檢查驅動包是否正確");
throw e;
} catch (SQLException e) {
e.printStackTrace();
System.out.println("請檢查數據庫的配置項是否正確");
throw e;
}
}
}
public void closeConnection() throws Exception {
if (this.connection != null) {
this.connection.close();
}
}
}
Statement方式
/**
*
* Description: 測試Statement
*
* @throws Exception void
*/
public void testStatement() throws Exception {
System.out.println("--------------Statement no batch----------------");
String sql = "";
this.openConnection();
// 手動提交
this.connection.setAutoCommit(false);
Statement statement = this.connection.createStatement();
Long beginTime = System.currentTimeMillis();
System.out.println(new Date(beginTime));
try {
for (int i = 100001; i < 200000; i++) {
sql = "insert into testStatement(code) values(" + i + ")";
statement.executeUpdate(sql);
}
} catch (SQLException exception) {
exception.printStackTrace();
}
this.connection.commit();
statement.close();
this.connection.close();
Long endTime = System.currentTimeMillis();
System.out.println(new Date(endTime));
System.out.println("Statement:" + (endTime - beginTime) / 1000 + "秒");
}
結果:
--------------Statement no batch----------------
Wed Oct 19 16:42:22 CST 2016
Wed Oct 19 16:46:32 CST 2016
Statement:249秒
PreparedStatement無Batch方式
/**
*
* Description: 測試PreparedStatement,不開啓Batch提交
*
* @throws Exception void
*/
public void testPreparedStatement() throws Exception {
System.out
.println("--------------PreparedStatement no batch----------------");
String sql = "insert into testStatement(code) values(?)";
this.openConnection();
// 手動提交
this.connection.setAutoCommit(false);
PreparedStatement ps = this.connection.prepareStatement(sql);
Long beginTime = System.currentTimeMillis();
System.out.println(new Date(beginTime));
try {
for (int i = 0; i < 100000; i++) {
String code = "" + i;
ps.setString(1, code);
ps.execute();
}
} catch (SQLException exception) {
exception.printStackTrace();
}
this.connection.commit();
ps.close();
this.connection.close();
Long endTime = System.currentTimeMillis();
System.out.println(new Date(endTime));
System.out.println("PreparedStatement:" + (endTime - beginTime) / 1000 + "秒");
}
結果
--------------PreparedStatement no batch----------------
Wed Oct 19 16:46:32 CST 2016
Wed Oct 19 16:48:37 CST 2016
PreparedStatement:125秒
PreparedStatement有Batch方式
/**
*
* Description: 測試使用PreparedStatement,並且開啓Batch提交.
*
* @throws Exception void
*/
public void testPreparedStatementBatch() throws Exception {
System.out
.println("--------------PreparedStatement with batch----------------");
String sql = "insert into testStatement(code) values(?)";
this.openConnection();
// 手動提交
this.connection.setAutoCommit(false);
PreparedStatement ps = this.connection.prepareStatement(sql);
Long beginTime = System.currentTimeMillis();
System.out.println(new Date(beginTime));
int count = 0;
try {
for (int i = 200001; i < 300000; i++) {
String code = "" + i;
ps.setString(1, code);
ps.addBatch();
count++;
if (count == 500) {
count = 0;
ps.executeBatch();
this.connection.commit();
ps.clearBatch();
}
}
} catch (SQLException exception) {
exception.printStackTrace();
}
ps.close();
this.connection.close();
Long endTime = System.currentTimeMillis();
System.out.println(new Date(endTime));
System.out.println("PreparedStatement+batch:" + (endTime - beginTime) / 1000 + "秒");
}
結果
--------------PreparedStatement with batch----------------
Wed Oct 19 16:48:37 CST 2016
Wed Oct 19 16:48:38 CST 2016
PreparedStatement+batch:1秒
總結
一般來說,PreparedStatement的Batch方式執行效率比PreparedStatement和Statement的都高,PreparedStatement無Batch方式比Statement方式也要高。
在實際開發中一般推薦使用PreparedStatement,不過PreparedStatement也有一些缺點,在這篇文章中暫時不在敘述了,這方面的對比將在下篇文章中詳細講解。