MySQL JDBC事务处理、封装JDBC工具类
MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类
一、JDBC事务处理:
我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败。在MySQL中提供了Commit、Rollback命令进行事务的提交与回滚。实际上在JDBC中也存在事务处理,如果要想进行事务处理的话,则必须按照以下的步骤完成。
JDBC中事务处理的步骤:
1、要取消掉JDBC的自动提交:void setAutoCommit(boolean autoCommit)
2、执行各个SQL语句,加入到批处理之中
3、如果所有语句执行成功,则提交事务 commit();如果出现了错误,则回滚:rollback()
核心代码:
conn.setAutoCommit(false); // 取消自动提交 把SQL语句加入批处理 stmt.addBatch(…) () stmt.addBatch(…) //执行批处理操作 stmt.executeBatch(); conn.commit(); // 提交事务 //如果发生错误 conn.rollback();
代码举例:
首先在sql中创建一个空的数据库,现在在java中,使用PreparedStatement插入数据并修改数据。正常情况下,代码应该这样写:
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 }
事务处理:
现在我们把上面的插入操作和修改操作变成一个事务,就要增加一部分代码了。修改上方的insertAndQuery()方法里面的代码:
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 }
核心代码是第07行、19行、28行。这三行代码就完成了事务处理的操作。两个sql语句中,只要有一个语句出现错误,程序将无法运行,说明事务提交失败,且报错如下:
二、封装JDBC工具类
之前的JDBC代码分析:
我们可以先回顾一下上一篇博文中的第五段:使用PreparedStatement重构增删改查。
通过分析可以发现有以下不足:有许多重复的代码、每次都要加载驱动、获取连接等。增删改查无非只是slq语句不一样而已。
封装工具类就是一个抽象的过程,我们可以把现在代码中非常公用的代码抽取出来,形成一个工具类。
- 第一步:抽象公共的代码到工具类。
- 第二步:为提高可以连接不同数据库的能力,将连接数据库的URL、用户名,密码等信息编写在一个属性文件(jdbc.properties)中,方便以后进行修改。
我们先把之前的文章中,使用PreparedStatement查询数据库的代码贴出来,方便和后面的内容进行对比,省的翻来翻去麻烦。
使用PreparedStatement查询数据库:(重构前)
在这之前,请建好一个Person类,参考上一篇博文就行了。然后,JDBCtest.java的代码如下:
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 }
接下来开始真正的工作了,从零开始。
封装工具类:
新建工程文件,结构如下:
(1)先新建一个DBUtils工具类:
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 }
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类:
(4)然后开始编写主程序来测试一下:
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工具类的更多相关文章
- JDBC深度封装的工具类 (具有高度可重用性)
首先介绍一下Dbutils: Common Dbutils是操作数据库的组件,对传统操作数据库的类进行二次封装,可以把结果集转化成List. 补充一下,传统操作数据库的类指的是JDBC(java ...
- 一、JDBC的概述 二、通过JDBC实现对数据的CRUD操作 三、封装JDBC访问数据的工具类 四、通过JDBC实现登陆和注册 五、防止SQL注入
一.JDBC的概述###<1>概念 JDBC:java database connection ,java数据库连接技术 是java内部提供的一套操作数据库的接口(面向接口编程),实现对数 ...
- JDBC封装的工具类
1. JDBC封装的工具类 public class JDBCUtil { private static Properties p = new Properties(); private static ...
- .NET3.5中JSON用法以及封装JsonUtils工具类
.NET3.5中JSON用法以及封装JsonUtils工具类 我们讲到JSON的简单使用,现在我们来研究如何进行封装微软提供的JSON基类,达到更加方便.简单.强大且重用性高的效果. 首先创建一个类 ...
- JAVA中封装JSONUtils工具类及使用
在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...
- Workbook导出excel封装的工具类
在实际中导出excel非常常见,于是自己封装了一个导出数据到excel的工具类,先附上代码,最后会写出实例和解释.支持03和07两个版本的 excel. HSSF导出的是xls的excel,XSSF导 ...
- writeValueAsString封装成工具类
封装成工具类 <span style="font-family:Microsoft YaHei;">public static String toJsonByObjec ...
- 转:轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)
搜了一下网络上别人封装的HttpClient,大部分特别简单,有一些看起来比较高级,但是用起来都不怎么好用.调用关系不清楚,结构有点混乱.所以也就萌生了自己封装HttpClient工具类的想法.要做就 ...
- 打印 Logger 日志时,需不需要再封装一下工具类?
在开发过程中,打印日志是必不可少的,因为日志关乎于应用的问题排查.应用监控等.现在打印日志一般都是使用 slf4j,因为使用日志门面,有助于打印方式统一,即使后面更换日志框架,也非常方便.在 < ...
- 【JDBC】Java 连接 MySQL 基本过程以及封装数据库工具类
一. 常用的JDBC API 1. DriverManager类 : 数据库管理类,用于管理一组JDBC驱动程序的基本服务.应用程序和数据库之间可以通过此类建立连接.常用的静态方法如下 static ...
随机推荐
- 异步的两种写法: async 与 BeginInvoke
现在要实现异步只要用关键字async/await就可以轻松实现,在此之前需要用到委托/回调等一堆东西. 对一下是对比写法: class Program { delegate string SendMe ...
- 普通图片转ascii码字符图
效果图 基本思路 把图片每个像素点的信息拿出来,最重要的是拿到rgb的值 把每个像素点由rgb转成灰度图像,即0-255 给0-255分级,把每个等级的像素点转换成ascii码,完成 实现 第一步:获 ...
- jquery 中获取URL参数的方法
今天写项目需要获取url后面的参数ref参数来判断是否开启计时器来刷新页面,之前一直都是用JS写的,今天在查资料的时候看到了一款JQ的插件 项目地址:https://github.com/allmar ...
- 不用SWIG,Go使用C++代码的方式
将C++代码用C作一次封装,就可以让Go调用了. 这是一个C++头文件: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #ifndef CGO_CPPGO_C ...
- Java多线程实现生产者消费者延伸问题
在操作系统中有一类问题被称为生产者消费者问题:意为,有数个生产者生产产品,有数个消费者消费产品,他们共享一定数量的缓存. 这里用java多线程编程,实现生产者消费者问题的一种延伸,橘子苹果问题. 题目 ...
- 相遇Qt5
使用Qt5.x版本中的不同方面来开发应用程序,着重于新的Qt Quick的技术,提供了编写C++后端的必要内容,并扩展了Qt Quick. 本章提供了关于Qt5高层次的概述.它对开发者有效的展 ...
- Cloudera Hadoop 4 实战课程(Hadoop 2.0、集群界面化管理、电商在线查询+日志离线分析)
课程大纲及内容简介: 每节课约35分钟,共不下40讲 第一章(11讲) ·分布式和传统单机模式 ·Hadoop背景和工作原理 ·Mapreduce工作原理剖析 ·第二代MR--YARN原理剖析 ·Cl ...
- 我在北京找工作(五):备战阿里巴巴java笔试<1>:筑基
@@@2013年9月11日 还在北京昌平区@@@ 好几天没有往博客上贴我的面试备战笔记了,今天开始分享一下备战阿里巴巴校招的笔经,当然重点是java方向的题目~. 插一段2014年阿里巴巴校招的消息: ...
- python 站点爬虫 下载在线盗墓笔记小说到本地的脚本
近期闲着没事想看小说,找到一个全是南派三叔的小说的站点,决定都下载下来看看,于是动手,在非常多QQ群里高手的帮助下(本人正則表達式非常烂.程序复杂的正则都是一些高手指导的),花了三四天写了一个脚本 须 ...
- Swift - 从ALAsset中获取照片的原图并转换成NSData
ALAsset类代表相册中的每个资源文件,可以通过它获取照片的相关信息,及其对应的原图,全屏图,缩略图等. 当我们想通过一个照片的ALAsset对象,来获取这张照片的原图并将其转换成NSData数据, ...