开发者学堂课程【JDBC 数据库开发进阶:jdbcUtils 】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/32/detail/692
jdbcUtils
内容简介:
1.DAO 中的事务
2.Service 才是处理事务的地方
3.修改 JdbcUtils
4.再次修改 JdbcUtils
1.DAO 中的事务
public void xxx() {
批注:在dao中处理事务,但dao中不应该存在业务,而只是对数据库的基本访问。
Connection con = null;
try {
con = JdbcUtils.getConnection();
con.setAutoCommitted(false);
QueryRunner gr = new QueryRunner();
String sal = ...;
Object[] params. =...;
qr.update(con, sql, params);
sql =...;
Object[] params= ...;
qr.update(con, sgl, params);
con.commit();
}catch(Exception e) {
try {
if(con != null) {con.rollback();}
}catch(Exception e){}
}finally {
try {
con.close();
}catch(Exception e){}
}
}
2. Service 才是处理事务的地方
DAO 中不是处理事务的地方,因为 DAO 中的每个方法都是对数据库的一次操作,而Service 中的方法才是对应一个业务逻辑。
也就是说我们需要在 service 中的一方法中调用 DAO 的多个方法,而这些方法应该在一起事务中。
怎么才能让 DAO 的多个方法使用相同的 Connection 呢?方法不能再自己来获得Connection ,而是由外界传递进去。
public void daoMethod1(Connection con,...) {
public void daoMethod2(Connection con,...) {
在Service中调用DAO的多个方法时,传递相同的 Connection就可以了。
public class XXXService(){
批注: Service 不应该出现Connection,它只应该在 dao,中出现
private XXXDao dao = new XXXDao();
public void serviceMethod(){
Connection con = null;
try {
con = JdbcUtils.getConnection();
con.setAutoCommitted(false);
dao.daoMethod1(con,...);
dao.doaMethod2(con,...);
com.commint();-
}catch(Exception e) {
try {
con.rollback();
catch(Exception e){}
}finally {
try {
con.close();
}catch(Exception e){}
}
}
}
但是,在service中不应该出现Connection,它应该只在DAO中出现,因为它是JDBC的东西,JDBC的东西是用来连接数据库的,连接数据库是DAO的事。但是,事务是service的事,不能放到DAO中。
3.修改 JdbcUtils
我们把对事务的开启和关闭放到 JdbcUtils ,中,在 Service 中调用 JdbcUtils 的方法来完成事务的处理,但在 Service 中就不会再出现 Connection 这一“禁忌”了。
DAO 中的方法不用再让 Service 来传递 Connection 了。DAO 会主动从 JdbcUtils中获取 Connection 对象,这样 JdbcUtils 成为了 DAO 和 Service 的中介。
我们在 JdbcUtils 中添加 begin Transaction() 和 rollbackTransaction() ,以及commitTransaction() 方法。这样在 Service 中的代码如下:
public class XXXService() {
批注:希望可以这样来处理事务,但Jdbcutils,还没有写好。
private XXXDao dao = new XXXDao();
public void serviceMethod(){
try {
JdbcUtils.beginTransaction();
批注:为con赋值,它不再为null
dao.daoMethod1 (...);
批注:内部Jdbutils.getConnection()如果con不为null,那么返回的是con,多次调用dao方法,返回的是同一个connection
dao.daoMethod2 (...);
JdbcUtils.co
mmitTransaction
();
批注:调用con.commit
}catch(Exception e){
JdbcUtils.rollbackTransaction();
批注:调用con.rollback()
}
}
4.再次修改 JdbcUtils
在 JdbcUtils ,Java 中调用三种方法, 先给出事务专用连接 private static connection con= null;
开启事务
//1.获取一个connection,设置它的setAutoComnmit (false)
//2.还要保证dao中使用的连接是我们刚刚创建的
//①创建一个connection,设置为手动提交
//②把这个connection给dao用
//③还要让conitTransaction或rollbackTransaction可以获取到
public static void beginTransaction () throw SQLException {
if(con == null) throw new SQLException("还没有开启事务,就不要重复开启了!");
//1.给con赋值
//2.给con设置为手动提交,给con赋值表示事务已经开始
con = getconneotion ( ) ;
con.setAutoComnit (false) ;
}
//提交事务
//1.获取beginTransaction提供的connection,然后调用cormit方法
public static void commitTransaction () {
if(con == null) throw new SQLException("还没有开启事务,不能提交!");
//直接使用con. commit ()
con.commit;
con.closeo;
//把它设置为null,表示事务已经结束了,下次再去调用getConnection()返回的就不是con了
con=null;
}
//提交事务
//1.获取beginTransaction提供的connection,然后调用rollback方法
public static void rollbackTransaction ( ) {
if(con == null) throw new SQLException("还没有开启事务,不能回滚!");
//直接使用con.rollback ( )
con.rollback();
con.close();
con=null;
}
//重新写出一个DAO
package cn.itcast.jdbc;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
public class AccountDao {
public static void update(string name,double money) throws SQLException {
QueryRunner qr = new QueryRunner ( );
string sql = "update account set balance=balance+ ? where name=? ";
object[] params ={money, name} ;
//我们需要自己来提供连接,保证多次调用使用的是同一个连接
Connection con = JdbcUtils.getConnection ();
qr. update (con,sql, params) ;
}
}
//再写一个代码Demo1.java
package cn.itcast.jdbc;
import java.sql.SQLException;
public class Demo1 {
private AccountDao dao = new AccountDao ( ) ;
public void serviceMethod() {
try {
JdbcUtils.beginTransaotion ( );
dao. update( "zs",-1000);
dao. update( "ls",1000);
jbcUtils.commitTransaction ();
}catch(Exception e) {
try{
JdbcUtils.rollbackTransaction ( );
}catch (sQIException e1) {
}
}
}
}