使用动态代理实现用AOP对数据库进行操作
上一篇 / 下一篇 2008-03-20 15:52:00 / 个人分类:C+.NET
要实现对数据库的操作,离不开数据源(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();
…………………………………………
一系列操作
…………………………………………
}
private Connection getConnection(){
return ConnectionUtil.getConnection();
}
}
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 = getConnection();
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
throw new TransactionException(e);
}
}
}
public void after(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.commit();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
releaseConnection(conn);
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}
public void exceptionThrow(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.rollback();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
releaseConnection(conn);
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}
private Connection getConnection(){
return ConnectionUtil.getConnection();
}
private void releaseConnection(Connection conn){
ConnectionUtil.releaseConnection(conn);
}
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;
}
}
最后将这个拦截器添加到AOP拦截框架中去,InterceptorHandler类中的getIntercetors方法中添加一个:
private synchronized List getIntercetors(){
if(null == interceptors){
interceptors = new ArrayList();
……………………………………
interceptors.add(new TransactionInterceptor ());
……………………………………
}
return interceptors;
}
到此全部ok!
在分别讨论这两种方法之前,我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个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
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();
…………………………………………
一系列操作
…………………………………………
}
private Connection getConnection(){
return ConnectionUtil.getConnection();
}
}
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 = getConnection();
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
throw new TransactionException(e);
}
}
}
public void after(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.commit();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
releaseConnection(conn);
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}
public void exceptionThrow(InvokeJniInfo invInfo) {
if(isNeedTransactions(invInfo)){
Connection conn = getConnection();
try {
conn.rollback();
} catch (SQLException e) {
throw new TransactionException(e);
}finally{
if(conn != null){
try {
conn.close();
releaseConnection(conn);
} catch (SQLException e) {
throw new TransactionException(e,"Close Connection is failure!");
}
}
}
}
}
private Connection getConnection(){
return ConnectionUtil.getConnection();
}
private void releaseConnection(Connection conn){
ConnectionUtil.releaseConnection(conn);
}
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
if(invInfo.getMethod().getName().startsWith(needTransaction)){
return true;
}
}
return false;
}
}
最后将这个拦截器添加到AOP拦截框架中去,InterceptorHandler类中的getIntercetors方法中添加一个:
private synchronized List getIntercetors(){
if(null == interceptors){
interceptors = new ArrayList();
……………………………………
interceptors.add(new TransactionInterceptor ());
……………………………………
}
return interceptors;
}
到此全部ok!
标题搜索
日历
|
|||||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
| 1 | 2 | ||||||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 | |||
| 10 | 11 | 12 | 13 | 14 | 15 | 16 | |||
| 17 | 18 | 19 | 20 | 21 | 22 | 23 | |||
| 24 | 25 | 26 | 27 | 28 | 29 | 30 | |||
| 31 | |||||||||
我的存档
数据统计
- 访问量: 3489
- 日志数: 108
- 建立时间: 2007-04-03
- 更新时间: 2008-07-11
