一、JDBC是什么?二、JDBC使用的准备工作
1.环境准备2.创建数据库和表3.创建项目并引入jar包 三、JDBC开发
1.导入jar包2.注册驱动3.获得连接4.基本操作5.释放资源 四、MVC架构
1.domain包2.dao包3.service包4.controller包5.Utils包 五、安全性问题
1.原理2.解决 六、JDBC事务
1.事务的定义2.可能涉及到事务的常见操作3.java中的JDBC事务特点 七、数据库连接池(JDBC的提高)
一、JDBC是什么?
JDBC即java数据库连接,是执行SQL语句的API,由类和接口组成
驱动:两个设备(应用)之间通信的桥梁
配置好Java环境
2.创建数据库和表create database web_test3; use web_test3; create table user ( id int primary key auto_increment, username varchar (20), password varchar (20), nickname varchar (20), age int ); insert into user values (null,'aaa','123','小丽',34); insert into user values (null,'bbb','123','小王',32); insert into user values (null,'ccc','123','小李',28); insert into user values (null,'ddd','123','小钱',34);3.创建项目并引入jar包
引入mysql的jar包
三、JDBC开发 1.导入jar包导入mysql-connection-java-xxx-bin.jar包
2.注册驱动mysql 5以后可以省略注册驱动步骤
3.获得连接 4.基本操作 5.释放资源//1.导入jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "123456");
//4.获取执行者对象
Statement statement = conn.createStatement();
//5.执行sql语句并接收结果
String sql = "select * from user";
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.print(rs.getInt("id") + "t");
System.out.print(rs.getString("username") + "t");
System.out.print(rs.getString("password") + "t");
System.out.print(rs.getString("nickname") + "t");
System.out.print(rs.getInt("age") + "n");
}
//释放资源
rs.close();
conn.close();
四、MVC架构
1.domain包
存放实体类
public class Student {
//使用包装类,避免数据库中有列值为空导致异常
public Integer stu_id;
public String username;
public String password;
public String nickname;
public Integer stu_age;
public Date stu_birthday;
public Student() {
}
public Student(Integer stu_id, String username, String password, String nickname, Integer stu_age, Date stu_birthday) {
this.stu_id = stu_id;
this.username = username;
this.password = password;
this.nickname = nickname;
this.stu_age = stu_age;
this.stu_birthday = stu_birthday;
}
public Integer getStu_id() {
return stu_id;
}
public void setStu_id(Integer stu_id) {
this.stu_id = stu_id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Integer getStu_age() {
return stu_age;
}
public void setStu_age(Integer stu_age) {
this.stu_age = stu_age;
}
public Date getStu_birthday() {
return stu_birthday;
}
public void setStu_birthday(Date stu_birthday) {
this.stu_birthday = stu_birthday;
}
@Override
public String toString() {
return "Student{" +
"stu_id=" + stu_id +
", username='" + username + ''' +
", password='" + password + ''' +
", nickname='" + nickname + ''' +
", stu_age=" + stu_age +
", stu_birthday=" + stu_birthday +
'}';
}
}
2.dao包
负责:与数据库进行交互
dao类:编写抽象功能方法
daoImpl类:实现dao类的抽象方法
原生StudentDaoImpl类
//StudentDao接口
public interface StudentDao {
//查询所有学生信息
public abstract ArrayList findAll() ;
//条件查询,根据id获取学生信息
public abstract Student findById(Integer id) ;
//新增学生信息,返回值为int,表示影响的行数
public abstract int insert(Student stu) ;
//修改学生信息
public abstract int update(Student stu) ;
//删除学生信息
public abstract int delete(Integer id) ;
}
//原生StudentDaoImpl类
public class StudentDaoImpl implements StudentDao{
//查询所有学生信息
@Override
public ArrayList findAll() {
ArrayList list = new ArrayList<>();
//为了在finally中释放资源,在此处做对象的抽取
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
//1.注册驱动(可省略)
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "123456");
//3.获取执行者对象
statement = conn.createStatement();
//4.执行sql语句,并且接收返回的结果集
String sql = "select * from user";
rs = statement.executeQuery(sql);
//5.处理结果集
while (rs.next()){
Integer stu_id = rs.getInt("id");
String stu_username = rs.getString("username");
String stu_password = rs.getString("password");
String stu_nickname = rs.getString("nickname");
Integer stu_age = rs.getInt("age");
Date stu_birthday = rs.getDate("birthday");
Student student = new Student(stu_id, stu_username, stu_password, stu_nickname, stu_age, stu_birthday);
list.add(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
//因为对象已经抽取出去且仅在try中赋值;一旦出现异常,则三个对象仍为空值,此时关闭则会导致异常
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//返回集合对象
return list;
}
@Override
public Student findById(Integer id) {
Student stu = new Student();
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "123456");
statement = conn.createStatement();
String sql = "select * from user where id = '"+id+"'";
rs = statement.executeQuery(sql);
while (rs.next()){
Integer stu_id = rs.getInt("id");
String stu_username = rs.getString("username");
String stu_password = rs.getString("password");
String stu_nickname = rs.getString("nickname");
Integer stu_age = rs.getInt("age");
Date stu_birthday = rs.getDate("birthday");
stu.setStu_id(stu_id);
stu.setUsername(stu_username);
stu.setPassword(stu_password);
stu.setNickname(stu_nickname);
stu.setStu_age(stu_age);
stu.setStu_birthday(stu_birthday);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return stu;
}
@Override
public int insert(Student stu) {
Connection conn = null;
Statement statement = null;
int result = 0;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "123456");
statement = conn.createStatement();
//执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
Date date = stu.getStu_birthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "insert into user values (null, '"+stu.getUsername()+"', '"+stu.getPassword()+"', '"+stu.getNickname()+"', '"+stu.getStu_age()+"', '"+birthday+"')";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return result;
}
@Override
public int update(Student stu) {
Connection conn = null;
Statement statement = null;
int result = 0;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "123456");
statement = conn.createStatement();
//执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
Date date = stu.getStu_birthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "update user set id='"+stu.getStu_id()+"'," +
"username='"+stu.getUsername()+"',password='"+stu.getPassword()+"'," +
"nickname='"+stu.getNickname()+"',age='"+stu.getStu_age()+"', " +
"birthday='"+stu.getStu_birthday()+"' where id='"+stu.getStu_id()+"' ";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return result;
}
@Override
public int delete(Integer id) {
Connection conn = null;
Statement statement = null;
int result = 0;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "123456");
statement = conn.createStatement();
String sql = "delete from user where id='"+id+"'";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return result;
}
}
使用JdbcUtils工具类的StudentDaoImpl类
public class StudentDaoImpl implements StudentDao{
//查询所有学生信息
@Override
public ArrayList findAll() {
ArrayList list = new ArrayList<>();
//为了在finally中释放资源,在此处做对象的抽取
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
//1.建立数据库连接
conn = JdbsUtils.getConnection();
//2.获取执行者对象
statement = conn.createStatement();
//3.执行sql语句,并且接收返回的结果集
String sql = "select * from user";
rs = statement.executeQuery(sql);
//4.处理结果集
while (rs.next()){
Integer stu_id = rs.getInt("id");
String stu_username = rs.getString("username");
String stu_password = rs.getString("password");
String stu_nickname = rs.getString("nickname");
Integer stu_age = rs.getInt("age");
Date stu_birthday = rs.getDate("birthday");
Student student = new Student(stu_id, stu_username, stu_password, stu_nickname, stu_age, stu_birthday);
list.add(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.释放资源
JdbsUtils.close(conn, statement, rs);
}
//返回集合对象
return list;
}
@Override
public Student findById(Integer id) {
Student stu = new Student();
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
conn = JdbsUtils.getConnection();
statement = conn.createStatement();
String sql = "select * from user where id = '"+id+"'";
rs = statement.executeQuery(sql);
while (rs.next()){
Integer stu_id = rs.getInt("id");
String stu_username = rs.getString("username");
String stu_password = rs.getString("password");
String stu_nickname = rs.getString("nickname");
Integer stu_age = rs.getInt("age");
Date stu_birthday = rs.getDate("birthday");
stu.setStu_id(stu_id);
stu.setUsername(stu_username);
stu.setPassword(stu_password);
stu.setNickname(stu_nickname);
stu.setStu_age(stu_age);
stu.setStu_birthday(stu_birthday);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbsUtils.close(conn, statement, rs);
}
//返回学生类对象
return stu;
}
@Override
public int insert(Student stu) {
Connection conn = null;
Statement statement = null;
int result = 0;
try {
conn = JdbsUtils.getConnection();
statement = conn.createStatement();
//执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
Date date = stu.getStu_birthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "insert into user values (null, '"+stu.getUsername()+"', '"+stu.getPassword()+"', '"+stu.getNickname()+"', '"+stu.getStu_age()+"', '"+birthday+"')";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbsUtils.close(conn, statement);
}
return result;
}
@Override
public int update(Student stu) {
Connection conn = null;
Statement statement = null;
int result = 0;
try {
conn = JdbsUtils.getConnection();
statement = conn.createStatement();
//4.执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
Date date = stu.getStu_birthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "update user set id='"+stu.getStu_id()+"'," +
"username='"+stu.getUsername()+"',password='"+stu.getPassword()+"'," +
"nickname='"+stu.getNickname()+"',age='"+stu.getStu_age()+"', " +
"birthday='"+stu.getStu_birthday()+"' where id='"+stu.getStu_id()+"' ";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
JdbsUtils.close(conn, statement);
}
return result;
}
@Override
public int delete(Integer id) {
Connection conn = null;
Statement statement = null;
int result = 0;
try {
conn = JdbsUtils.getConnection();
statement = conn.createStatement();
//4.执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
String sql = "delete from user where id='"+id+"'";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
JdbsUtils.close(conn, statement);
}
return result;
}
}
3.service包
进行业务操作
service类:编写抽象功能方法
serviceImpl类:创建Dao层对象,返回调用的Dao层结果
//StudentService接口
public interface StudentService {
//查询所有学生信息
public abstract ArrayList findAll() ;
//条件查询,根据id获取学生信息
public abstract Student findById(Integer id) ;
//新增学生信息,返回值为int,表示影响的行数
public abstract int insert(Student stu) ;
//修改学生信息
public abstract int update(Student stu) ;
//删除学生信息
public abstract int delete(Integer id) ;
}
//
public class StudentServiceImpl implements StudentService{
//因为要调用Dao层,故先声明Dao层对象
private StudentDao dao = new StudentDaoImpl();
//Dao层会返回一个集合对象,在此调用后返回
@Override
public ArrayList findAll() { return dao.findAll(); }
@Override
public Student findById(Integer id) { return dao.findById(id); }
@Override
public int insert(Student stu) { return dao.insert(stu); }
@Override
public int update(Student stu) { return dao.update(stu); }
@Override
public int delete(Integer id) { return dao.delete(id); }
}
4.controller包
控制层
public class StudentController {
//因为调用service层方法,故先声明service对象
private StudentService service = new StudentServiceImpl();
@Test
public void findAll(){
//调用service层的findAll()方法,会接收一个集合对象
ArrayList list = service.findAll();
//对集合对象进行遍历处理
for(Student stu:list){
System.out.println(stu);
}
}
@Test
public void findById() {
Student student = service.findById(3);
System.out.println(student);
}
@Test
public void insert() {
Student student = new Student(null, "fff", "123", "小小梁", 18, new Date());
int result = service.insert(student);
if (result != 0)
System.out.println("success");
else
System.out.println("fail");
}
@Test
public void update() {
Student student = service.findById(3);
student.setUsername("小小白");
int result = service.update(student);
if (result != 0)
System.out.println("success");
else
System.out.println("fail");
}
@Test
public void delete() {
int result = service.delete(3);
if (result != 0)
System.out.println("success");
else
System.out.println("fail");
}
}
5.Utils包
存放jdbc工具类(jdbc工具类抽取了dao层的重复的代码)。步骤:
(1)src目录下创建jdbc.properties配置文件
(2)编写工具类
"增、删、改"操作不涉及ResultSet结果集对象,但是”查询“操作涉及,故需要重载数据库关闭方法
public class JdbsUtils {
//1.私有构造方法
private JdbsUtils() {}
//2.声明所需要的配置变量
public static Connection conn;
private static String driverClass;
private static String url;
private static String username;
private static String password;
//3.提供静态代码块
static {
try {
//读取配置文件信息
InputStream is = JdbsUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(is);
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//注册驱动
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
}
}
//4.提供数据库连接方法
public static Connection getConnection(){
try {
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//5.提供数据库释放方法,"增、删、改"操作不涉及ResultSet结果集对象
public static void close(Connection conn, Statement stat){
if (conn != null){
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (stat != null){
try {
stat.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//方法重载,"查询"操作需要ResultSet结果集对象
public static void close(Connection conn, Statement stat, ResultSet rs){
if (conn != null){
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (stat != null){
try {
stat.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (rs != null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
五、安全性问题
简单使用Statement对象的系统会被sql注入攻击破解,如在登录页面的密码框出输入
aaa' or '1'='11.原理
Statement对象在执行sql语句时,将密码的一部分内容当作查询条件来执行了
2.解决解决的原理:在执行sql语句时,会提前将sql语句进行编译(明确sql语句格式),剩余内容将被视为参数(这样就不会将部分内容当作sql语句条件来执行)
使用PreparedStatement预编译执行者对象,在sql语句中使用”?“来当做占位符
为占位符"?"赋值的方法:调用setXxx(参数1, 参数2)方法
Xxx表示数据类型,参数1表示?的位置编号(从1开始),参数2表示?的实际参数,如:
String sql = "delete from user where name=?"; //对sql语句进行预编译 pstm = conn.prepareStatement(sql); pstm.setString(1, "张三");
执行sql语句
//执行insert、update、delete语句,用executeUpdate()方法 //执行select语句,用executeQuery()方法
完善版本的例子:
未解决的问题:update方法中对birthday的更新
public class StudentDaoImpl implements StudentDao{
//查询所有学生信息
@Override
public ArrayList findAll() {
ArrayList list = new ArrayList<>();
Connection conn = null;
PreparedStatement statement = null;
ResultSet rs = null;
try {
//1.建立数据库连接
conn = JdbsUtils.getConnection();
//2.获取执行者对象
String sql = "select * from user";
statement = conn.prepareStatement(sql);
//3.执行sql语句,并且接收返回的结果集
rs = statement.executeQuery(sql);
//4.处理结果集
while (rs.next()){
Integer stu_id = rs.getInt("id");
String stu_username = rs.getString("username");
String stu_password = rs.getString("password");
String stu_nickname = rs.getString("nickname");
Integer stu_age = rs.getInt("age");
Date stu_birthday = rs.getDate("birthday");
Student student = new Student(stu_id, stu_username, stu_password, stu_nickname, stu_age, stu_birthday);
list.add(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.释放资源
JdbsUtils.close(conn, statement, rs);
}
//返回集合对象
return list;
}
@Override
public Student findById(Integer id) {
Student stu = new Student();
Connection conn = null;
PreparedStatement statement = null;
ResultSet rs = null;
try {
conn = JdbsUtils.getConnection();
String sql = "select * from user where id=?";
statement = conn.prepareStatement(sql);
statement.setInt(1, id);
rs = statement.executeQuery();
while (rs.next()){
Integer stu_id = rs.getInt("id");
String stu_username = rs.getString("username");
String stu_password = rs.getString("password");
String stu_nickname = rs.getString("nickname");
Integer stu_age = rs.getInt("age");
Date stu_birthday = rs.getDate("birthday");
stu.setStu_id(stu_id);
stu.setUsername(stu_username);
stu.setPassword(stu_password);
stu.setNickname(stu_nickname);
stu.setStu_age(stu_age);
stu.setStu_birthday(stu_birthday);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbsUtils.close(conn, statement, rs);
}
return stu;
}
@Override
public int insert(Student stu) {
Connection conn = null;
PreparedStatement statement = null;
int result = 0;
try {
conn = JdbsUtils.getConnection();
//执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
Date date = stu.getStu_birthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "insert into user values (null, '"+stu.getUsername()+"', '"+stu.getPassword()+"', '"+stu.getNickname()+"', '"+stu.getStu_age()+"', '"+birthday+"')";
statement = conn.prepareStatement(sql);
result = statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbsUtils.close(conn, statement);
}
return result;
}
//未完善
@Override
public int update(Student stu) {
Connection conn = null;
PreparedStatement statement = null;
int result = 0;
try {
conn = JdbsUtils.getConnection();
//4.执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
Date date = stu.getStu_birthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "update user set id=?,username=?,password=?,nickname=?,age=?,birthday=? where id=?";
statement = conn.prepareStatement(sql);
statement.setInt(1, stu.getStu_id());
statement.setString(2, stu.getUsername());
statement.setString(3, stu.getPassword());
statement.setString(4, stu.getNickname());
statement.setInt(5, stu.getStu_age());
statement.setString(6, birthday);
statement.setInt(7, stu.getStu_id());
result = statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbsUtils.close(conn, statement);
}
return result;
}
@Override
public int delete(Integer id) {
Connection conn = null;
PreparedStatement statement = null;
int result = 0;
try {
conn = JdbsUtils.getConnection();
//4.执行sql语句,并且接收返回的结果集,生日为Date类型,需要重新格式化
String sql = "delete from user where id=?";
statement = conn.prepareStatement(sql);
statement.setInt(1, id);
result = statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbsUtils.close(conn, statement);
}
return result;
}
}
六、JDBC事务
1.事务的定义
JDBC操作可以对数据库进行增删改查,但当这些操作放在多线程高并发的平台下,会出现信息的不同步 问题,比如执行了一个修改操作后,在执行查询操作之前有一个线程也执行了修改语句,这时再执行查询操作,看到的信息就有可能与我们修改的不同,为了解决这一问题,必须引入JDBC事务机制(为了保证操作的原子性)
2.可能涉及到事务的常见操作(1)对数据库的批量操作
(2)多线程操作
(1)JDBC的事务是自动提交的
只要执行任意一条sql语句就会自动提交一次。当一个方法中会执行多次sql语句时,若前面的sql语句正常执行而后面出现错误时,前面的sql语句仍然会成功对数据库进行操作,这样就导致了安全问题
Connection conn = null;
PreparedStatement statement = null;
try {
conn = JdbsUtils.getConnection();
//将自动事务的自动提交机制修改为手动
conn.setAutoCommit(false);
String sql = "update user set age=? where id=?";
statement = conn.prepareStatement(sql);
statement.setInt(1, 1000);
statement.setInt(2, 2);
statement.executeUpdate();
System.out.println("我这执行完啦");
//设置错误
String str = null;
str.toString();
statement.setInt(1, 4000);
statement.setInt(2, 2);
statement.executeUpdate();
System.out.println("我也执行完啦,哈哈");
//如果程序执行可以执行到这,说明以上程序没有异常,开启提交
conn.commit();
} catch (SQLException throwables) {
//出现异常,回滚事务
try {
conn.rollback();
System.out.println("有问题,回滚事务");
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}finally {
JdbsUtils.close(conn, statement);
}
七、数据库连接池(JDBC的提高)
等待



