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

时间:2023-01-02 14:27:23

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 {
10
11
12     //数据库连接地址
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";
20
21
22     public static void main(String[] args) {
23         // TODO Auto-generated method stub
24         //insert(p);
25         //update(p);
26         //delete(3);
27         insertAndQuery();
28     }
29
30
31     //方法:使用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();
43
44             ps = conn.prepareStatement(sql2);
45             ps.setString(1, "008");
46             ps.setString(2, "smyh");
47             ps.executeUpdate();
48
49             ps.close();
50             conn.close();
51
52         } catch (ClassNotFoundException e) {
53             e.printStackTrace();
54         } catch (SQLException e) {
55             e.printStackTrace();
56         }
57     }
58
59 }
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();
14
15             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();
22
23         } 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         }
33
34     }
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 {
10
11
12     //数据库连接地址
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";
20
21
22     public static void main(String[] args) {
23         // TODO Auto-generated method stub
24         Person p = new Person();
25
26         p = findById(2);
27         System.out.println(p);
28     }
29
30
31
32     // 使用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);
42
43             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));
50
51             }
52             rs.close();
53             ps.close();
54             conn.close();
55
56
57         } catch (ClassNotFoundException e) {
58             e.printStackTrace();
59         } catch (SQLException e) {
60             e.printStackTrace();
61         }
62         return p;
63     }
64
65
66 }
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;
 9
10 /**
11  * 数据库操作工具类
12  * @author lamp
13  *
14  */
15 public class DBUtils {
16
17     //数据库连接地址
18     public static String URL;
19     //用户名
20     public static String USERNAME;
21     //密码
22     public static String PASSWORD;
23     //mysql的驱动类
24     public static String DRIVER;
25
26     private static ResourceBundle rb = ResourceBundle.getBundle("com.vae.jdbc.db-config");
27
28     private DBUtils(){}
29
30     //使用静态块加载驱动程序
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     }
53
54     /**
55      * 关闭数据库连接
56      * @param rs
57      * @param stat
58      * @param conn
59      */
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     }
69
70 }
MySQL JDBC事务处理、封装JDBC工具类

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

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

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

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

60行:关闭数据库连接

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

jdbc.url=jdbc:mysql://localhost:3306/jdbcdb
jdbc.username=root
jdbc.password=smyh
jdbc.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 {
10
11     public static void main(String[] args) {
12         Person p = new Person();
13         p = findById(1);
14         System.out.println(p);
15     }
16
17
18
19
20     /**
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;
48
49     }
50
51 }

MySQL JDBC事务处理、封装JDBC工具类的更多相关文章

  1. JDBC深度封装的工具类 (具有高度可重用性)

    首先介绍一下Dbutils:    Common Dbutils是操作数据库的组件,对传统操作数据库的类进行二次封装,可以把结果集转化成List. 补充一下,传统操作数据库的类指的是JDBC(java ...

  2. 一、JDBC的概述 	二、通过JDBC实现对数据的CRUD操作 	三、封装JDBC访问数据的工具类 	四、通过JDBC实现登陆和注册 	五、防止SQL注入

    一.JDBC的概述###<1>概念 JDBC:java database connection ,java数据库连接技术 是java内部提供的一套操作数据库的接口(面向接口编程),实现对数 ...

  3. JDBC封装的工具类

    1. JDBC封装的工具类 public class JDBCUtil { private static Properties p = new Properties(); private static ...

  4. &period;NET3&period;5中JSON用法以及封装JsonUtils工具类

    .NET3.5中JSON用法以及封装JsonUtils工具类  我们讲到JSON的简单使用,现在我们来研究如何进行封装微软提供的JSON基类,达到更加方便.简单.强大且重用性高的效果. 首先创建一个类 ...

  5. JAVA中封装JSONUtils工具类及使用

    在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...

  6. Workbook导出excel封装的工具类

    在实际中导出excel非常常见,于是自己封装了一个导出数据到excel的工具类,先附上代码,最后会写出实例和解释.支持03和07两个版本的 excel. HSSF导出的是xls的excel,XSSF导 ...

  7. writeValueAsString封装成工具类

    封装成工具类 <span style="font-family:Microsoft YaHei;">public static String toJsonByObjec ...

  8. 转&colon;轻松把玩HttpClient之封装HttpClient工具类&lpar;一&rpar;(现有网上分享中的最强大的工具类)

    搜了一下网络上别人封装的HttpClient,大部分特别简单,有一些看起来比较高级,但是用起来都不怎么好用.调用关系不清楚,结构有点混乱.所以也就萌生了自己封装HttpClient工具类的想法.要做就 ...

  9. 【JDBC】Java 连接 MySQL 基本过程以及封装数据库工具类

    一. 常用的JDBC API 1. DriverManager类 : 数据库管理类,用于管理一组JDBC驱动程序的基本服务.应用程序和数据库之间可以通过此类建立连接.常用的静态方法如下 static ...

  10. java基础之JDBC三:简单工具类的提取及应用

    简单工具类: public class JDBCSimpleUtils { /** * 私有构造方法 */ private JDBCSimpleUtils() { } /** * 驱动 */ publ ...

随机推荐

  1. 【hihoCoder 1454】【hiho挑战赛25】【坑】Rikka with Tree II

    http://hihocoder.com/problemset/problem/1454 调了好长时间,谜之WA... 等我以后学好dp再来看为什么吧,先弃坑(╯‵□′)╯︵┻━┻ #include& ...

  2. Ubuntu杂记——Ubuntu下安装VMware

    转战Ubuntu,不知道能坚持多久,但是自己还是要努力把转战过程中的学习到的给记录下来.这次就来记录一下,Ubuntu下如何安装VMware. 就我所知,Linux下有VirtualBox和VMwar ...

  3. ORA-12537&colon; TNS&colon;connection closed

    http://www.vitalsofttech.com/ora-12537-tnsconnection-closed/ Question: When trying to establish a sq ...

  4. js组合继承和寄生组合式继承比较

    本文是原创文章,如需转载,请注明文章出处 1.js中实现组合继承(B继承A): function A(name){ this.name = name; this.ary = ["AA&quo ...

  5. 安装VS 2013遇到的问题,及解决方案

    一.在启动调试时报错 Visual Studio 2013 虽然集成安装了 IIS Express 8.0,但是并未安装 WebMatrix ,第一个问题就是这个原因造成的. 解决方案: 1.下载最新 ...

  6. 比较java与c语言中数字转换成字符的不同

    java java中将数字转换成字符非常方便,只要用一个"+"然后在跟一个空格行了.比如,你输入一个122 ,就会变成"122 ". import java.u ...

  7. Object C和C&num;的差异

    从C#到Object C,循序渐进学习苹果开发(1)--准备开发账号和开发环境 本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台开发苹果开发的一系列感想和体验历程,本系列文章是在起步 ...

  8. Classy&lpar;排序)

    Description In his memoir So, Anyway. . ., comedian John Cleese writes of the class di erence betwee ...

  9. 201521123024 《Java程序设计》 第九周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...

  10. mfc启动画面

    目标 用一张位图来作为启动画面,在进入程序时显示. 策略 在应用程序类的I n i t I n s t a n c e ()函数中,在最早时刻创建启动窗口.启动窗口用一个位图类显示在普通窗口中. 步骤 ...