由于上述AccountDao存在具体的业务处理方法,导致AccountDao的职责不够单一,下面我们对AccountDao进行改造,让AccountDao的职责只是做CRUD操作,将事务的处理挪到业务层(BusinessService),改造后的AccountDao如下:
package wkcto.com.dao;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import wkcto.com.domain.Account;
import wkcto.com.util.JdbcUtils;
/*account测试表
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
insert into account(name,money) values('A',1000);
insert into account(name,money) values('B',1000);
insert into account(name,money) values('C',1000);
*/
/**
* @ClassName: AccountDao
* @Description: 针对Account对象的CRUD
*
*/
public class AccountDao {
//接收service层传递过来的Connection对象
private Connection conn = null;
public AccountDao(Connection conn){
this.conn = conn;
}
public AccountDao(){
}
/**
* @Method: update
* @Description:更新
* @param account
* @throws SQLException
*/
public void update(Account account) throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "update account set name=?,money=? where id=?";
Object params[] = {account.getName(),account.getMoney(),account.getId()};
//使用service层传递过来的Connection对象操作数据库
qr.update(conn,sql, params);
}
/**
* @Method: find
* @Description:查找
* @param id
* @return
* @throws SQLException
*/
public Account find(int id) throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "select * from account where id=?";
//使用service层传递过来的Connection对象操作数据库
return (Account) qr.query(conn,sql, id, new BeanHandler(Account.class));
}
}
接着对AccountService(业务层)中的transfer方法的改造,在业务层(BusinessService)中处理事务
package wkcto.com.service;
import java.sql.Connection;
import java.sql.SQLException;
import wkcto.com.dao.AccountDao;
import wkcto.com.domain.Account;
import wkcto.com.util.JdbcUtils;
/**
* @ClassName: AccountService
* @Description: 业务逻辑处理层
*/
public class AccountService {
/**
* @Method: transfer
* @Description:这个方法是用来处理两个用户之间的转账业务
* @param sourceid
* @param tartgetid
* @param money
* @throws SQLException
*/
public void transfer(int sourceid,int tartgetid,float money) throws SQLException{
Connection conn = null;
try{
//获取数据库连接
conn = JdbcUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//将获取到的Connection传递给AccountDao,保证dao层使用的是同一个Connection对象操作数据库
AccountDao dao = new AccountDao(conn);
Account source = dao.find(sourceid);
Account target = dao.find(tartgetid);
source.setMoney(source.getMoney()-money);
target.setMoney(target.getMoney()+money);
dao.update(source);
//模拟程序出现异常让事务回滚
int x = 1/0;
dao.update(target);
//提交事务
conn.commit();
}catch (Exception e) {
e.printStackTrace();
//出现异常之后就回滚事务
conn.rollback();
}finally{
conn.close();
}
}
}
经过改造,AccountDao只负责CRUD,里面没有具体的业务处理方法了,职责就单一了,而AccountService则负责具体的业务逻辑和事务的处理,需要操作数据库时,就调用AccountDao层提供的CRUD方法操作数据库,正好迎合程序“高内聚,低耦合”的开发原则。
不写代码你养我啊08-23 11:30
HelloWorld09-29 17:28
兔子06-15 17:15