首页|资讯|互联网|电信|硬件|软件|情报|产经|博客|家庭|商用电脑|游戏|评测|学院|下载|网络通信|方案应用|搜索
移动计算|商用软件|外包|开源|中间件|企业|IT经理|发烧友|程序员|IT女性|学生|老板|笔记本|手机|台式机|数码|论坛
程序员

使用动态代理实现用AOP对数据库进行操作

2008-03-14 11:04 作者:reverocean 来源:赛迪网
[摘要] 要实现对数据库的操作,离不开数据源(DataSource)或者连接(Connection),但是通常来说对数据库的操作都应该放在DAO中,而DAO又不应该与应用服务器相关联,所以一般都使用连接(Connection)。
[关键字] 动态代理 AOP 数据库
  要实现对数据库的操作,离不开数据源(DataSource)或者连接(Connection),但是通常来说对数据库的操作都应该放在DAO中,而DAO又不应该与应用服务器相关联,所以一般都使用连接(Connection)。现在我们这里就有一个问题了,怎么在拦截器中获得连接。我想可以通过两种方式获得:

  在分别讨论这两种方法之前,我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个TransactionException继承至RuntimeException然后在拦截器里面抛出,再又应用框架处理这个异常。下面试这个类的代码:

  public class TransactionException extends RuntimeException {

  private Throwable superException;

  private String myMessage;

  public TransactionException(Throwable throwable){

  super(throwable);

  this.superException = throwable;

  }

  public TransactionException(Throwable throwable,String message){

  super(message,throwable);

  this.superException = throwable;

  this.myMessage = message;

  }

  /**

  * @return Returns the myMessage.

  */

  public String getMessage() {

  return myMessage;

  }

  /**

  * @return Returns the superException.

  */

  public Throwable getSuperException() {

  return superException;

  }

  /**

  * @param myMessage The myMessage to set.

  */

  public void setMyMessage(String message) {

  this.myMessage = message;

  }

  /**

  * @param superException The superException to set.

  */

  public void setSuperException(Throwable superException) {

  this.superException = superException;

  }

  }

  1) 通过方法的第一个参数传进去

  l DAO

  import java.sql.Connection;

  public class TestDao {

  public void insertA(Connection con,String a,String b,……){

  …………………………………………

  一系列操作

  …………………………………………

  }

  public String queryA(Connection con,…….){

  …………………………………………

  一系列操作

  …………………………………………

  }

  public void updateA(Connection con,…….){

  …………………………………………

  一系列操作

  …………………………………………

  }

  }

  l 拦截器

  import java.sql.Connection;

  import java.sql.SQLException;

  import java.util.ArrayList;

  import java.util.List;

  public class TransactionInterceptor implements Interceptor {

  public void before(InvokeJniInfo invInfo) {

  if(isNeedTransactions(invInfo)){

  Connection conn = (Connection) invInfo.getArgs()[0];

  try {

  conn.setAutoCommit(false);

  } catch (SQLException e) {

  throw new TransactionException(e);

  }

  }

  }

  public void after(InvokeJniInfo invInfo) {

  if(isNeedTransactions(invInfo)){

  Connection conn = (Connection) invInfo.getArgs()[0];

  try {

  conn.commit();

  } catch (SQLException e) {

  throw new TransactionException(e);

  }finally{

  if(conn != null){

  try {

  conn.close();

  } catch (SQLException e) {

  throw new TransactionException(e,"Close Connection is failure!");

  }

  }

  }

  }

  }

  public void exceptionThrow(InvokeJniInfo invInfo) {

  if(isNeedTransactions(invInfo)){

  Connection conn = (Connection) invInfo.getArgs()[0];

  try {

  conn.rollback();

  } catch (SQLException e) {

  throw new TransactionException(e);

  }finally{

  if(conn != null){

  try {

  conn.close();

  } catch (SQLException e) {

  throw new TransactionException(e,"Close Connection is failure!");

  }

  }

  }

  }

  }

  private List getNeedTransaction(){

  List needTransactions = new ArrayList();

  needTransactions.add("insert");

  needTransactions.add("update");

  return needTransactions;

  }

  private boolean isNeedTransactions(InvokeJniInfo invInfo){

  String needTransaction = "";

  List needTransactions = getNeedTransaction();

  for(int i = 0;i needTransaction = (String)needTransactions.get(i);

  if(invInfo.getMethod().getName().startsWith(needTransaction)){

  return true;

  }

  }

  return false;

  }

  }

  需要注意的是:getNeedTransaction就是需要进行事务处理的方法的开头,这个方法可以写成一个从配置文件里面去读,这里我就写死在里面了。只是对insert和update开头的方法进行事务控制。

  2) 将Connection对象放在ThreadLocal中

  l ConnectionUtil类:

  import java.sql.Connection;

  public final class ConnectionUtil {

  private static ThreadLocal connections = new ThreadLocal();

  public static Connection getConnection(){

  Connection conn = null;

  conn = (Connection) connections.get();

  if(conn == null){

  conn = getRealConnection();

  connections.set(conn);

  }

  return conn;

  }

  public static void realseConnection(Connection conn){

  connections.set(null);

  }

  private static Connection getRealConnection() {

  实现自己获取连接的代码

  return null;

  }

  }

  l DAO类

  public class TestDao {

  public void insertA(String a,String b){

  Connection conn = getConnection();

  …………………………………………

  一系列操作

  …………………………………………

  }

  public String queryA(Connection con,…….){

  Connection conn = getConnection();

  …………………………………………

  一系列操作

  …………………………………………

  }

  public void updateA(Connection con,…….){

  Connection conn = getConnection();

  ………………………………………
关键词: 动态代理, AOP, 数据库,
  • 我要留言
关于eNet | 广告服务 | 版权声明 | 加入eNet | 联系我们 | 建议/投诉 | 网站导航 | 加入收藏

网站合作、内容监督、商务咨询、投诉建议:010-65245588
合作建议:hezuo@mail.enet.com.cn
Copyright © 1998--2008 硅谷动力公司版权所有 京ICP证000044号

京ICP证000044号