提纲:
1. JDBC使用快速回顾
2. 批处理
3. 事务
####复习
- 怎样注册驱动
Class.forName("com.sql.jdbc.Driver");
2.怎样获取连接对象
DriverManager.getConnection(url,name,password);
url作用:通过url可以知道具体加载哪一个驱动
mysql的url可以简写:jdbc:myql:///mydb
- 怎样获取可以操作sql语句的对象
Statement st=conn.createStatement();
st.executeQuery();
st.executeUpdate();
st.execute();
PreparedStatement pst=conn.prepareStatement(sql); //占位符是?
setXXX()
executeQuery();
pst.executeUpdate();
4.执行查询语句后,可以得到ResultSet
ResultSet rs=st.executeQuery(sql);
rs.next();
getObject()
getInt();
5.关闭资源
rs.close();
st.close();
conn.close();
##关于多数据处理.
###批处理
批处理应用:一次可以执行多条sql语句
批处理有两种方式
1.Statement
addBatch(String sql) //将多条sql语句回到批处理中
cleaarBatch(); //清空所有的sql
executetBatch(); //执行一批sql
2.PreparedStatement
addBatch(); //添加SQL语句回到批处理
executeBaatch(); //批量执行sql
####Statement与PreparedStatement区别
1.Statement适合执行不同的sql语句 PreparedStatement适合执行相同的sql语句
2.Statement在执行时比PreParedStatement的效率低1
####看两个demo吧
我先把jdbc封装到一个utils里面
package cn.lawfree.JDBC.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
public class JdbcUtil {
private static String DRIVER;
private static String URL;
private static String USERNAME;
private static String PASSWORD;
// private static final ThreadLocal<Connection> tl = new
// ThreadLocal<Connection>();
static {
// 获取连接数据
ResourceBundle bundle = ResourceBundle.getBundle("db");
DRIVER = bundle.getString("driver");
URL = bundle.getString("url");
USERNAME = bundle.getString("username");
PASSWORD = bundle.getString("pwd");
}
static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
throw new RuntimeException("加载驱动加载驱动");
}
}
// 创建一个可以去Connection对象的方法
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
// throw new RuntimeException("获取连接失败");
e.printStackTrace();
}
return conn;
}
// 关闭方法Connection方法
public static void closeConnection(Connection conn) throws SQLException {
if (conn != null) {
conn.close();
}
}
// 关闭Statement方法
public static void closeStatement(Statement st) throws SQLException {
if (st != null) {
st.close();
}
}
// 关闭ResultSet方法
public static void closeResultSet(ResultSet rs) throws SQLException {
if (rs != null) {
rs.close();
}
}
}
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import cn.lawfree.JDBC.util.JdbcUtil;
//statement的批处理
public class Demo1 {
public static void main(String[] args) throws SQLException {
String sql0 = "use t_testpatch";
String sql1 = "create table user(id int,name varchar(20),sex varchar(10),age int )";
String sql2 = "insert into user values(1,'tom','male','20')";
String sql3 = "insert into user values(2,'fox','male','30')";
String sql4 = "update user set age=40 where id=1";
// 1.获取Connection对象
Connection conn = JdbcUtil.getConnection();
// 2.获取Statement对象
Statement st = conn.createStatement();
// 3.将sql语句添加到st中
st.addBatch(sql0);
st.addBatch(sql1);
st.addBatch(sql2);
st.addBatch(sql3);
st.addBatch(sql4);
// 4.批处理
st.executeBatch();
// 5.关闭资源
st.close();
conn.close();
}
}
package cn.lawfree.JDBC.batch;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import cn.lawfree.JDBC.util.JdbcUtil;
//PreparedStatement执行批处理
public class demo2 {
public static void main(String[] args) throws SQLException {
Connection conn = JdbcUtil.getConnection();
String sql = "insert into user values(?,?,?,?)";
PreparedStatement pst = conn.prepareStatement(sql);
for (int i = 1; i < 10; i++) {
pst.setInt(1, i);
pst.setString(2, "name" + i);
pst.setString(3, "male");
pst.setInt(4, 20 + (int) (Math.random() * 10));
// 添加到批处理
pst.addBatch();
}
// 执行
pst.executeBatch();
pst.close();
conn.close();
conn.close();
}
}
##事务
通俗地讲:事务是指一组操作,组成这组操作的功能,要不全部成功,要不全部不成功
关于事务
1.数据库本意识提供事务.
2.jdbc提供对事务的处理.
###1.数据库中事务处理
mysql事务是自动提交的.------默认情况,事务自动提交,一条sql语句是一个单独事务
oracle事务是手动提交. commit
start transaction ------开启事务
rollback ------回滚
commit ------提交事务
mysql可以设置提交方式吗?
show variables like ‘%commit’; 查看提交方式
set autocomit=off/on; 关闭自动提交
演示 start transaction rollback commit使用
create table acount(
id int,
name varchar(10),
money int
)
insert into account values(1,'aaa',1000);
insert into account values(2,'bbb',1000);
insert into account values(3,'ccc',1000);
aaa--汇款给-->bbb 500元
update acount set money=money-500 where name='aaa'; 从aaa前去500.
update acount set money=money+500 where name='bbb'; 给bbb加上500.
事务处理操作
1.start transcation.
2.
update acount set money=money-500 where name='aaa'; 从aaa前去500.
update acount set money=money+500 where name='bbbb'; 给bbb加上500.
3.发现数据有问题–>rollback;
4. commit
###2.jdbc事务处理
在Connection中提供
setAutoCommit(boolean f); //-----设置事务的提交方式
rollback(); //-----事务回滚
commit(); //-----事务提交
这三个方法是jdbc中事务的三个方法
Savepoint 回滚点
con.setSavepoint(); 获取(设置回滚点)
rollback(Savepoint) ;//这样使用
还是来看一个demo
package cn.lawfree.JDBC.transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//这是转账操作的底层实现
//包含两个方法,存钱和取钱方法
public class AccountDao {
// 存储
public void save(double money, String name, Connection conn)
throws SQLException {
String sql = "update account set money=money+? where name=? ";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setDouble(1, money);
pst.setString(2, name);
int row = pst.executeUpdate();
if (row == 0) {
throw new RuntimeException("存款失败");
}
pst.close();
}
// 取钱
public void get(double money, String name, Connection conn)
throws SQLException {
String sql = "update account set money=money-? where name=?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setDouble(1, money);
pst.setString(2, name);
int row = pst.executeUpdate();
if (row == 0) {
throw new RuntimeException("存款失败");
}
pst.close();
}
}
package cn.lawfree.JDBC.transaction;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
import cn.itcast.lawfree.util.JdbcUtil;
//这是转账支付的service操作,主要用于实现事务逻辑
//我们给它添加一个回滚的逻辑
public class AccountService {
public void hk() {
AccountDao dao = new AccountDao();
Connection conn = JdbcUtil.getConnection();
// 开启事务 ------setAutoCommit(false);
Savepoint point = null;
try {
conn.setAutoCommit(false);
// 1.从a账户取钱500
dao.get(500, "aaa", conn);
// 设置一个回滚点
point = conn.setSavepoint();
// 2.向账户存500;
dao.save(500, "bbb", conn);
} catch (SQLException e) {
// 回滚
// rollback
try {
conn.rollback(point);
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
// commit
conn.commit();
// 关闭conn
JdbcUtil.closeConnection(conn);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
###事务的特性(ACID)
1.原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
2.一致性(Consistency)
事务前后数据的完整性必须一致
3.隔离性(Isolation)
事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间的数据要相互隔离
4.持久性(Durability)
持久性是指一个事务一旦被提交.它对数据库中数据的改变是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
重点介绍事务的隔离性
如果不考虑事务的隔离性会引发的问题
-
脏读 一个事务读取到另一个事务的未提交数据
A 转账给B 100,未提交 B 查询账户多了100 A 回滚 B 查询账户那100不见了
2.不可重复读 两次读取的数据不一致(强调的是update操作,数据的总条数不变
将隔离级别设置成 Read committed.查看是否可以解决脏读问题
演示不可重复读:
A 转账 给B 100,未提交
B 查询 金额没变(级别是: Read committed 避免了脏读)
A 查询,发现金额多了100
两次读取到的数据不一致,出现了不可重复读.
- 虚读(幻读) 两次读取的数据不一致(强调的是insert操作,数据的总条数变化)
###事务的隔离级别
数据库中一共有四种隔离级别
1.Serializable:可避免脏读 不可重复读 虚读情况的发生.(串行化)
2.Repeatable read:可避免脏读 不可重复读情况发生(输入一个commit即可得到最新数据) .(可重复读)不可避免虚读
3.Read committed:可避免脏读情况发生(读已提交)
4.Read uncommitted:最低级别,以上情况均无法保证(读未提交)
####mysql默认的隔离级别是什么?怎么设置隔离级别?
mysql默认隔离级别是Repeatable read 级别
select @@tx_isolation 查询当起事务隔离级别
set session transaction isolation level 设置事务隔离级别
set session transaction isolation level Read uncommitted;
serializable会出现锁表情况
安全性越高的,性能越低
下面我们用mysql具体来看看不同的事务隔离级别会发生什么.
- 准备一个表account,用两个Mysql打开打开,就像这样:
- 我们已经知道Mysql默认事务隔离级别是Repeatable read,我们先来看看能不能避免脏读和不可重复读:
- 由于csdn传图片卡到爆?以后有空再弄…
###JDBC设置事务的隔离级别
在connection接口中提供
setTransactionIsolation(int level)用来设置事务的隔离级别
四个级别字段
小结:
1.Statementment与PreparedStatement执行批处理的特点
Statement适合执行多条不同的sql
PreparedStatement适合执行相同的sql
2.事务
一组操作,要么全部成功,要么全不成功
3.mysql中的事务管理
1.start transcation rollback commit.
2.mysql中的事务默认是
autocommit=on 可手动修改
autocommit=off
oracle数据库它的事务必须手动提交
4.jdbc管理事务
Connection下的
1.setAutoCommit(boolean flag)
2.rollback
3.commit
4.Savepoint回滚点
5.事务特性 (重点)
ACID
原子性 一致性 gelixing 持久性
6.隔离性
不考虑隔离性会发生什么问题?
1.脏读 2.不可重复读 3虚读(幻读)
7.隔离级别
1.Serializable:可避免脏读 不可重复读 虚读情况的发生.(串行化)
2.Repeatable read:可避免脏读 不可重复读情况发生(输入一个commit即可得到最新数据) .(可重复读)不可避免虚读
3.Read committed:可避免脏读情况发生(读已提交)
4.Read uncommitted:最低级别,以上情况均无法保证(读未提交)
8.jdbc怎样设置事务的隔离级别
setTranscationIsolation(int level)