Java JDBC批量執(zhí)行executeBatch方法詳解
JDBC事務(wù)
在數(shù)據(jù)庫中,所謂事務(wù)是指一組邏輯操作單元,使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)。為確保數(shù)據(jù)庫中數(shù)據(jù)的一致性,數(shù)據(jù)的操縱應(yīng)當(dāng)是離散的成組的邏輯單元:當(dāng)它全部完成時(shí),數(shù)據(jù)的一致性可以保持,而當(dāng)這個(gè)單元中的一部分操作失敗,整個(gè)事務(wù)應(yīng)全部視為錯(cuò)誤,所有從起始點(diǎn)以后的操作應(yīng)全部回退到開始狀態(tài)。
事務(wù)的操作:先定義開始一個(gè)事務(wù),然后對(duì)數(shù)據(jù)作修改操作,這時(shí)如果提交(COMMIT),這些修改就永久地保存下來,如果回退(ROLLBACK),數(shù)據(jù)庫管理系統(tǒng)將放棄您所作的所有修改而回到開始事務(wù)時(shí)的狀態(tài)。
事務(wù)的ACID屬性
1. 原子性(Atomicity)
原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
2. 一致性(Consistency)
事務(wù)必須使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)。(數(shù)據(jù)不被破壞)
3. 隔離性(Isolation)
事務(wù)的隔離性是指一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。
4. 持久性(Durability)
持久性是指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來的其他操作和數(shù)據(jù)庫故障不應(yīng)該對(duì)其有任何影響。
在JDBC中,事務(wù)默認(rèn)是自動(dòng)提交的,每次執(zhí)行一個(gè) SQL 語句時(shí),如果執(zhí)行成功,就會(huì)向數(shù)據(jù)庫自動(dòng)提交,而不能回滾
為了讓多個(gè) SQL 語句作為一個(gè)事務(wù)執(zhí)行:
- 執(zhí)行語句前調(diào)用 Connection 對(duì)象的 setAutoCommit(false); 以取消自動(dòng)提交事務(wù)
- 在所有的 SQL 語句都成功執(zhí)行后,調(diào)用 commit(); 方法提交事務(wù)
- 在出現(xiàn)異常時(shí),調(diào)用 rollback(); 方法回滾事務(wù)。
JDBC批量執(zhí)行
當(dāng)需要成批插入或者更新記錄時(shí)??梢圆捎肑ava的批量更新機(jī)制,這一機(jī)制允許多條語句一次性提交給數(shù)據(jù)庫批量處理。通常情況下比單獨(dú)提交處理更有效率
JDBC的批量處理語句包括下面兩個(gè)方法:
addBatch(String):添加需要批量處理的SQL語句或是參數(shù);
executeBatch();執(zhí)行批量處理語句;
clearBatch();清除批量打包
通常我們會(huì)遇到兩種批量執(zhí)行SQL語句的情況:
多條SQL語句的批量處理;
for (int i = 1; i < 5000; i++) {
sql = "insert into person(id,name,email) values(" + i",'name" + i + "','email" + i + "')";
stmt.addBatch(sql);
if((i+1)%1000==0){
//批量處理
stmt.executeBatch();
//清除stmt中積攢的參數(shù)列表
stmt.clearBatch();
}
}
一個(gè)SQL語句的批量傳參;
for(int i=1;i<100000;i++){
pstmt.setInt(1, i);
pstmt.setString(2, "name"+i);
pstmt.setString(3, "email"+i);
pstmt.addBatch();
if((i+1)%1000==0){
//批量處理
pstmt.executeBatch();
//清空pstmt中積攢的sql
pstmt.clearBatch();
}
}
JDBC執(zhí)行SQL語句,有兩個(gè)處理的接口,一個(gè)PreparedStatement,Statement,一般操作JDBC比較用得多的還是PreparedStatement
不過在執(zhí)行批量,PreparedStatement有點(diǎn)不夠Statement
ps = conn.prepareStatement(sql);
for(int i = 0;i<10;i++){
ps.setString(1,"1");
//PreparedStatement批處理方式一
ps.addBatch();
}
//PreparedStatement批處理方式二
ps.addBatch("靜態(tài)SQL");
ps.executeBatch();
這個(gè)是正常執(zhí)行的
可是把PreparedStatement放到里面就沒效了,以下:
for(int i = 0;i<10;i++){
ps = conn.prepareStatement(sql);
ps.setString(1,"1");
ps.addBatch();
}
ps.executeBatch();
Statement適合循環(huán)賦值到sql,代碼以下:
Statement st = conn.createStatement();
for(int i = 0;i<10;i++){
st.addBatch("靜態(tài)sql..........");
}
st.executeBatch();
這個(gè)是正常執(zhí)行所有的語句
總結(jié):造成這樣的原因是
Statement st = conn.createStatement();這里可以不放SQL語句
ps = conn.prepareStatement(sql);這個(gè)一定要放初始SQL語句
JDBC的批處理不能加入select語句,否則會(huì)拋異常:
java.sql.BatchUpdateException: Can not issue SELECT via executeUpdate().
at com.MySQL.jdbc.StatementImpl.executeBatch(StatementImpl.java:1007)
到此這篇關(guān)于Java JDBC批量執(zhí)行executeBatch方法詳解的文章就介紹到這了,更多相關(guān)Java JDBC批量執(zhí)行executeBatch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Java如何在并發(fā)環(huán)境下生成一個(gè)只讀的map
這篇文章主要為大家詳細(xì)介紹了Java如何在并發(fā)環(huán)境下生成一個(gè)只讀的map,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
SpringBoot?全局線程池配置及應(yīng)用小結(jié)
為了提高應(yīng)用程序的性能和響應(yīng)速度,線程池是一個(gè)非常重要的工具,本文主要介紹了Spring?Boot?全局線程池配置及應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05
spring boot 自定義starter的實(shí)現(xiàn)教程
下面小編就為大家分享一篇spring boot 自定義starter的實(shí)現(xiàn)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12

