<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.learn</groupId><artifactId>day03_learn_01account</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.4</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.45</version></dependency><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
</project>
package com.learn.dao;import com.learn.domain.Account;import java.util.List;/*** 账户的持久层接口*/
public interface IAccountDao {/*** 查询所有* @return*/List<Account> findAllAccount();/*** 查询一个* @return*/Account findAccountById(Integer accountId);/*** 保存* @param account*/void saveAccount(Account account);/*** 更新* @param account*/void updateAccount(Account account);/*** 删除* @param acccountId*/void deleteAccount(Integer acccountId);/*** 根据名称查询账户* @param accountName* @return  如果有唯一的一个结果就返回,如果没有结果就返回null*          如果结果集超过一个就抛异常*/Account findAccountByName(String accountName);
}
package com.learn.factory;import com.learn.service.IAccountService;
import com.learn.utils.TransactionManager;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** 用于创建Service的代理对象的工厂*/
public class BeanFactory {private IAccountService accountService;private TransactionManager txManager;public void setTxManager(TransactionManager txManager) {this.txManager = txManager;}public final void setAccountService(IAccountService accountService) {this.accountService = accountService;}/*** 获取Service代理对象* @return*/public IAccountService getAccountService() {return (IAccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(),accountService.getClass().getInterfaces(),new InvocationHandler() {/*** 添加事务的支持** @param proxy* @param method* @param args* @return* @throws Throwable*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if("test".equals(method.getName())){return method.invoke(accountService,args);}Object rtValue = null;try {//1.开启事务txManager.beginTransaction();//2.执行操作rtValue = method.invoke(accountService, args);//3.提交事务txManager.commit();//4.返回结果return rtValue;} catch (Exception e) {//5.回滚操作txManager.rollback();throw new RuntimeException(e);} finally {//6.释放连接txManager.release();}}});}
}
package com.learn.service;import com.learn.domain.Account;import java.util.List;/*** 账户的业务层接口*/
public interface IAccountService {/*** 查询所有* @return*/List<Account> findAllAccount();/*** 查询一个* @return*/Account findAccountById(Integer accountId);/*** 保存* @param account*/void saveAccount(Account account);/*** 更新* @param account*/void updateAccount(Account account);/*** 删除* @param acccountId*/void deleteAccount(Integer acccountId);/*** 转账* @param sourceName        转出账户名称* @param targetName        转入账户名称* @param money             转账金额*/void transfer(String sourceName, String targetName, Float money);//void test();//它只是连接点,但不是切入点,因为没有被增强
}
package com.learn.utils;import javax.sql.DataSource;
import java.sql.Connection;/*** 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定*/
public class ConnectionUtils {private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();private DataSource dataSource;public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}/*** 获取当前线程上的连接* @return*/public Connection getThreadConnection() {try{//1.先从ThreadLocal上获取Connection conn = tl.get();//2.判断当前线程上是否有连接if (conn == null) {//3.从数据源中获取一个连接,并且存入ThreadLocal中conn = dataSource.getConnection();tl.set(conn);}//4.返回当前线程上的连接return conn;}catch (Exception e){throw new RuntimeException(e);}}/*** 把连接和线程解绑*/public void removeConnection(){tl.remove();}
}
package com.learn.utils;/*** 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接*/
public class TransactionManager {private ConnectionUtils connectionUtils;public void setConnectionUtils(ConnectionUtils connectionUtils) {this.connectionUtils = connectionUtils;}/*** 开启事务*/public  void beginTransaction(){try {connectionUtils.getThreadConnection().setAutoCommit(false);}catch (Exception e){e.printStackTrace();}}/*** 提交事务*/public  void commit(){try {connectionUtils.getThreadConnection().commit();}catch (Exception e){e.printStackTrace();}}/*** 回滚事务*/public  void rollback(){try {connectionUtils.getThreadConnection().rollback();}catch (Exception e){e.printStackTrace();}}/*** 释放连接*/public  void release(){try {connectionUtils.getThreadConnection().close();//还回连接池中connectionUtils.removeConnection();}catch (Exception e){e.printStackTrace();}}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置代理的service--><bean id="proxyAccountService" factory-bean="beanFactory" factory-method="getAccountService"></bean><!--配置beanfactory--><bean id="beanFactory" class="com.learn.factory.BeanFactory"><!-- 注入service --><property name="accountService" ref="accountService"></property><!-- 注入事务管理器 --><property name="txManager" ref="txManager"></property></bean><!-- 配置Service --><bean id="accountService" class="com.learn.service.impl.AccountServiceImpl"><!-- 注入dao --><property name="accountDao" ref="accountDao"></property></bean><!--配置Dao对象--><bean id="accountDao" class="com.learn.dao.impl.AccountDaoImpl"><!-- 注入QueryRunner --><property name="runner" ref="runner"></property><!-- 注入ConnectionUtils --><property name="connectionUtils" ref="connectionUtils"></property></bean><!--配置QueryRunner--><bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"></bean><!-- 配置数据源 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!--连接数据库的必备信息--><property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property><property name="user" value="root"></property><property name="password" value="123456"></property></bean><!-- 配置Connection的工具类 ConnectionUtils --><bean id="connectionUtils" class="com.learn.utils.ConnectionUtils"><!-- 注入数据源--><property name="dataSource" ref="dataSource"></property></bean><!-- 配置事务管理器--><bean id="txManager" class="com.learn.utils.TransactionManager"><!-- 注入ConnectionUtils --><property name="connectionUtils" ref="connectionUtils"></property></bean>
</beans>
package com.learn.service.impl;import com.learn.dao.IAccountDao;
import com.learn.domain.Account;
import com.learn.service.IAccountService;
import com.learn.utils.TransactionManager;import java.util.List;/*** 账户的业务层实现类** 事务控制应该都是在业务层*/
public class AccountServiceImpl_OLD implements IAccountService{private IAccountDao accountDao;private TransactionManager txManager;public void setTxManager(TransactionManager txManager) {this.txManager = txManager;}public void setAccountDao(IAccountDao accountDao) {this.accountDao = accountDao;}public List<Account> findAllAccount() {try {//1.开启事务txManager.beginTransaction();//2.执行操作List<Account> accounts = accountDao.findAllAccount();//3.提交事务txManager.commit();//4.返回结果return accounts;}catch (Exception e){//5.回滚操作txManager.rollback();throw new RuntimeException(e);}finally {//6.释放连接txManager.release();}}public Account findAccountById(Integer accountId) {try {//1.开启事务txManager.beginTransaction();//2.执行操作Account account = accountDao.findAccountById(accountId);//3.提交事务txManager.commit();//4.返回结果return account;}catch (Exception e){//5.回滚操作txManager.rollback();throw new RuntimeException(e);}finally {//6.释放连接txManager.release();}}public void saveAccount(Account account) {try {//1.开启事务txManager.beginTransaction();//2.执行操作accountDao.saveAccount(account);//3.提交事务txManager.commit();}catch (Exception e){//4.回滚操作txManager.rollback();}finally {//5.释放连接txManager.release();}}public void updateAccount(Account account) {try {//1.开启事务txManager.beginTransaction();//2.执行操作accountDao.updateAccount(account);//3.提交事务txManager.commit();}catch (Exception e){//4.回滚操作txManager.rollback();}finally {//5.释放连接txManager.release();}}public void deleteAccount(Integer acccountId) {try {//1.开启事务txManager.beginTransaction();//2.执行操作accountDao.deleteAccount(acccountId);//3.提交事务txManager.commit();}catch (Exception e){//4.回滚操作txManager.rollback();}finally {//5.释放连接txManager.release();}}public void transfer(String sourceName, String targetName, Float money) {try {//1.开启事务txManager.beginTransaction();//2.执行操作//2.1根据名称查询转出账户Account source = accountDao.findAccountByName(sourceName);//2.2根据名称查询转入账户Account target = accountDao.findAccountByName(targetName);//2.3转出账户减钱source.setMoney(source.getMoney()-money);//2.4转入账户加钱target.setMoney(target.getMoney()+money);//2.5更新转出账户accountDao.updateAccount(source);int i=1/0;//2.6更新转入账户accountDao.updateAccount(target);//3.提交事务txManager.commit();}catch (Exception e){//4.回滚操作txManager.rollback();e.printStackTrace();}finally {//5.释放连接txManager.release();}}
}
package com.learn.service.impl;import com.learn.dao.IAccountDao;
import com.learn.domain.Account;
import com.learn.service.IAccountService;import java.util.List;/*** 账户的业务层实现类** 事务控制应该都是在业务层*/
public class AccountServiceImpl implements IAccountService{private IAccountDao accountDao;public void setAccountDao(IAccountDao accountDao) {this.accountDao = accountDao;}public List<Account> findAllAccount() {return accountDao.findAllAccount();}public Account findAccountById(Integer accountId) {return accountDao.findAccountById(accountId);}public void saveAccount(Account account) {accountDao.saveAccount(account);}public void updateAccount(Account account) {accountDao.updateAccount(account);}public void deleteAccount(Integer acccountId) {accountDao.deleteAccount(acccountId);}public void transfer(String sourceName, String targetName, Float money) {System.out.println("transfer....");//2.1根据名称查询转出账户Account source = accountDao.findAccountByName(sourceName);//2.2根据名称查询转入账户Account target = accountDao.findAccountByName(targetName);//2.3转出账户减钱source.setMoney(source.getMoney()-money);//2.4转入账户加钱target.setMoney(target.getMoney()+money);//2.5更新转出账户accountDao.updateAccount(source);//            int i=1/0;//2.6更新转入账户accountDao.updateAccount(target);}
}
package com.learn.test;import com.learn.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** 使用Junit单元测试:测试我们的配置*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class AccountServiceTest {@Autowired@Qualifier("proxyAccountService")private  IAccountService as;@Testpublic  void testTransfer(){as.transfer("aaa","bbb",100f);}}

编写业务层和持久层事务控制代码并配置spring的ioc相关推荐

  1. 控制层远程调用业务层_如何应用数据访问服务层分离系统中的业务层和持久层之间耦合关系...

    软件项目实训及课程设计指导--如何应用数据访问服务层分离业务层和持久层之间耦合关系 作者已经在本系列文章<软件项目实训及课程设计指导--如何正确地设计J2EE应用系统持久层中的各个组件结构及关系 ...

  2. SSH、SSM三种框架及表示层、业务层和持久层的理解

    Struts(表示层)+Spring(业务层)+Hibernate(持久层) SSH:Struts(表示层)+Spring(业务层)+Hibernate(持久层) Struts:Struts是一个表示 ...

  3. 表现层、持久层、业务层

    为了实现web层(struts)和持久层(Hibernate)之间的松散耦合,我们采用业务代表(Business Delegate)和DAO(Data Access Object)两种模式.DAO模式 ...

  4. 面向对象——三层架构(表现层、业务层、持久层)

    ① 持久层:采用DAO模式,建立实体类和数据库表映射(ORM映射).也就是哪个类对应哪个表,哪个属性对应哪个列.持久层 的目的就是,完成对象数据和关系数据的转换. ② 业务层:采用事务脚本模式.将一个 ...

  5. 三层架构理解(表现层、业务层、持久层)

    三层架构:即表现层.业务层.持久层. 大话一下这三个层. 举例1+1=? 你输入1+1=?的地方就是表现层,业务层把1+1=?拆成"1","+","1 ...

  6. JAVA表示层,业务层,持久层的框架分别有哪些

    JAVA表示层,业务层,持久层的框架分别有哪些 1.表示层 JSP,Freemark,Velocity, 2.控制层 Struts,Struts2 3.持久层 Hibernate.Mybatis.My ...

  7. web项目的三层结构: 视图层,业务逻辑层,持久层

    web项目的三层结构: 视图层,业务逻辑层,持久层 (1)视图层:视图层很好解释 你现在看到的网页 一些界面 都属于表现层的东西可以用一些Html,jsp,Swing来实现 (2)业务逻辑层:业务层用 ...

  8. Spring中的事务控制(Transacion Management with Spring)

    1.1. 有关事务(Transaction)的楔子 1.1.1. 认识事务本身1.1.2. 初识事务家族成员 1.2. 群雄逐鹿下的Java事务管理 1.2.1. Java平台的局部事务支持1.2.2 ...

  9. SSH三种框架及表示层、业务层和持久层的理解

    SSH:Struts(表示层)+Spring(业务层)+Hibernate(持久层) 在项目开发的过程中,有时把整个项目分为三层架构,其中包括: 1.表示层(UI). 2.业务逻辑层(BLL) 3.数 ...

最新文章

  1. DIV同时使用两个class
  2. 用jQuery写的最简单的表单验证
  3. LiveVideoStackCon 一次全新的尝试,错过了就是一辈子
  4. 作者:马晓磊(1985-),男,北京航空航天大学交通科学与工程学院交通运输工程系副教授、博士生导师。...
  5. 2020微信生态全景运营白皮书:10大热门场景、5大案例剖析.pdf(附下载链接)
  6. 电脑插上U盘双击打不开应用程序右键可以打开问题
  7. 2018年全国多校算法寒假训练营练习比赛(第一场)C. 六子冲(模拟)
  8. 嵌入式系——软件管理工程
  9. 关闭笔记本电脑计算机键盘,笔记本小键盘怎么关闭,教您怎么关闭笔记本小键盘...
  10. 怎么成为一名Java架构师 都需要掌握哪些技术
  11. Linux操作系统课后参考答案
  12. apple pay代码实现
  13. java中怎样实现登陆界面_JAVA登陆界面的实现(一)
  14. 8.3 初步理解 Texture Alpha
  15. matalb laod时无法读取文件
  16. java计算机毕业设计 - 大转盘抽奖微信小程序
  17. 【倾心整理】高级工程师手写总结,入门到顶级程序员的学习方法
  18. 计算机网络的三种交换方式
  19. 高数——定积分计算大法之换元法
  20. 合租在北京,那些你不知道的事

热门文章

  1. jdbc mysql数据类型对比 (版本: 5.1)
  2. 第三章:3.2  get 请求
  3. [Leetcode] Binary Tree Maximum Path Sum
  4. Objective-C策略模式(Strategy)
  5. 关于编译器的一个疑问
  6. Netflix如何使用机器学习来提升流媒体质量?
  7. 基于WebSocket协议实现Broker
  8. redis之sorted sets类型及操作
  9. 《写给大家看的设计书:实例与创意(修订版)》—1你已经知道多少了?
  10. 洛谷——1064金明的预算方案————有依赖的背包