JDBC批處理
piliang處理允許將相關的SQL語句分組到批處理中,並通過對數據庫的一次調用提交它們
當需要一次向數據庫發送多個SQL語句時,可以減少連接數據庫的開銷,從而提高性能
在jdbc的URL中添加rewriteBatchedStatements=true參數,可以提高批處理執行效率
Statement批處理
註冊驅動獲取連接
使用createStatement()方法創建Statements對象
使用setAutoCommit()將auto_commit設置爲false
使用使用addBatch()方法在創建的語句對象上添加您喜歡的SQL語句到批處理中
在創建的語句對象上使用executeBatch()方法執行所有SQL語句
使用commit()方法提交所有更改
釋放資源
package waking. test. jdbc;
import java. sql. Connection;
import java. sql. DriverManager;
import java. sql. SQLException;
import java. sql. Statement;
public class Demo10 {
public static void main ( String[ ] args) {
String dirver = "com.mysql.jdbc.Driver" ;
String url = "jdbc:mysql://localhost:3306/csdn" ;
String user = "root" ;
String password = "123456" ;
Connection conn = null;
Statement stmt = null;
try {
Class. forName ( dirver) ;
conn = DriverManager. getConnection ( url, user, password) ;
stmt = conn. createStatement ( ) ;
conn. setAutoCommit ( false ) ;
String sql1 = "insert into user values(8,'waki','wakig','xixix','17273934784')" ;
stmt. addBatch ( sql1) ;
String sql2 = "insert into user values(9,'wa','wak','hee','17273934784')" ;
stmt. addBatch ( sql2) ;
int [ ] executeBatch = stmt. executeBatch ( ) ;
conn. commit ( ) ;
System. out. println ( "影響" + executeBatch. length+ "行" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
if ( stmt!= null) {
try {
stmt. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( conn!= null) {
try {
conn. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
String sql1 = "insert into user values(8,'waki','wakig','xixix','17273934784')" ;
stmt. addBatch ( sql1) ;
String sql2 = "insert into user values(9,'wa','wak','hee','17273934784')" ;
stmt. addBatch ( sql2) ;
int [ ] executeBatch = stmt. executeBatch ( ) ;
PrepareStatement批處理
使用佔位符創建SQL語句
使用PrepareStatement()方法創建PrepareStatement對象
使用setAutoCommit()將auto_commit設置爲false
使用addBatch()方法在創建的語句對象上添加您喜歡的SQL語句到批處理
在創建的語句對象上使用executeBatch()方法執行所有SQL語句
最後,使用commit()方法提交所有更改
package waking. test. jdbc;
import java. sql. Connection;
import java. sql. DriverManager;
import java. sql. PreparedStatement;
import java. sql. SQLException;
import java. sql. Statement;
public class Demo11 {
public static void main ( String[ ] args) {
String dirver = "com.mysql.jdbc.Driver" ;
String url = "jdbc:mysql://localhost:3306/csdn" ;
String user = "root" ;
String password = "123456" ;
Connection conn = null;
PreparedStatement pstmt = null;
try {
Class. forName ( dirver) ;
conn = DriverManager. getConnection ( url, user, password) ;
String sql1 = "insert into user values(?,?,?,?,?)" ;
pstmt = conn. prepareStatement ( sql1) ;
conn. setAutoCommit ( false ) ;
pstmt. setInt ( 1 , 10 ) ;
pstmt. setString ( 2 , "wakk" ) ;
pstmt. setString ( 3 , "fdas" ) ;
pstmt. setString ( 4 , "asa" ) ;
pstmt. setString ( 5 , "17273934784" ) ;
pstmt. addBatch ( ) ;
pstmt. setInt ( 1 , 11 ) ;
pstmt. setString ( 2 , "akk" ) ;
pstmt. setString ( 3 , "fs" ) ;
pstmt. setString ( 4 , "aa" ) ;
pstmt. setString ( 5 , "17273934784" ) ;
pstmt. addBatch ( ) ;
int [ ] executeBatch = pstmt. executeBatch ( ) ;
conn. commit ( ) ;
System. out. println ( "影響" + executeBatch. length+ "行" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
if ( pstmt!= null) {
try {
pstmt. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( conn!= null) {
try {
conn. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
Statment批處理和PrepareStatement批處理區別
Statement批處理可以添加不同SQL語句,而PrepareStatement只能添加一種SQL語句
PrepareStatement效率比Statement高,而且更安全
數據庫事務
事務概述
一組要麼同時執行成功,要麼同時失敗的SQL語句。是數據庫操作的一個不能分割執行單元
數據庫事務(Database Transaction),是指作爲單個邏輯單元執行的一系列操作,要麼完全的執行,要麼完全的不執行。
事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。
通過將一組相關操作組合爲一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢復並使應用程序更可靠。
一個邏輯工作單元要成爲事務,必須滿足所謂的ACID(原子性,一致性,隔離性,持久性)屬性。
事務是數據庫運行中的邏輯工作單位,有DBMS中的事務管理子系統負責事務的處理。
通常事務開始於
連接到數據庫上,並執行一條DML語句insert,update或delete
前一個事務結束後,又輸入了另一條DML語句
通常事務結束於
執行commit後rollback語句
執行一條DDL語句,列如create table語句,在這種情況下,會自動執行commit語句
斷開與數據庫的連接
執行了一條DML語句,該語句卻失敗了,在這種情況中,會爲這個無效的DML語句執行rollback語句
事務特性(ACID)
Atomicity(原子性)
表示一個事務內的所有操作是一個整體,要麼全部成功,要麼全部失敗
Consistency(一致性)
表示一個事務內有一個操作失敗時,所有的更改過的數據都必須回滾到修改前狀態
Isolation(隔離性)
事務查看數據時數據所處的狀態,要麼是另一併發事務修改它之前的狀態,要麼是另一事務修改它之後的狀態,事務不會查看中間狀態的數據
Durability(持久性)
數據庫操作
CREATE TABLE account(
id INT PRIMARY KEY,
NAME VARCHAR(20)NOT NULL,
money DOUBLE(10,2)
);
INSERT INTO account(id,NAME,money) VALUES(1,'wkaing',100),(2,'lily',100);
package waking. test. jdbc;
import java. sql. Connection;
import java. sql. DriverManager;
import java. sql. PreparedStatement;
import java. sql. SQLException;
import java. sql. Statement;
public class Demo12 {
public static void main ( String[ ] args) {
String dirver = "com.mysql.jdbc.Driver" ;
String url = "jdbc:mysql://localhost:3306/csdn" ;
String user = "root" ;
String password = "123456" ;
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
Class. forName ( dirver) ;
conn = DriverManager. getConnection ( url, user, password) ;
conn. setAutoCommit ( false ) ;
String sql1 = "update account set money = money - 100 where id = ?" ;
String sql2 = "update account set money = money + 100 where id = ?" ;
pstmt1 = conn. prepareStatement ( sql1) ;
pstmt1. setInt ( 1 , 1 ) ;
pstmt1. executeUpdate ( ) ;
pstmt2 = conn. prepareStatement ( sql2) ;
pstmt2. setInt ( 1 , 2 ) ;
pstmt2. executeUpdate ( ) ;
System. out. println ( "轉賬成功、、" ) ;
conn. commit ( ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
System. out. println ( "轉賬失敗、、、" ) ;
try {
conn. rollback ( ) ;
} catch ( SQLException e1) {
e1. printStackTrace ( ) ;
}
} finally {
if ( pstmt1!= null) {
try {
pstmt1. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( pstmt2!= null) {
try {
pstmt2. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( conn!= null) {
try {
conn. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
Mysql事務語句
#開啓事務
START TRANSACTION;
UPDATE account SET money = money-100 WHERE id =1;
UPDATE account SET money = money+100 WHERE id =2;
#提交事務
COMMIT;
#回滾事務
ROLLBACK;
事務的隔離級別
一個事務,在併發訪問的情況下,不同隔離級別會出現不同效果
併發:在同一時刻,有多個客戶在操作同一張表
1.read uncommitted
一個事務中讀到了另一個事務並未提交的結果。
這種隔離級別就會導致:髒讀、不可重複讀、幻讀
2.read committed (oracle的默認隔離級別)
一個事務中能讀到另一個事務已經提交的結果,但是不能讀到另一個事務沒有提交的結果
這種隔離級別解決了髒讀問題。但出現了不可從重複讀和幻讀的問題
注:
所謂的不可重複讀,就是不能重複讀,一重複讀數據就不一樣
所謂的幻讀,在一個事務中,兩次讀到的數據的條數不相同
3.repeatable read(mysql的默認級別)
一個事務中可以重複讀,每次讀到的數據都是一樣的
無論其他事務對數據進行怎樣的操作(添加數據、修改數據、提交事務)。當前事務每次讀到的數據內容都不會有變化
這種隔離級別解決了:髒讀、不可重複讀,幻讀
4.serializable串行化
最嚴苛的隔離級別。將並行變成串行。效率非常低。
set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;
Savepoint
Connection對象有兩種新的方法來幫助您管理保存點 -
setSavepoint(String savepointName):定義新的保存點。它還返回一個Savepoint對象。
releaseSavepoint(Savepoint savepointName):刪除保存點。請注意,它需要一個Savepoint對象作爲參數。此對象通常是由setSavepoint()方法生成的保存點。
package waking. test. jdbc;
import java. sql. Connection;
import java. sql. DriverManager;
import java. sql. PreparedStatement;
import java. sql. SQLException;
import java. sql. Savepoint;
import java. sql. Statement;
public class Demo13 {
public static void main ( String[ ] args) {
String dirver = "com.mysql.jdbc.Driver" ;
String url = "jdbc:mysql://localhost:3306/csdn" ;
String user = "root" ;
String password = "123456" ;
Connection conn = null;
Statement stmt = null;
Savepoint savepoint= null;
try {
Class. forName ( dirver) ;
conn = DriverManager. getConnection ( url, user, password) ;
conn. setAutoCommit ( false ) ;
String sql = "update account set money = money - 100 where id = 1" ;
stmt = conn. createStatement ( ) ;
stmt. executeUpdate ( sql) ;
savepoint= conn. setSavepoint ( "save" ) ;
String sql1 = "update account set money = money + 100 where id = 2" ;
stmt. executeUpdate ( sql1) ;
conn. commit ( ) ;
System. out. println ( "轉賬成功、、" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
System. out. println ( "轉賬失敗、、、" ) ;
try {
conn. rollback ( savepoint) ;
} catch ( SQLException e1) {
e1. printStackTrace ( ) ;
}
} finally {
if ( stmt!= null) {
try {
stmt. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( conn!= null) {
try {
conn. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
感謝您的觀看