1.JDBC相关API总结832
2.封装JDBCUtils[关闭连接,获得连接]8332.1说明在JDBC操作中,通常使用具有JDBCUtils来获取连接和释放资源,可以包装JDBC连接
2.2代码实现JDBCUTilss实际使用工具
com中的代码.stulzl.utils.JDBCUtils833package com.stulzl.utils;import java.io.FileInputStream;import java.io.IOException;import java.sql.*;import java.util.Properties;///这是工具类,完成 mysql 资源的连接和关闭 833public class JDBCUtils { //定义相关属性(4) 个), 因为只需要一份,所以,我们做出 static private static String user; //用户名 private static String password; //密码 private static String url; //url private static String driver; //驱动名 ///去static代码块进行初始化 static{ try { Properties properties = new Properties(); properties.load(new FileInputStream("src\\mysql.properties")); ////读取相关属性数据 user = properties.getProperty("user"); password = properties.getProperty("password"); url = properties.getProperty("url"); driver = properties.getProperty("driver"); } catch (IOException e) { //在实际开发中,我们可以这样处理 //1. 将编译异常转化为 运行异常 //2. 调用者可选择捕获异常,也可选择默认处理异常,比较方便. throw new RuntimeException(e); } } //连接数据库,回到Conection public static Connection getConnection(){ try { return DriverManager.getConnection(url,user,password); } catch (SQLException e) { //1. 将编译异常转化为 运行异常 //2. 调用者可选择捕获异常,也可选择默认处理异常,比较方便. throw new RuntimeException(e); } } ///关闭相关资源 ///分析可能关闭的资源 /* 1. ResultSet 结果集 2. Statement 或者 PreparedStatement 3. Connection 4. 若需要关闭资源,传入对象,否则传入对象 null */ public static void close(ResultSet set, Statement statement,Connection connection){ try { ///判断是否为nulll if(set!=null){ set.close(); } if(statement!=null){ statement.close(); } if(connection!=null){ connection.close(); } } catch (SQLException e) { //1. 将编译异常转化为 运行异常 //2. 调用者可以选择捕获异常,也可以选择默认处理异常,比较方便. throw new RuntimeException(e); } }}
JDBCUtils测试类_Use834package com.stulzl.utils;import org.junit.jupiter.api.Test;import javax.annotation.processing.SupportedAnnotationTypes;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;///如何使用JDBCUtils工具进行此类演示?dml和select完成 834public class JDBCUtils_Use { public static void main(String[] args) { } @Test public void testDML(){ //1.连接 Connection connection = null; //2.组织sql语句 String sql = "update actor set name=? where id = ?"; PreparedStatement preparedStatement=null; try { connection = JDBCUtils.getConnection(); /3.创建preparedStatent对象 preparedStatement = connection.prepareStatement(sql); //4. 给占位符赋值 preparedStatement.setString(1,“周星驰”); preparedStatement.setInt(2,2); //执行 preparedStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { ///关闭资源 JDBCUtils.close(null,preparedStatement,connection); } }}
SRC下的mysqll配置文件.propertiesuser=rootpassword=lzlurl=jdbc:mysql://localhost:3306/hsp_db02driverdriver=com.mysql.jdbc.Driver
2.2.1JDBCUtilsselect采用835testselect()方法///使用JDBCUtilsselect 835 @Test public void testSelect(){ //1.连接 Connection connection = null; //2.组织sql语句 String sql = "select * from actor where id=?"; PreparedStatement preparedStatement=null; ResultSet set = null; try { connection = JDBCUtils.getConnection(); /3.创建preparedStatent对象 preparedStatement = connection.prepareStatement(sql); //4. 给占位符赋值 preparedStatement.setInt(1,2); //执行,得到结果集 set = preparedStatement.executeQuery(); ///遍历结果集 while(set.next()){ int id = set.getInt("id");//这里提示(”id可以直接写,也可以写数字(按相应顺序) String name = set.getString("name"); String sex = set.getString("sex"); Date borndate = set.getDate("borndate"); String phone = set.getString("phone"); System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone); } } catch (SQLException e) { e.printStackTrace(); } finally { ///关闭资源 JDBCUtils.close(set,preparedStatement,connection); } }}
3.事务8363.1基本介绍8361.JDBC程序中创建Conection对象时,默认情况下会自动提交事务:每次执行SQL语句时,如果执行成功,会自动提交到数据库而不是回滚。
2.JDBC程序需要使用事务,以使多个SQL语句作为一个整体执行
3.调用Connectionsetautocomitit(false)自动提交事务可以取消
4.所有SQL语询成功实施后,调用Conection的commit();提交事务的方法
5.调用connectionrolback(),当其中一个操作失败或出现异常时。;方法回滚事务
3.2应用实例837模拟经典的转账业务
3.3不使用事务中可能出现的问题模拟-模拟经典转账业务8373.4利用事务解决上述问题-模拟经典转账业务837comm代码3.3和3.4.stulzl.transaction_Transaction_package com.stulzl.transaction_;import com.stulzl.utils.JDBCUtils;import org.junit.jupiter.api.Test;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;///演示如何在JDBC中使用事务 837public class Transaction_ { //不使用事务 @Test public void noTransaction(){ //1.连接 Connection connection = null; //2.组织sql语句 String sql = "update account1 set balance=balance-100 where id = 1"; String sql2 = "update account1 set balance=balance+100 where id = 2"; PreparedStatement preparedStatement=null; try { connection = JDBCUtils.getConnection();// 默认情况下,connection 默认自动提交 /3.创建preparedStatent对象 ///这里是给马云扣100 preparedStatement = connection.prepareStatement(sql); preparedStatement.executeUpdate();///执行第一条sqll ///这里抛出异常,我们的目的是让马云转账,但是马化腾没有收到(因为执行异常 // 表面代码将不再运行) 让我们更直观地感受接下来的事务操作 int i = 1/0; ///这里给马化腾加100 preparedStatement = connection.prepareStatement(sql2); preparedStatement.executeUpdate();//执行第二条sql2 } catch (SQLException e) { e.printStackTrace(); } finally { ///关闭资源 JDBCUtils.close(null,preparedStatement,connection); } } //使用事务来解决 @Test public void useTransaction(){ //1.连接 Connection connection = null; //2.组织sql语句 String sql = "update account1 set balance=balance-100 where id = 1"; String sql2 = "update account1 set balance=balance+100 where id = 2"; PreparedStatement preparedStatement=null; try { connection = JDBCUtils.getConnection();// 默认情况下,connection 默认自动提交 ///将connection设置为不自动提交 connection.setAutoCommit(false);///相当于开始事务 /3.创建preparedStatent对象 ///这里是给马云扣100 preparedStatement = connection.prepareStatement(sql); preparedStatement.executeUpdate();///执行第一条sqll //int i = 1/0;///这里抛出异常 ///这里给马化腾加100 preparedStatement = connection.prepareStatement(sql2); preparedStatement.executeUpdate();//执行第二条sql2 ///在这里提交事务 connection.commit(); } catch (SQLException e) { //我们可以在这里回滚,即撤销执行 SQL ////默认回滚到事务开始的状态 System.out.println("执行异常,撤销执行的 sql"); try { connection.rollback(); } catch (SQLException throwables) { throwables.printStackTrace(); } e.printStackTrace(); } finally { ///关闭资源 JDBCUtils.close(null,preparedStatement,connection); } }}
代码在E:java学习\初级\course17db_java_transaction-- 创建表 837CREATE TABLE account1(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(32) NOT NULL DEFAULT'',balance DOUBLE NOT NULL DEFAULT 0) CHARACTER SET utf8;-- 添加数据INSERT INTO account1 VALUES(NULL, 马云,3000);INSERT INTO account1 VALUES(NULL, "马化腾",10000);SELECT * FROM account1