spring批处理mysql语句_Spring框架——批处理(batch)和事务(Transaction)
批處理(batch)
批處理(batch)------------>好比快遞員【不能一件一件的送快遞】
- 批處理指的是一次操作中執(zhí)行多條SQL語(yǔ)句
- 批處理相比于一次一次執(zhí)行效率會(huì)提高很多
- 批處理主要是分兩步:
1.將要執(zhí)行的SQL語(yǔ)句保存
2.執(zhí)行SQL語(yǔ)句
- Statement和PreparedStatement都支持批處理操作,這里我們只需要掌握PreparedStatement的批處理方式:
- 方法:
void addBatch()
- 將要執(zhí)行的SQL先保存起來(lái),先不執(zhí)行
- 這個(gè)方法在設(shè)置完所有的占位符之后調(diào)用
int[] executeBatch()
- 這個(gè)方法用來(lái)執(zhí)行SQL語(yǔ)句,這個(gè)方法會(huì)將批處理中所有SQL語(yǔ)句執(zhí)行
- mysql默認(rèn)批處理是關(guān)閉的,所以我們還需要去打開(kāi)mysql的批處理:
rewriteBatchedStatements=true
我們需要將以上的參數(shù)添加到mysql的url地址中
- 注意:低版本的mysql-jdbc驅(qū)動(dòng)也不支持批處理,一般都是在修改的時(shí)候使用批處理,查詢(xún)的時(shí)候不使用!
案例演示:
1.創(chuàng)建一張新的數(shù)據(jù)表
CREATE TABLE t_emp(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50)
)
2.反復(fù)打開(kāi)數(shù)據(jù)庫(kù)客戶(hù)端,插入語(yǔ)句【相當(dāng)于每次獲取一個(gè)connection連接,執(zhí)行executeUpdate語(yǔ)句】
INSERT INTO t_emp(NAME) VALUES('張三');
SELECT * FROM t_emp;
3.引出批處理--->執(zhí)行效率高,資源利用率好!
@Test//測(cè)試批處理
public void testBatch(){
//向t_emp表中插入10000條數(shù)據(jù)
//準(zhǔn)備兩個(gè)變量
Connection connection = null;
PreparedStatement ps = null;
try {
//獲取數(shù)據(jù)庫(kù)連接
connection=JDBCUtil.getConnection();
//準(zhǔn)備SQL模板
String sql = "INSERT INTO t_emp(NAME) VALUES(?)";
//獲取PrepareStatement
ps = connection.prepareStatement(sql);
//創(chuàng)建一個(gè)for循環(huán),來(lái)設(shè)置占位符
for(int i = 0; i < 10000 ;i++){
//填充占位符
ps.setString(1,"emp"+i);
//添加到批處理方法中,調(diào)用無(wú)參的,有參的是Statement來(lái)調(diào)用的!
ps.addBatch();
}
//獲取一個(gè)時(shí)間戳
long start = System.currentTimeMillis();
//執(zhí)行批處理
ps.executeBatch();
//獲取一個(gè)時(shí)間戳
long end = System.currentTimeMillis();
System.out.println("共花費(fèi)了:"+(end-start));
} catch (SQLException e) {
e.printStackTrace();
}
}
事務(wù)(Transaction)
演示銀行轉(zhuǎn)賬的功能:
1.創(chuàng)建一張表示賬號(hào)的表
CREATE TABLE t_account(
id INT PRIMARY KEY AUTO_INCREMENT,
a_name VARCHAR(50),
balance DECIMAL(11,2)
)
2.向表中插入幾個(gè)用戶(hù)
INSERT INTO t_account(id,a_name,balance) VALUES(NULL,'sunwukong',1000);
INSERT INTO t_account(id,a_name,balance) VALUES(NULL,'zhubajie',1000);
INSERT INTO t_account(id,a_name,balance) VALUES(NULL,'shaheshang',1000);
SELECT * FROM t_account;
3.sunwukong向shaheshang轉(zhuǎn)賬100元
從sunwukong的賬號(hào)減去100元
UPDATE t_account SET balance = balance - 100 WHERE a_name='sunwukong';
給shaheshang的賬號(hào)加上100元
UPDATE t_account SET balance = balance +100 WHERE a_name = 'shaheshang';
重新設(shè)置為1000元:
UPDATE t_account SET balance =1000;
4.從java代碼中演示上面的案例:
1.創(chuàng)建Dao類(lèi)
public class AcountDao {
public void update(String name,double money){
//準(zhǔn)備兩個(gè)變量
Connection conn = null;
PreparedStatement ps = null;
//準(zhǔn)備SQL模板
String sql = "UPDATE t_account SET balance = balance + ? WHERE a_name = ?";
try {
conn = JDBCUtil.getConnection();
//獲取PreparedStatement
ps = conn.prepareStatement(sql);
//填充占位符
ps.setDouble(1, money);
ps.setString(2, name);
//執(zhí)行SQL語(yǔ)句
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(conn, ps, null);
}
}
}
2.測(cè)試該DAO
public class TestTransaction {
private AcountDao accountDao = new AcountDao();
@Test
public void test() {
//從sunwukong賬戶(hù)向shaheshang賬戶(hù)轉(zhuǎn)賬100元!
//1.從sunwukong賬戶(hù)扣除100元
accountDao.update("sunwukong", -100);
//2.向shaheshang賬戶(hù)添加100元
accountDao.update("shaheshang", 100);
}
}
顯然上面是可以正常執(zhí)行的!
但是如果上面的程序在suwukong減去100元之后,shaheshang加錢(qián)之前,出現(xiàn)了異常,如下所示:
//從sunwukong賬戶(hù)向shaheshang賬戶(hù)轉(zhuǎn)賬100元!
//1.從sunwukong賬戶(hù)扣除100元
accountDao.update("sunwukong", -100);
int i =10/0;//添加一個(gè)異常
//2.向shaheshang賬戶(hù)添加100元
accountDao.update("shaheshang", 100);
- 在開(kāi)發(fā)中我們的一個(gè)業(yè)務(wù)往往需要同時(shí)操作多個(gè)表,這些操作往往是不可分割,業(yè)務(wù)中的對(duì)數(shù)據(jù)庫(kù)的多次操作,
要么同時(shí)成功,要么全都失敗。
- 事務(wù)的特性(ACID):
原子性(atomicity)
一個(gè)事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中包括的諸操作要么都做,要么都不做。
一致性(consistency)
事務(wù)必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。一致性與原子性是密切相關(guān)的。
隔離性(isolation)
一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。
即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。
持久性(durability)
持久性也稱(chēng)永久性(permanence),指一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就應(yīng)該是永久性的。
接下來(lái)的其他操作或故障不應(yīng)該對(duì)其有任何影響。
- 操作事務(wù)的基本步驟:
1.開(kāi)啟事務(wù)
- 開(kāi)啟事務(wù)以后,我們只后的所有操作將都會(huì)在同一個(gè)事務(wù)當(dāng)中
2.操作數(shù)據(jù)庫(kù)
- 開(kāi)啟事務(wù)以后再去操作數(shù)據(jù)庫(kù),所有操作將不會(huì)直接提交到數(shù)據(jù)庫(kù)中
3.提交事務(wù)
- 將修改應(yīng)用到數(shù)據(jù)庫(kù)
4.回滾事務(wù)
- 數(shù)據(jù)庫(kù)操作過(guò)程中出現(xiàn)異常了,回滾事務(wù),回滾事務(wù)以后,數(shù)據(jù)庫(kù)變成開(kāi)啟事務(wù)之前的狀態(tài)
- mysql中的事務(wù)控制
#開(kāi)啟事務(wù)
START TRANSACTION
#回滾事務(wù)
ROLLBACK
#提交事務(wù)
COMMIT
- JDBC中的事務(wù)主要通過(guò)Connection對(duì)象來(lái)控制的
1.開(kāi)啟事務(wù)
void setAutoCommit(boolean autoCommit) throws SQLException;
- 設(shè)置事務(wù)是否自動(dòng)提交,默認(rèn)是自動(dòng)提交
- 設(shè)置事務(wù)手動(dòng)提交
conn.setAutoCommit(false);
2.提交事務(wù)
void commit() throws SQLException;
- 提交事務(wù)
conn.commit()
3.回滾事務(wù)
void rollback() throws SQLException;
- 回滾事務(wù)
conn.rollback()
- 事務(wù)控制的格式:
//創(chuàng)建一個(gè)Connection
Connection conn = null;
try{
//獲取Connection
conn = JDBCUtils.getConnection();
//開(kāi)啟事務(wù)
conn.setAutoCommit(false);
//對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作
//操作成功,提交事務(wù)
conn.commit();
}catch(Exception e){
e.printStackTrace();
//回滾事務(wù)
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
JDBCUtils.close(conn, null, null);
}
- 注意:我們?cè)谕粋€(gè)事務(wù)中使用的數(shù)據(jù)庫(kù)連接(Connection)必須是同一個(gè),否則事務(wù)還是不作用!
所以此時(shí)原來(lái)的AcountDAO中的update方法要改為如下所示:
public class AcountDao {
public void update(Connection conn,String name,double money){
//準(zhǔn)備兩個(gè)變量
PreparedStatement ps = null;
//準(zhǔn)備SQL模板
String sql = "UPDATE t_account SET balance = balance + ? WHERE a_name = ?";
try {
//獲取PreparedStatement
ps = conn.prepareStatement(sql);
//填充占位符
ps.setDouble(1, money);
ps.setString(2, name);
//執(zhí)行SQL語(yǔ)句
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//此時(shí)也不能在這里關(guān)閉數(shù)據(jù)庫(kù)連接了,而是在外邊統(tǒng)一關(guān)閉
JDBCUtil.close(null, ps, null);
}
}
}
總結(jié)
以上是生活随笔為你收集整理的spring批处理mysql语句_Spring框架——批处理(batch)和事务(Transaction)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pdb连接数_Oracle 19c 之多
- 下一篇: mysql 散列存储_什么是数据库散列存