|
<p >要实现对数据库的操作,离不开数据源(DataSource)或者连接(Connection),但是通常来说对数据库的操作都应该放在DAO中,而DAO又不应该与应用服务器相关联,所以一般都使用连接(Connection)。现在我们这里就有一个问题了,怎么在拦截器中获得连接。我想可以通过两种方式获得:<BR>在分别讨论这两种方法之前,我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个TransactionException继承至RuntimeException然后在拦截器里面抛出,再又应用框架处理这个异常。下面试这个类的代码:<BR>public class TransactionException extends RuntimeException {<BR> private Throwable superException;<BR> private String myMessage;<BR><BR> public TransactionException(Throwable throwable){<BR> super(throwable);<BR> this.superException = throwable;<BR> }<BR><BR> public TransactionException(Throwable throwable,String message){<BR> super(message,throwable);<BR> this.superException = throwable;<BR> this.myMessage = message;<BR> }<BR><BR> /**<BR> * @return Returns the myMessage.<BR> */<BR> public String getMessage() {<BR> return myMessage;<BR> }<BR><BR> /**<BR> * @return Returns the superException.<BR> */<BR> public Throwable getSuperException() {<BR> return superException;<BR> }<BR><BR> /**<BR> * @param myMessage The myMessage to set.<BR> */<BR> public void setMyMessage(String message) {<BR> this.myMessage = message;<BR> }<BR><BR> /**<BR> * @param superException The superException to set.<BR> */<BR> public void setSuperException(Throwable superException) {<BR> this.superException = superException;<BR> }<BR><BR><BR>}<BR>1) 通过方法的第一个参数传进去<BR>l DAO<BR>import java.sql.Connection;<BR><BR>public class TestDao {<BR> public void insertA(Connection con,String a,String b,……){<BR> …………………………………………<BR>一系列操作<BR>…………………………………………<BR> }<BR><BR> public String queryA(Connection con,…….){<BR> …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR><BR> public void updateA(Connection con,…….){<BR> …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR>}<BR><BR>l 拦截器<BR>import java.sql.Connection;<BR>import java.sql.SQLException;<BR>import java.util.ArrayList;<BR>import java.util.List;<BR><BR>public class TransactionInterceptor implements Interceptor {<BR><BR> public void before(InvokeJniInfo invInfo) {<BR> if(isNeedTransactions(invInfo)){<BR> Connection conn = (Connection) invInfo.getArgs()[0];<BR> try {<BR> conn.setAutoCommit(false);<BR> } catch (SQLException e) {<BR> throw new TransactionException(e);<BR> }<BR> }<BR> }<BR><BR> public void after(InvokeJniInfo invInfo) {<BR> if(isNeedTransactions(invInfo)){<BR> Connection conn = (Connection) invInfo.getArgs()[0];<BR> try {<BR> conn.commit();<BR> } catch (SQLException e) {<BR> throw new TransactionException(e);<BR> }finally{<BR> if(conn != null){<BR> try {<BR> conn.close();<BR> } catch (SQLException e) {<BR> throw new TransactionException(e,"Close Connection is failure!");<BR> }<BR> }<BR> }<BR> }<BR> }<BR><BR> public void exceptionThrow(InvokeJniInfo invInfo) {<BR> if(isNeedTransactions(invInfo)){<BR> Connection conn = (Connection) invInfo.getArgs()[0];<BR> try {<BR> conn.rollback();<BR> } catch (SQLException e) {<BR> throw new TransactionException(e);<BR> }finally{<BR> if(conn != null){<BR> try {<BR> conn.close();<BR> } catch (SQLException e) {<BR> throw new TransactionException(e,"Close Connection is failure!");<BR> }<BR> }<BR> }<BR> }<BR> }<BR><BR> private List getNeedTransaction(){<BR> List needTransactions = new ArrayList();<BR> needTransactions.add("insert");<BR> needTransactions.add("update");<BR> return needTransactions;<BR> }<BR><BR> private boolean isNeedTransactions(InvokeJniInfo invInfo){<BR> String needTransaction = "";<BR> List needTransactions = getNeedTransaction();<BR> for(int i = 0;i<needTransactions.size();i++){<BR> needTransaction = (String)needTransactions.get(i);<BR> if(invInfo.getMethod().getName().startsWith(needTransaction)){<BR> return true;<BR> }<BR> }<BR> return false;<BR> }<BR>}<BR><BR>需要注意的是:getNeedTransaction就是需要进行事务处理的方法的开头,这个方法可以写成一个从配置文件里面去读,这里我就写死在里面了。只是对insert和update开头的方法进行事务控制。<BR>2) 将Connection对象放在ThreadLocal中<BR>l ConnectionUtil类:<BR>import java.sql.Connection;<BR><BR>public final class ConnectionUtil {<BR> private static ThreadLocal connections = new ThreadLocal();<BR> public static Connection getConnection(){<BR> Connection conn = null;<BR> conn = (Connection) connections.get();<BR> if(conn == null){<BR> conn = getRealConnection();<BR> connections.set(conn);<BR> }<BR> return conn;<BR> }<BR> public static void realseConnection(Connection conn){<BR> connections.set(null);<BR> }<BR> private static Connection getRealConnection() {<BR> 实现自己获取连接的代码<BR> return null;<BR> }<BR>}<BR>l DAO类<BR>public class TestDao {<BR> public void insertA(String a,String b){<BR> Connection conn = getConnection();<BR> …………………………………………<BR>一系列操作<BR>…………………………………………<BR> }<BR> public String queryA(Connection con,…….){<BR> Connection conn = getConnection();<BR> …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR><BR> public void updateA(Connection con,…….){<BR>Connection conn = getConnection();<BR> …………………………………………<BR>一系列操作<BR>…………………………………………<BR>}<BR><BR> private Connection getConnection(){<BR> return ConnectionUtil.getConnection();<BR> }<BR><BR>}<BR>l 拦截器<BR>import java.sql.Connection;<BR>import java.sql.SQLException;<BR>import java.util.ArrayList;<BR>import java.util.List;<BR><BR>public class TransactionInterceptor implements Interceptor {<BR><BR> public void before(InvokeJniInfo invInfo) {<BR> if(isNeedTransactions(invInfo)){<BR> Connection conn = getConnection();<BR> try {<BR> conn.setAutoCommit(false);<BR> } catch (SQLException e) {<BR> throw new TransactionException(e);<BR> }<BR> }<BR> }<BR><BR> public void after(InvokeJniInfo invInfo) {<BR> if(isNeedTransactions(invInfo)){<BR> Connection conn = getConnection();<BR> try {<BR> conn.commit();<BR> } catch (SQLException e) {<BR> throw new TransactionException(e);<BR> }finally{<BR> if(conn != null){<BR> try {<BR> conn.close();<BR> releaseConnection(conn);<BR> } catch (SQLException e) {<BR> throw new TransactionException(e,"Close Connection is failure!");<BR> }<BR> }<BR> }<BR> }<BR> }<BR><BR> public void exceptionThrow(InvokeJniInfo invInfo) {<BR> if(isNeedTransactions(invInfo)){<BR> Connection conn = getConnection();<BR> try {<BR> conn.rollback();<BR> } catch (SQLException e) {<BR> throw new TransactionException(e);<BR> }finally{<BR> if(conn != null){<BR> try {<BR> conn.close();<BR> releaseConnection(conn);<BR> } catch (SQLException e) {<BR> throw new TransactionException(e,"Close Connection is failure!");<BR> }<BR> }<BR> }<BR> }<BR> }<BR><BR> private Connection getConnection(){<BR> return ConnectionUtil.getConnection();<BR> }<BR><BR> private void releaseConnection(Connection conn){<BR> ConnectionUtil.releaseConnection(conn);<BR> }<BR> private List getNeedTransaction(){<BR> List needTransactions = new ArrayList();<BR> needTransactions.add("insert");<BR> needTransactions.add("update");<BR> return needTransactions;<BR> }<BR><BR> private boolean isNeedTransactions(InvokeJniInfo invInfo){<BR> String needTransaction = "";<BR> List needTransactions = getNeedTransaction();<BR> for(int i = 0;i<needTransactions.size();i++){<BR> needTransaction = (String)needTransactions.get(i);<BR> if(invInfo.getMethod().getName().startsWith(needTransaction)){<BR> return true;<BR> }<BR> }<BR> return false;<BR> }<BR>}<BR> 最后将这个拦截器添加到AOP拦截框架中去,InterceptorHandler类中的getIntercetors方法中添加一个:<BR><BR> private synchronized List getIntercetors(){<BR> if(null == interceptors){<BR> interceptors = new ArrayList();<BR> ……………………………………<BR>interceptors.add(new TransactionInterceptor ());<BR> ……………………………………<BR> }<BR> return interceptors;<BR>}<BR><BR>到此全部ok!<BR><FONT face="Times New Roman"> </FONT><p align="center"></p></p> |
|