一.JDB的批处理
应用环境:
需要批量保存信息,一次性执行大量数据。
用户类:
import java.io.Serializable; public class User implements Serializable{ private static final long serialVersionUID = 1L; private int id; private String name; public User() { super(); // TODO Auto-generated constructor stub } public User(int id, String name) { super(); this.setId(id); this.setName(name); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; public class JDBC_PCL { public static void main(String[] args) throws SQLException { //批处理:一次执行大量数据 // 创建100个 ArrayList<User> a = new ArrayList<>(); for (int i = 0; i < 100; i++) { User u = new User(i,"Ying"); a.add(u); } // 把100个用户添加到数据库中 Connection c = JDBCTool.getConnection(); String sql = "insert into users values(?,?)"; PreparedStatement ps = c.prepareStatement(sql); //方法一 :用循环插入用户 //方法二:用批处理插入 } }
工具类:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import com.mysql.jdbc.Statement; public class JDBCTool { // 工具类 // 作用:不让外界创建对象 // 私有 public static String url = null; public static String user = null; public static String password = null; static { // 加载驱动 try { Properties p = new Properties(); p.load(new FileInputStream("./src/jdbc.properties")); url = p.getProperty("url"); user = p.getProperty("name"); password = p.getProperty("passwrod"); Class.forName(p.getProperty("driverclass")); // System.out.println(url); // System.out.println(user); // System.out.println(password); // } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public JDBCTool() { super(); // TODO Auto-generated constructor stub } // 返回连接对象 public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url,user,password); } // 释放资源 public static void close(Connection c,PreparedStatement s ,ResultSet r) throws SQLException{ if(c!= null){ c.close(); } if(s!= null){ s.close(); } if(r!= null){ r.close(); } } public static void close(Connection c,PreparedStatement s ) throws SQLException{ if(c!= null){ c.close(); } if(s!= null){ s.close(); } } }
方法一:用循环插入用户
代码:
for (User u : a) { //给?赋值 ps.setInt(1, u.getId()); ps.setString(2, u.getName()); //执行 int i = ps.executeUpdate(); if (i != 0) { System.out.println("插入成功"); } else { System.out.println("插入失败"); } }
缺点:这样是能成功:但是要考虑的性能,因为你没执行一次,就会连接一次,java每建立一次链接 是很耗费资源的
方法二:利用批处理的方法
java.sqlpublic interfacePreparedStatement extendsStatement
接口 Statement接口 PreparedStatement方法:
voidaddBatch(String sql) throws SQLException
将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。通过调用方法 executeBatch 可以批量执行此列表中的命令。
voidclearBatch()throws SQLException
清空此 Statement 对象的当前 SQL 命令列表。
int[]executeBatch()throws SQLException
将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
代码:for (User u : a) { //给?赋值 ps.setInt(1, u.getId()); ps.setString(2, u.getName()); ps.addBatch(); } //添加批处理 addBatch(); 执行批处理 executeBatch(); 清空批处理:clearBatch(); //执行 ps.executeBatch(); //清空 ps.clearBatch(); //释放资源 JDBCTool.close(c, ps);
二.事务
1.基本概念:
事务指一组最小逻辑操作单元,里面有多个操作组成。组成的事务的每一部分必须要同时提交成功,如果有一个失败,整个操作就回滚。
2.事务(ACID)的特性
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另一个一致性状态。
隔离性(lsolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要互相隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
3.事务的特点
- 原子性:是一个最小逻辑操作单元
- 一致性:事务过程中,数据处于一致状态
- 持久性:事务一旦提交成功,对数据的更改会反映到数据库中
- 隔离性:事务与事务之间是隔离的
4.例子
需求:Yang给Fan 转账设计:账户表相关知识:
java.sql接口 Connection方法:
voidsetAutoCommit(boolean autoCommit) throws SQLException
将此连接的自动提交模式设置为给定状态。如果连接处于自动提交模式下,则它的所有 SQL 语句将被执行并作为单个事务提交。否则,它的 SQL 语句将聚集到事务中,直到调用 commit 方法或 rollback 方法为止。
voidcommit() throws SQLException
使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁。此方法只应该在已禁用自动提交模式时使用。
voidrollback()throws SQLException
取消在当前事务中进行的所有更改,并释放此 Connection 对象当前持有的所有数据库锁。此方法只应该在已禁用自动提交模式时使用。
SavepointsetSavepoint() throws SQLException
在当前事务中创建一个未命名的保存点 (savepoint),并返回表示它的新 Savepoint 对象。如果在活动事务范围之外调用 setSavepoint,则将在新创建的保存点上启动事务。
代码:
SQL:
JAVA:CREATE TABLE bank( name VARCHAR(10), money DOUBLE );
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import Demo01.JDBCTool;
public class ShiWu { public static void main(String[] args) { Connection c =null; PreparedStatement ps1 = null; PreparedStatement ps2 = null; //定义sql try { String sql1 = "updata bank set money=money-100 where name = 'yang'"; String sql2 = "updata bank set money=money+100 where name = 'fan'"; c = JDBCTool.getConnection(); c.setAutoCommit(false);//开启事务 ps1 =c.prepareStatement(sql1); ps2 =c.prepareStatement(sql2); //执行 ps1.executeUpdate(); System.out.println(1/0); ps2.executeUpdate(); } catch (SQLException e) { //一旦发生异常,回滚到最初状态 try { c.rollback(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } finally { //提交事务 try { c.commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } //释放资源 try { JDBCTool.close(c, ps1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { JDBCTool.close(c, ps2); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }