首页 技术 正文
技术 2022年11月23日
0 收藏 317 点赞 5,191 浏览 6980 个字

MySQL数据库学习笔记(十)—-JDBC事务处理、封装JDBC工具类

一、JDBC事务处理:

我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败。在MySQL中提供了Commit、Rollback命令进行事务的提交与回滚。实际上在JDBC中也存在事务处理,如果要想进行事务处理的话,则必须按照以下的步骤完成。

JDBC中事务处理的步骤:

1、要取消掉JDBC的自动提交:void setAutoCommit(boolean autoCommit)

2、执行各个SQL语句,加入到批处理之中

3、如果所有语句执行成功,则提交事务 commit();如果出现了错误,则回滚:rollback()

核心代码:

MySQL JDBC事务处理、封装JDBC工具类

conn.setAutoCommit(false); // 取消自动提交把SQL语句加入批处理stmt.addBatch(…) ()stmt.addBatch(…)//执行批处理操作stmt.executeBatch();conn.commit(); // 提交事务//如果发生错误conn.rollback();

MySQL JDBC事务处理、封装JDBC工具类

代码举例:

首先在sql中创建一个空的数据库,现在在java中,使用PreparedStatement插入数据并修改数据。正常情况下,代码应该这样写:

MySQL JDBC事务处理、封装JDBC工具类

 1 package com.vae.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 9 public class JDBCtest {101112     //数据库连接地址13     public final static String URL = "jdbc:mysql://localhost:3306/JDBCdb";14     //用户名15     public final static String USERNAME = "root";16     //密码17     public final static String PASSWORD = "smyh";18     //驱动类19     public final static String DRIVER = "com.mysql.jdbc.Driver";202122     public static void main(String[] args) {23         // TODO Auto-generated method stub24         //insert(p);25         //update(p);26         //delete(3);27         insertAndQuery();28     }293031     //方法:使用PreparedStatement插入数据、更新数据32     public static void insertAndQuery(){33         Connection conn = null;34         try {35             Class.forName(DRIVER);36             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);37             String sql1 = "insert into user(name,pwd)values(?,?)";38             String sql2 = "update user set pwd=? where name=?";39             PreparedStatement ps = conn.prepareStatement(sql1);40             ps.setString(1, "smyhvae");41             ps.setString(2, "007");42             ps.executeUpdate();4344             ps = conn.prepareStatement(sql2);45             ps.setString(1, "008");46             ps.setString(2, "smyh");47             ps.executeUpdate();4849             ps.close();50             conn.close();5152         } catch (ClassNotFoundException e) {53             e.printStackTrace();54         } catch (SQLException e) {55             e.printStackTrace();56         }57     }5859 }

MySQL JDBC事务处理、封装JDBC工具类

事务处理:

现在我们把上面的插入操作和修改操作变成一个事务,就要增加一部分代码了。修改上方的insertAndQuery()方法里面的代码:

MySQL JDBC事务处理、封装JDBC工具类

 1 //方法:使用PreparedStatement插入数据、更新数据 2     public static void insertAndQuery(){ 3         Connection conn = null; 4         try { 5             Class.forName(DRIVER); 6             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); 7             conn.setAutoCommit(false);//设置为手动提交事务 8             String sql1 = "insert into user(name,pwd)values(?,?)"; 9             String sql2 = "update user set pwd=? where name=?";10             PreparedStatement ps = conn.prepareStatement(sql1);11             ps.setString(1, "smyhvae");12             ps.setString(2, "007");13             ps.executeUpdate();1415             ps = conn.prepareStatement(sql2);16             ps.setString(1, "008");17             ps.setString(2, "smyh");18             ps.executeUpdate();19             conn.commit(); //如果所有sql语句成功,则提交事务20             ps.close();21             conn.close();2223         } catch (ClassNotFoundException e) {24             e.printStackTrace();25         } catch (SQLException e) {26             e.printStackTrace();27             try {28                 conn.rollback();//只要有一个sql语句出现错误,则将事务回滚29             } catch (SQLException e1) {30                 e1.printStackTrace();31             }32         }3334     }

MySQL JDBC事务处理、封装JDBC工具类

核心代码是第07行、19行、28行。这三行代码就完成了事务处理的操作。两个sql语句中,只要有一个语句出现错误,程序将无法运行,说明事务提交失败,且报错如下:

MySQL JDBC事务处理、封装JDBC工具类

二、封装JDBC工具类

之前的JDBC代码分析:

我们可以先回顾一下上一篇博文中的第五段:使用PreparedStatement重构增删改查。

通过分析可以发现有以下不足:有许多重复的代码、每次都要加载驱动、获取连接等。增删改查无非只是slq语句不一样而已。

封装工具类就是一个抽象的过程,我们可以把现在代码中非常公用的代码抽取出来,形成一个工具类。

  • 第一步:抽象公共的代码到工具类。
  • 第二步:为提高可以连接不同数据库的能力,将连接数据库的URL、用户名,密码等信息编写在一个属性文件(jdbc.properties)中,方便以后进行修改。 

我们先把之前的文章中,使用PreparedStatement查询数据库的代码贴出来,方便和后面的内容进行对比,省的翻来翻去麻烦。

使用PreparedStatement查询数据库:(重构前)

在这之前,请建好一个Person类,参考上一篇博文就行了。然后,JDBCtest.java的代码如下:

MySQL JDBC事务处理、封装JDBC工具类

 1 package com.vae.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 9 public class JDBCtest {101112     //数据库连接地址13     public final static String URL = "jdbc:mysql://localhost:3306/JDBCdb";14     //用户名15     public final static String USERNAME = "root";16     //密码17     public final static String PASSWORD = "smyh";18     //驱动类19     public final static String DRIVER = "com.mysql.jdbc.Driver";202122     public static void main(String[] args) {23         // TODO Auto-generated method stub24         Person p = new Person();2526         p = findById(2);27         System.out.println(p);28     }29303132     // 使用PreparedStatement查询数据33     public static Person findById(int id){34         Person p = null;35         try {36             Class.forName(DRIVER);37             Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);38             String sql = "select name,age,description from person where id=?";39             PreparedStatement ps = conn.prepareStatement(sql);40             //设置占位符对应的值41             ps.setInt(1, id);4243             ResultSet rs = ps.executeQuery();44             if(rs.next()){45                 p = new Person();46                 p.setId(id);47                 p.setName(rs.getString(1));48                 p.setAge(rs.getInt(2));49                 p.setDescription(rs.getString(3));5051             }52             rs.close();53             ps.close();54             conn.close();555657         } catch (ClassNotFoundException e) {58             e.printStackTrace();59         } catch (SQLException e) {60             e.printStackTrace();61         }62         return p;63     }646566 }

MySQL JDBC事务处理、封装JDBC工具类

接下来开始真正的工作了,从零开始。

封装工具类:

新建工程文件,结构如下:

MySQL JDBC事务处理、封装JDBC工具类

(1)先新建一个DBUtils工具类:

MySQL JDBC事务处理、封装JDBC工具类

 1 package com.vae.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.ResourceBundle; 910 /**11  * 数据库操作工具类12  * @author lamp13  *14  */15 public class DBUtils {1617     //数据库连接地址18     public static String URL;19     //用户名20     public static String USERNAME;21     //密码22     public static String PASSWORD;23     //mysql的驱动类24     public static String DRIVER;2526     private static ResourceBundle rb = ResourceBundle.getBundle("com.vae.jdbc.db-config");2728     private DBUtils(){}2930     //使用静态块加载驱动程序31     static{32         URL = rb.getString("jdbc.url");33         USERNAME = rb.getString("jdbc.username");34         PASSWORD = rb.getString("jdbc.password");35         DRIVER = rb.getString("jdbc.driver");36         try {37             Class.forName(DRIVER);38         } catch (ClassNotFoundException e) {39             e.printStackTrace();40         }41     }42     //定义一个获取数据库连接的方法43     public static Connection getConnection(){44         Connection conn = null;45         try {46             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);47         } catch (SQLException e) {48             e.printStackTrace();49             System.out.println("获取连接失败");50         }51         return conn;52     }5354     /**55      * 关闭数据库连接56      * @param rs57      * @param stat58      * @param conn59      */60     public static void close(ResultSet rs,Statement stat,Connection conn){61             try {62                 if(rs!=null)rs.close();63                 if(stat!=null)stat.close();64                 if(conn!=null)conn.close();65             } catch (SQLException e) {66                 e.printStackTrace();67             }68     }6970 }

MySQL JDBC事务处理、封装JDBC工具类

28行:既然是工具类,一般不要实例化,此时可以采用单例设计模式,或者将构造方法私有化。

26行:很明显可以看到,我们是将连接数据库的URL、用户名,密码等信息编写在一个属性文件(jdbc.properties)中,稍后再来定义这个属性文件。

31行:为避免重复代码,使用静态代码块:只会在类加载的时候执行一次。

42行:定义一个获取数据库连接的方法

60行:关闭数据库连接

(2)接下来新建一个属性文件,new–>file,命名为:db-config.properties,代码如下:

jdbc.url=jdbc:mysql://localhost:3306/jdbcdbjdbc.username=rootjdbc.password=smyhjdbc.driver=com.mysql.jdbc.Driver

以后如果需要修改配置信息,只需要在这里改就行了。注意在上面的DBUtils类中是怎么来调用这个配置信息的。

(3)紧接着新建文件,定义好Person类:

Person.java

(4)然后开始编写主程序来测试一下:

MySQL JDBC事务处理、封装JDBC工具类

 1 package com.vae.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 8 9 public class Test {1011     public static void main(String[] args) {12         Person p = new Person();13         p = findById(1);14         System.out.println(p);15     }1617181920     /**21      * 查询的方法22      */23     public static Person findById(int id){24         Person p =null;25         //通过工具类获取数据库连接26         Connection conn = DBUtils.getConnection();27         PreparedStatement ps = null;28         ResultSet rs = null;29         String sql = "select name,age,description from person where id=?";30         try {31             ps = conn.prepareStatement(sql);32             //设置占位符对应的值33             ps.setInt(1, id);34             rs = ps.executeQuery();35             if(rs.next()){36                 p = new Person();37                 p.setName(rs.getString(1));38                 p.setAge(rs.getInt(2));39                 p.setDescription(rs.getString(3));40             }41         } catch (SQLException e) {42             e.printStackTrace();43         }finally{44             //通过工具类关闭数据库连接45             DBUtils.close(rs, ps, conn);46         }47         return p;4849     }5051 }
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,440
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,857
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,695
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,450
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,096
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,248