jdbc mysql事务源代码_MySQL JDBC事务处理、封装JDBC工具类

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

一、JDBC事务处理:

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

JDBC中事务处理的步骤:

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

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

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

核心代码:

48304ba5e6f9fe08f3fa1abda7d326ab.png

conn.setAutoCommit(false); //取消自动提交

把SQL语句加入批处理

stmt.addBatch(…) ()

stmt.addBatch(…)

//执行批处理操作

stmt.executeBatch();

conn.commit(); //提交事务

//如果发生错误

conn.rollback();

48304ba5e6f9fe08f3fa1abda7d326ab.png

代码举例:

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 packagecom.vae.jdbc;

2

3 importjava.sql.Connection;

4 importjava.sql.DriverManager;

5 importjava.sql.PreparedStatement;

6 importjava.sql.ResultSet;

7 importjava.sql.SQLException;

8

9 public classJDBCtest {

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 voidmain(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 voidinsertAndQuery(){

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 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

事务处理:

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 //方法:使用PreparedStatement插入数据、更新数据

2 public static voidinsertAndQuery(){

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 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

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

86ef1cefc084cf66b98475778691eac3.png

二、封装JDBC工具类

之前的JDBC代码分析:

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

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

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

第一步:抽象公共的代码到工具类。

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

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

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

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 packagecom.vae.jdbc;

2

3 importjava.sql.Connection;

4 importjava.sql.DriverManager;

5 importjava.sql.PreparedStatement;

6 importjava.sql.ResultSet;

7 importjava.sql.SQLException;

8

9 public classJDBCtest {

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 voidmain(String[] args) {

23 //TODO Auto-generated method stub

24 Person p = newPerson();

25

26 p = findById(2);

27 System.out.println(p);

28 }

29

30

31

32 //使用PreparedStatement查询数据

33 public static Person findById(intid){

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 = newPerson();

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 returnp;

63 }

64

65

66 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

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

封装工具类:

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

48929d89a602bb84b6eb8cd050b410bb.png

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 packagecom.vae.jdbc;

2

3 importjava.sql.Connection;

4 importjava.sql.DriverManager;

5 importjava.sql.ResultSet;

6 importjava.sql.SQLException;

7 importjava.sql.Statement;

8 importjava.util.ResourceBundle;

9

10 /**

11 * 数据库操作工具类

12 * @authorlamp

13 *

14 */

15 public classDBUtils {

16

17 //数据库连接地址

18 public staticString URL;

19 //用户名

20 public staticString USERNAME;

21 //密码

22 public staticString PASSWORD;

23 //mysql的驱动类

24 public staticString DRIVER;

25

26 private static ResourceBundle rb = ResourceBundle.getBundle("com.vae.jdbc.db-config");

27

28 privateDBUtils(){}

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 staticConnection 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 returnconn;

52 }

53

54 /**

55 * 关闭数据库连接

56 * @paramrs

57 * @paramstat

58 * @paramconn

59 */

60 public static voidclose(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 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

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类:

8f900a89c6347c561fdf2122f13be562.png Person.java

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 packagecom.vae.jdbc;

2

3 importjava.sql.Connection;

4 importjava.sql.PreparedStatement;

5 importjava.sql.ResultSet;

6 importjava.sql.SQLException;

7

8

9 public classTest {

10

11 public static voidmain(String[] args) {

12 Person p = newPerson();

13 p = findById(1);

14 System.out.println(p);

15 }

16

17

18

19

20 /**

21 * 查询的方法

22 */

23 public static Person findById(intid){

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 = newPerson();

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 returnp;

48

49 }

50

51 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值