本文主要内容:JDBC实现数据库的增删改查操作—Version2.0(事务版)
一、 数据库事务简要说明
-
什么叫数据库事务?
事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态
一组逻辑操作单元:一个或多个DML语句 -
事务处理的原则:保证所有的事务都作为一个工作单元来执行,即使处理故障,都不能改变这种方式,要么所有的事务都被提交(commit),这些修改就会永久的保存;要么就整个事务回滚(rollback)到最初状态
-
数据一旦提交,就不可回滚
-
哪些操作会导致数据的自动提交?
DDL操作一旦执行,都会自动提交
set autocommit = false对DDL失效
DML默认会自动提交
我们可以通过set autocommit = false的方式取消自动提交
关闭数据库链接库时也会自动提交
二、获取数据库连接与关闭的通用方法 2.0版
//通用的增删改操作---version 2.0 开启事务版
public int update(Connection conn, String sql, Object...args){
PreparedStatement ps = null;
try {
//1. 预编译sql语句,返回PrepareStatement实例
ps = conn.prepareStatement(sql);
//2. 填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
//3.执行
return ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
//4. 资源关闭
JDBCUtils.closeResource(null, ps);
}
return 0;
}
/**
* 转账功能测试
*/
@Test
public void testUpdate() {
Connection coon = null;
try {
coon = JDBCUtils.getConnection();
//取消数据的自动提交(必须执行此步)否则DML语句默认自动提交
coon.setAutoCommit(false);
String sql1 = "update account set money = money - 100 where name = ?";
update(coon, sql1, "MT");
//模拟转账异常情况,开启事务只会可以让数据回滚,防止钱不翼而飞的情况
System.out.println(10 / 0);
String sql2 = "update account set money = money + 100 where name = ?";
update(coon, sql2, "F6");
System.out.println("转账成功");
//2. 数据提交
coon.commit();
} catch (Exception e) {
System.out.println("转账失败");
try {
if (coon != null) {
coon.rollback();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
//修改commit为自动提交, 主要应用于数据库连接池
try {
if (coon != null) {
coon.setAutoCommit(true);
}
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(coon, null);
}
}
二、数据库表中查的通用方法 2.0版
//通用的查询操作---version 2.0 开启事务版
public <T> List<T> MultiplyQuery(Connection coon, Class<T> clazz, String sql, Object...args){
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = coon.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
//获取结果的元数据:ResultSetMetaData
ResultSetMetaData rsm = rs.getMetaData();
//通过ResultSetMetaData获取结果集的列数
int columnCount = rsm.getColumnCount();
//创建集合对象
ArrayList<T> list = new ArrayList<>();
while (rs.next()) {
T t = clazz.getDeclaredConstructor().newInstance();
//处理结果集一行数据的每一个列
for (int i = 0; i < columnCount; i++) {
//获取列值
Object columnValue = rs.getObject(i + 1);
//getColumnLabel():在sql有别名的情况下,可以获得别名,无别名的情况下,可以获得原列名
String columnLabel = rsm.getColumnLabel(i + 1);
//给stu对象指定的columnLabel属性,赋值为columnValue:通过反射
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null, ps, rs);
}
return null;
}