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 ( ) ;
}
}
}
}
}
感谢您的观看