转账示例:service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)
Posted 第九种格调的人生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转账示例:service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)相关的知识,希望对你有一定的参考价值。
用了AOP(面向切面编程),实现动态代理,service层面隐藏了开启事务。
1.自行创建C3P0Uti,account数据库,导入Jar包
2.Dao层面
接口:
package com.learning.dao;
import com.learning.domain.Account;
public interface AccountDao {
/**
* 转账
* @param fromname 转出用户
* @param toname 转入用户
* @param money 转账金额
*/
@Deprecated
public void updateAccount(String fromname,String toname,double money)throws Exception;
/**
* 根据账户信息修改金额
* @param accout
*/
public void updateAccout(Account accout) throws Exception;
/**
* 根据用户名查找账户信息
* @param name
* @return
* @throws Exception
*/
public Account findAccountByName(String name)throws Exception;
}
实现类:
package com.learning.dao.impl;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.learning.dao.AccountDao;
import com.learning.domain.Account;
import com.learning.util.C3P0Util;
public class AccountDaoImpl implements AccountDao {
private Connection conn;
public AccountDaoImpl(Connection conn) {
this.conn = conn;
}
public void updateAccount(String fromname, String toname, double money) throws Exception {
//创建一个QueryRunner对象
QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
qr.update("update account set money=money-? where name=?",money,fromname);
qr.update("update account set money=money+? where name=?",money,toname);
}
public void updateAccout(Account account) throws Exception {
QueryRunner qr = new QueryRunner();
qr.update(conn,"update account set money=? where name=?",account.getMoney(),account.getName());
}
public Account findAccountByName(String name) throws Exception {
QueryRunner qr = new QueryRunner();
return qr.query(conn,"select * from account where name=?", new BeanHandler<Account>(Account.class),name);
}
}
3.Service层面
接口:
package com.learning.service;
public interface AccountService {
/**
* 转账
* @param fromname 转出用户
* @param toname 转入用户
* @param money 转账金额
*/
public void transfer(String fromname,String toname,double money);
}
实现类:
package com.learning.service.impl; import java.sql.Connection; import java.sql.SQLException; import com.learning.dao.AccountDao; import com.learning.dao.impl.AccountDaoImpl; import com.learning.domain.Account; import com.learning.service.AccountService; import com.learning.util.C3P0Util; import com.learning.util.ManagerThreadLocal; public class AccountServiceImpl implements AccountService { public void transfer(String fromname, String toname, double money) throws Exception { // ad.updateAccount(fromname, toname, money); AccountDao ad = new AccountDaoImpl(); //分别得到转出和转入账户对象 Account fromAccount = ad.findAccountByName(fromname); Account toAccount = ad.findAccountByName(toname); //修改账户各自的金额 fromAccount.setMoney(fromAccount.getMoney()-money); toAccount.setMoney(toAccount.getMoney()+money); //完成转账操作 ad.updateAccout(fromAccount); int i = 10/0; ad.updateAccout(toAccount); } }
4.创建ManagerThreadLocal管理Connection
AccountDaoImpl(); try { ManagerThreadLocal.startTransacation();//begin //分别得到转出和转入账户对象 Account fromAccount = ad.findAccountByName(fromname); Account toAccount = ad.findAccountByName(toname); //修改账户各自的金额 fromAccount.setMoney(fromAccount.getMoney()-money); toAccount.setMoney(toAccount.getMoney()+money); //完成转账操作 ad.updateAccout(fromAccount); // int i = 10/0; ad.updateAccout(toAccount); ManagerThreadLocal.commit();//提交事务 } catch (Exception e) { try { ManagerThreadLocal.rollback();//回滚事务 } catch (Exception e1) { e1.printStackTrace(); } }finally{ try { ManagerThreadLocal.close(); } catch (Exception e) { e.printStackTrace(); }//关闭 } }package com.learning.util; import java.sql.Connection; import java.sql.SQLException; public class ManagerThreadLocal { private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); //得到一个连接 public static Connection getConnection(){ Connection conn = tl.get();//从当前线程中取出一个连接 if(conn==null){ conn = C3P0Util.getConnection();//从池中取出一个 tl.set(conn);//把conn对象放入到当前线程对象中 } return conn; } //开始事务 public static void startTransacation(){ try { Connection conn = getConnection(); conn.setAutoCommit(false);//从当前线程对象中取出的连接,并开始事务 } catch (SQLException e) { e.printStackTrace(); } } public static void commit(){ try { getConnection().commit();//提交事务 } catch (SQLException e) { e.printStackTrace(); } } public static void rollback(){ try { getConnection().rollback();//回滚事务 } catch (SQLException e) { e.printStackTrace(); } } public static void close(){ try { getConnection().close();//把连接放回池中 tl.remove();//把当前线程对象中的conn移除 } catch (SQLException e) { e.printStackTrace(); } } }
5.创建ProxyFactory(代理类)
package com.learning.util; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.learning.service.AccountService; import com.learning.service.impl.AccountServiceImpl; public class ProxyFactory { //方法返回一个代理对象 public static AccountService getAccountService(){ final AccountService as= new AccountServiceImpl(); AccountService proxy = (AccountService) Proxy.newProxyInstance(as.getClass().getClassLoader(), as.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = null; try { ManagerThreadLocal.startTransacation();//begin //执行的是真实对象的转账方法 invoke = method.invoke(as, args); ManagerThreadLocal.commit();//提交事务 } catch (Exception e) { try { ManagerThreadLocal.rollback();//回滚事务 } catch (Exception e1) { e1.printStackTrace(); } }finally{ try { ManagerThreadLocal.close(); } catch (Exception e) { e.printStackTrace(); }//关闭 } return invoke; } }); return proxy; } }
6.Test
package com.learning.test; import com.learning.service.AccountService; import com.learning.service.impl.AccountServiceImpl; import com.learning.util.ObjectFactory; public class TestTransfer { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { AccountService as = ProxyFactory.getAccountService(); as.transfer("aaa", "bbb", 100); } }
以上是关于转账示例:service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)的主要内容,如果未能解决你的问题,请参考以下文章
转账示例:service层面实现(本例采用QueryRunner来执行sql语句,数据源为C3P0)