课程名称:Java工程师2022版
课程章节:Java与数据库连接的桥梁
课程讲师:IT老齐 悟空 八戒猪 神思者 Leo
课程内容:JDBC第三部分
一、JDBC的事务操作
1.什么是事务?
事务是以一种可靠的,一致的方式,访问和操作数据库的程序单元。
说人话:要么把事情做完,要么什么都不做,不要做一半。
事务依赖于数据库实现,MySQL通过事务区作为数据缓冲地带。
事务的话要么一次性全部完成,要么把之前做的都撤销。
应用程序执行写操作到事务区,然后进行commit提交操作,在提交后,写入数据库,写入后事务区把原来的清空掉。
应用程序执行写操作到事务区,如果使用rollback回滚的话事务区就会直接执行清空。
JDBC两种事务模式,JDBC允许两种事务模式,自动提交事务模式,手动提交事务模式。
2.自动提交事务模式
自动提交事务模式是指没执行一次写操作SQL,自动提交事务。
自动提交开启方法:conn.setAutoCommit(true)。
自动事务是JDBC默认行为,此模式无法保证多数据一致性。
3.手动提交事务模式
手动提交模式是指调用commit()与rollback()方法管理事务。
手动提交开启方法:conn.setAutoCommit(false)
手动提交事务可保证多数据一致性,但必须手动调用提交/回滚方法。
package com.imooc.jdbc.sample;
import com.imooc.jdbc.common.DbUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* JDBC中的事务控制
*/
public class TransactionSample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
try {
conn = DbUtils.getConnection();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//默认使用自动提交模式
conn.setAutoCommit(false); //关闭自动提交
String sql = "insert into employee(eno,ename,salary,dname) values(?,?,?,?)";
for(int i=1000;i<2000;i++){
if(i==1005){
// throw new RuntimeException("插入失败");
}
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1,i);
pstmt.setString(2,"员工" + i);
pstmt.setFloat(3,4000f);
pstmt.setString(4,"市场部");
pstmt.executeUpdate();
}
conn.commit(); //提交数据
} catch (SQLException e) {
e.printStackTrace();
try {
if(conn != null && !conn.isClosed()){
conn.rollback();
}
}catch (SQLException ex){
ex.printStackTrace();
}
} finally {
DbUtils.closeConnection(null,pstmt,conn);
}
}
}
使用JDBC事务控制机制完成多目标(员工)的插入。如果插入成功,那就不报错,进行commit提交;如果插入失败,那就进行回滚,执行Rullback;整个程序也是满足了要么全部成功,要么全部失败,不会有中间状态的出现。
二、基于实体类的封装分页
实体类会有三个要求:
1.具备默认构造函数
2.属性私有
3.存在getter与setter
package com.imooc.jdbc.hrapp.entity;
/**
* 员工实体类
*/
public class Employee {
/**
* 1.具备默认构造函数
* 2.属性私有
* 3.存在getter与setter
*/
public Employee(){
}
private Integer eno;
private String ename;
private Float salary;
private String dname;
public Integer getEno() {
return eno;
}
public void setEno(Integer eno) {
this.eno = eno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
}
满足以上三点要求,且实现了员工实体类。
package com.imooc.jdbc.hrapp.command;
import com.imooc.jdbc.common.DbUtils;
import com.imooc.jdbc.hrapp.entity.Employee;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
*分页查询员工数据
*/
public class PaginationCommand implements Command{
@Override
public void execute() {
Scanner in = new Scanner(System.in);
System.out.println("请输入页号:");
int page = in.nextInt();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List <Employee> list = new ArrayList ();
try {
conn = DbUtils.getConnection();
String sql = "Select * from employee limit ?,10";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1,(page-1)*10);
rs = pstmt.executeQuery();
while(rs.next()){
Integer eno = rs.getInt("eno");
String ename = rs.getString("ename");
Float salary = rs.getFloat("salary");
String dname = rs.getString("dname");
Employee emp = new Employee();
emp.setEno(eno);
emp.setEname(ename);
emp.setSalary(salary);
emp.setDname(dname);
list.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
实现分页查询员工数据功能。
课程总结:
完成了今天的学习目标:
1.JDBC的事务操作。
2.基于实体类实现分页数据封装。