JDBC处理大文本,JDBC处理图片,JDBC进行批处理 数据库连接池
参考文献:https://www.cnblogs.com/shanheyongmu/p/5909539.html
参考文献:https://www.cnblogs.com/shanheyongmu/p/5909922.html
1. 事务(Transaction,简写为tx):
所谓事务是用户定义的一组操作,使数据从一种状态变换到另一种状态,要么同时成功,要么同时失败。
2. 事务的操作:
先定义开始一个事务,然后对数据作修改操作,这时如果提交(commit),这些修改就永久地保存下来,如果回退(rollback),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。
3. 事务的ACID属性:
Atomic原子性、Consistency一致性、Isolation [ˌaɪsəˈleɪʃn] 隔离性和 Durability 持久性。
1、原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2、一致性(Consistency):事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
3、隔离性(Isolation):事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4、持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。)
4. 如何在代码中去处理事务:
1.在JDBC中,事务是默认提交的. 必须先设置事务为手动提交.
connection对象.setAutoCommit(false);//设置事务为手动提交.
2.手动的提交事务.
connection对象.commit();
3.若出现异常必须回滚事务:
不回滚事务,总余额依然是正确的. 若不回滚事务,不会释放数据库资源.
connection对象.rollback();
6. 事务示例:
银行转帐功能: bank / money
过儿和姑姑: 过儿 : 10000块钱 姑姑 : 0块钱
转账:过儿要给姑姑转1000块钱
分析:转钱需要提供两条sql,但是程序员也会出错,比较代码写错了.
①update bank set money = money +1000 where name = '姑姑'
②代码出错, 会导致过儿账户钱少了,而姑姑账户没有收到钱,钱去哪了?
③update bank set money = money -1000 where name= '过儿'
解决办法 代码:
数据库:
CREATE TABLE `bank` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `money` double DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
com.domain包下的 实体类 Bank
package com.domain; public class Bank { private String name; private double money; public Bank(String name, double money) { super(); this.name = name; this.money = money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public Bank() { // TODO Auto-generated constructor stub } @Override public String toString() { return "Bank [name=" + name + ", money=" + money + "]"; } }
com.dao 包下的 IBankDao 接口
package com.dao; import com.domain.Bank; public interface IBankDao { void transMoney(Bank b1,Bank b2, double money); }
com.dao .impl 包 的 BankDaoImpl 实现类
package com.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.Util.JDBCUtil; import com.dao.IBankDao; import com.domain.Bank; public class BankDaoImpl implements IBankDao { // 单利模式获取 BankDaoImpl 类对象 private BankDaoImpl (){} private static BankDaoImpl instance = null; public static BankDaoImpl getInstance(){ if(instance == null){ return instance = new BankDaoImpl(); } return null; } @Override public void transMoney(Bank b1, Bank b2, double money) { Connection conn = null; PreparedStatement ps = null; try { conn = JDBCUtil.getInstance().getConnection(); //在JDBC中,事务是默认提交的true. 必须先设置事务为手动提交false conn.setAutoCommit(false); ps = conn.prepareStatement("update bank set money = money - ? where name = ? "); ps.setDouble(1, money); ps.setString(2, b1.getName() ); ps.executeUpdate(); // int a = 1/0; //错误代码 ps = conn.prepareStatement("update bank set money = money + ? where name = ?"); ps.setDouble(1, money); ps.setString(2, b2.getName()); ps.executeUpdate(); conn.commit(); //手动进行提交 } catch (Exception e) { try { conn.rollback(); //数据回滚 } catch (SQLException e1) { e1.printStackTrace(); } } JDBCUtil.getInstance().closeAll(null,ps,conn); } }
测试类
public class TestBank { @Test public void trans(){ Bank b1 = new Bank("过儿",10000); Bank b2 = new Bank("姑姑",0); BankDaoImpl.getInstance().transMoney(b1, b2, 1000); } }
7. 如何在JDBC中保存数据的时候获取自动生成的主键呢?
Statement方式:
int executeUpdate(String sql, int autoGeneratedKeys):执行SQL:
参数:autoGeneratedKeys,是否需要返回自动生成的主键.常量值:Statement.RETURN_GENERATED_KEYS.
ResultSet getGeneratedKeys():获取自动生成的主键
示列代码如下:
@Test public void statementTest() throws Exception { String sql = "insert into student (name, age) values ('zhangsan', 30)"; Connection connection = JdbcUtil.getConn(); Statement statement = connection.createStatement(); // statement.executeUpdate(sql); statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); ResultSet resultSet = statement.getGeneratedKeys(); if (resultSet.next()) { Long id = resultSet.getLong(1); System.out.println(id); } JdbcUtil.close(connection, statement, null); }
PreparedStatement方式:
PreparedStatement prepareStatement(String sql,int autoGeneratedKeys) :
创建PreparedStatement对象,病指定是否需要返回生成的主键. 常量值:Statement.RETURN_GENERATED_KEYS
示列代码:
public class PreparedStatementTest { @Test public void preparedStatement() throws Exception { String sql = "insert into student (name,age) values (?,?)"; Connection connection = JdbcUtil.getConn(); PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, "张三"); preparedStatement.setInt(2, 24); preparedStatement.executeUpdate(); ResultSet resultSet = preparedStatement.getGeneratedKeys(); if (resultSet.next()) { Long id = resultSet.getLong(1); System.out.println(id); } JdbcUtil.close(connection, preparedStatement, null); } }