2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > spring批处理mysql语句_Spring框架——批处理(batch)和事务(Transaction)

spring批处理mysql语句_Spring框架——批处理(batch)和事务(Transaction)

时间:2023-12-16 14:36:11

相关推荐

spring批处理mysql语句_Spring框架——批处理(batch)和事务(Transaction)

批处理(batch)

批处理(batch)------------>好比快递员【不能一件一件的送快递】

- 批处理指的是一次操作中执行多条SQL语句

- 批处理相比于一次一次执行效率会提高很多

- 批处理主要是分两步:

1.将要执行的SQL语句保存

2.执行SQL语句

- Statement和PreparedStatement都支持批处理操作,这里我们只需要掌握PreparedStatement的批处理方式:

- 方法:

void addBatch()

- 将要执行的SQL先保存起来,先不执行

- 这个方法在设置完所有的占位符之后调用

int[] executeBatch()

- 这个方法用来执行SQL语句,这个方法会将批处理中所有SQL语句执行

- mysql默认批处理是关闭的,所以我们还需要去打开mysql的批处理:

rewriteBatchedStatements=true

我们需要将以上的参数添加到mysql的url地址中

- 注意:低版本的mysql-jdbc驱动也不支持批处理,一般都是在修改的时候使用批处理,查询的时候不使用!

案例演示:

1.创建一张新的数据表

CREATE TABLE t_emp(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(50)

)

2.反复打开数据库客户端,插入语句【相当于每次获取一个connection连接,执行executeUpdate语句】

INSERT INTO t_emp(NAME) VALUES('张三');

SELECT * FROM t_emp;

3.引出批处理--->执行效率高,资源利用率好!

@Test//测试批处理

public void testBatch(){

//向t_emp表中插入10000条数据

//准备两个变量

Connection connection = null;

PreparedStatement ps = null;

try {

//获取数据库连接

connection=JDBCUtil.getConnection();

//准备SQL模板

String sql = "INSERT INTO t_emp(NAME) VALUES(?)";

//获取PrepareStatement

ps = connection.prepareStatement(sql);

//创建一个for循环,来设置占位符

for(int i = 0; i < 10000 ;i++){

//填充占位符

ps.setString(1,"emp"+i);

//添加到批处理方法中,调用无参的,有参的是Statement来调用的!

ps.addBatch();

}

//获取一个时间戳

long start = System.currentTimeMillis();

//执行批处理

ps.executeBatch();

//获取一个时间戳

long end = System.currentTimeMillis();

System.out.println("共花费了:"+(end-start));

} catch (SQLException e) {

e.printStackTrace();

}

}

事务(Transaction)

演示银行转账的功能:

1.创建一张表示账号的表

CREATE TABLE t_account(

id INT PRIMARY KEY AUTO_INCREMENT,

a_name VARCHAR(50),

balance DECIMAL(11,2)

)

2.向表中插入几个用户

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转账100元

从sunwukong的账号减去100元

UPDATE t_account SET balance = balance - 100 WHERE a_name='sunwukong';

给shaheshang的账号加上100元

UPDATE t_account SET balance = balance +100 WHERE a_name = 'shaheshang';

重新设置为1000元:

UPDATE t_account SET balance =1000;

4.从java代码中演示上面的案例:

1.创建Dao类

public class AcountDao {

public void update(String name,double money){

//准备两个变量

Connection conn = null;

PreparedStatement ps = null;

//准备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);

//执行SQL语句

ps.executeUpdate();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

JDBCUtil.close(conn, ps, null);

}

}

}

2.测试该DAO

public class TestTransaction {

private AcountDao accountDao = new AcountDao();

@Test

public void test() {

//从sunwukong账户向shaheshang账户转账100元!

//1.从sunwukong账户扣除100元

accountDao.update("sunwukong", -100);

//2.向shaheshang账户添加100元

accountDao.update("shaheshang", 100);

}

}

显然上面是可以正常执行的!

但是如果上面的程序在suwukong减去100元之后,shaheshang加钱之前,出现了异常,如下所示:

//从sunwukong账户向shaheshang账户转账100元!

//1.从sunwukong账户扣除100元

accountDao.update("sunwukong", -100);

int i =10/0;//添加一个异常

//2.向shaheshang账户添加100元

accountDao.update("shaheshang", 100);

- 在开发中我们的一个业务往往需要同时操作多个表,这些操作往往是不可分割,业务中的对数据库的多次操作,

要么同时成功,要么全都失败。

- 事务的特性(ACID):

原子性(atomicity)

一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)

事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)

一个事务的执行不能被其他事务干扰。

即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)

持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

接下来的其他操作或故障不应该对其有任何影响。

- 操作事务的基本步骤:

1.开启事务

- 开启事务以后,我们只后的所有操作将都会在同一个事务当中

2.操作数据库

- 开启事务以后再去操作数据库,所有操作将不会直接提交到数据库中

3.提交事务

- 将修改应用到数据库

4.回滚事务

- 数据库操作过程中出现异常了,回滚事务,回滚事务以后,数据库变成开启事务之前的状态

- mysql中的事务控制

#开启事务

START TRANSACTION

#回滚事务

ROLLBACK

#提交事务

COMMIT

- JDBC中的事务主要通过Connection对象来控制的

1.开启事务

void setAutoCommit(boolean autoCommit) throws SQLException;

- 设置事务是否自动提交,默认是自动提交

- 设置事务手动提交

conn.setAutoCommit(false);

2.提交事务

void commit() throws SQLException;

- 提交事务

mit()

3.回滚事务

void rollback() throws SQLException;

- 回滚事务

conn.rollback()

- 事务控制的格式:

//创建一个Connection

Connection conn = null;

try{

//获取Connection

conn = JDBCUtils.getConnection();

//开启事务

conn.setAutoCommit(false);

//对数据库进行操作

//操作成功,提交事务

mit();

}catch(Exception e){

e.printStackTrace();

//回滚事务

try {

conn.rollback();

} catch (SQLException e1) {

e1.printStackTrace();

}

}finally{

JDBCUtils.close(conn, null, null);

}

- 注意:我们在同一个事务中使用的数据库连接(Connection)必须是同一个,否则事务还是不作用!

所以此时原来的AcountDAO中的update方法要改为如下所示:

public class AcountDao {

public void update(Connection conn,String name,double money){

//准备两个变量

PreparedStatement ps = null;

//准备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);

//执行SQL语句

ps.executeUpdate();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

//此时也不能在这里关闭数据库连接了,而是在外边统一关闭

JDBCUtil.close(null, ps, null);

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。