设计模式之 动态代理 - ThreadLocal实现事务管理

动态代理:JDK动态代理只能对实现了接口的类进入代理,采用JDK动态代理必须实现InvocationHandler接口,采用Proxy 类创建相应的代理类.

下面使用Model2(MVC)使用代理事务查询用户基本信息,使用DB2数据库:

Sql代码  

  1. 建立表:  

  2. create table T_USER  

  3. (  

  4.    USER_ID              VARCHAR(10)            not null,  

  5.    USER_NAME            VARCHAR(30)            not null,  

  6.    PASSWORD             VARCHAR(20)            not null,  

  7.    CONTACT_TEL          VARCHAR(30),  

  8.    EMAIL                VARCHAR(30),  

  9.    CREATE_DATE          DATE,  

  10.    constraint P_KEY_1 primary key (USER_ID)  

  11. );  

  12.   

  13. 初始化数据:  

  14. insert into t_user(user_id, user_name, passwordvalues('root''系统管理员''root');  

 

ConnectionManager :数据库连接管理类,实现对数据库连接和事务的管理.

Java代码  收藏代码

  1. package gd.hz.util;  

  2.   

  3. import java.sql.Connection;  

  4. import java.sql.DriverManager;  

  5. import java.sql.SQLException;  

  6.   

  7. public class ConnectionManager {  

  8.     private ConnectionManager() {  

  9.     }  

  10.   

  11.     private static ThreadLocal<Connection> threadConn = new ThreadLocal<Connection>();  

  12.   

  13.     // 获取数据库连接  

  14.     public static Connection getConnection() {  

  15.         Connection conn = threadConn.get();  

  16.         if (conn == null) {  

  17.             try {  

  18.                 Class.forName("com.ibm.db2.jcc.DB2Driver");  

  19.                 conn = DriverManager.getConnection(  

  20.                         "jdbc:db2://127.0.0.1:50000/DRP""db2admin""619100");  

  21.             } catch (ClassNotFoundException e) {  

  22.                 e.printStackTrace();  

  23.             } catch (SQLException e) {  

  24.                 e.printStackTrace();  

  25.             }  

  26.             threadConn.set(conn);  

  27.         }  

  28.         return conn;  

  29.     }  

  30.   

  31.     // 设置事务手动提交  

  32.     public static void benigTransction(Connection conn) {  

  33.         try {  

  34.             if (conn != null) {  

  35.                 if (conn.getAutoCommit()) {  

  36.                     conn.setAutoCommit(false);  

  37.                 }  

  38.             }  

  39.         } catch (SQLException e) {  

  40.             e.printStackTrace();  

  41.         }  

  42.     }  

  43.   

  44.     // 提交事务  

  45.     public static void endTransction(Connection conn) {  

  46.         try {  

  47.             if (conn != null) {  

  48.                 if (!conn.getAutoCommit()) {  

  49.                     conn.commit();  

  50.                 }  

  51.             }  

  52.         } catch (SQLException e) {  

  53.             e.printStackTrace();  

  54.         }  

  55.     }  

  56.   

  57.     // 设置Connection的原始状态  

  58.     public static void recoverTransction(Connection conn) {  

  59.         try {  

  60.             if (conn != null) {  

  61.                 if (conn.getAutoCommit()) {  

  62.                     conn.setAutoCommit(false);  

  63.                 } else {  

  64.                     conn.setAutoCommit(true);  

  65.                 }  

  66.             }  

  67.         } catch (SQLException e) {  

  68.             e.printStackTrace();  

  69.         }  

  70.     }  

  71.   

  72.     // 发生异常回滚事务  

  73.     public static void rollback(Connection conn) {  

  74.         try {  

  75.             if (conn != null) {  

  76.                 conn.rollback();  

  77.             }  

  78.         } catch (SQLException e) {  

  79.             e.printStackTrace();  

  80.         }  

  81.     }  

  82.   

  83.     // 关闭连接,并将其从当前线程删除  

  84.     public static void close() {  

  85.         Connection conn = threadConn.get();  

  86.         if (conn != null) {  

  87.             try {  

  88.                 conn.close();  

  89.                 conn = null;  

  90.                 threadConn.remove();  

  91.             } catch (SQLException e) {  

  92.                 e.printStackTrace();  

  93.             }  

  94.         }  

  95.     }  

  96. }  

 

 

Model:

Java代码  收藏代码

  1. package gd.hz.model;  

  2.   

  3. import java.util.Date;  

  4.   

  5. //用户实体类  

  6. public class User {  

  7.     // 用户ID  

  8.     private String id;  

  9.     // 用户名称  

  10.     private String name;  

  11.     // 登陆密码  

  12.     private String password;  

  13.     // 联系电话  

  14.     private String contact_tel;  

  15.     // 电子邮件  

  16.     private String email;  

  17.     // 用户创建日期  

  18.     private Date create_date;  

  19.   

  20.     public String getId() {  

  21.         return id;  

  22.     }  

  23.   

  24.     public void setId(String id) {  

  25.         this.id = id;  

  26.     }  

  27.   

  28.     public String getName() {  

  29.         return name;  

  30.     }  

  31.   

  32.     public void setName(String name) {  

  33.         this.name = name;  

  34.     }  

  35.   

  36.     public String getPassword() {  

  37.         return password;  

  38.     }  

  39.   

  40.     public void setPassword(String password) {  

  41.         this.password = password;  

  42.     }  

  43.   

  44.     public String getContact_tel() {  

  45.         return contact_tel == null ? "" : contact_tel;  

  46.     }  

  47.   

  48.     public void setContact_tel(String contact_tel) {  

  49.         this.contact_tel = contact_tel;  

  50.     }  

  51.   

  52.     public String getEmail() {  

  53.         return email == null ? "" : email;  

  54.     }  

  55.   

  56.     public void setEmail(String email) {  

  57.         this.email = email;  

  58.     }  

  59.   

  60.     public Date getCreate_date() {  

  61.         return create_date;  

  62.     }  

  63.   

  64.     public void setCreate_date(Date create_date) {  

  65.         this.create_date = create_date;  

  66.     }  

  67. }  

 

DAO接口:

Java代码  收藏代码

  1. package gd.hz.dao;  

  2.   

  3. import gd.hz.model.User;  

  4.   

  5. import java.sql.SQLException;  

  6.   

  7. public interface UserDAO {  

  8.     public User selUser(String id) throws SQLException;  

  9. }  

 

DAO实现类:

Java代码  收藏代码

  1. package gd.hz.dao;  

  2.   

  3. import java.sql.Connection;  

  4. import java.sql.PreparedStatement;  

  5. import java.sql.ResultSet;  

  6. import java.sql.SQLException;  

  7.   

  8. import gd.hz.model.User;  

  9. import gd.hz.util.ConnectionManager;  

  10.   

  11. public class UserDAOImpl implements UserDAO {  

  12.     // 根据ID查询用户  

  13.     public User selUser(String id) throws SQLException {  

  14.         ResultSet resu = null;  

  15.         String sql = "SELECT * FROM DB2ADMIN.T_USER WHERE USER_ID = ?";  

  16.         Connection conn = ConnectionManager.getConnection();  

  17.         PreparedStatement pstat = conn.prepareStatement(sql);  

  18.         User user = null;  

  19.         try {  

  20.             pstat.setString(1, id);  

  21.             resu = pstat.executeQuery();  

  22.             if (resu.next()) {  

  23.                 user = getUser(resu);  

  24.             }  

  25.         } finally {  

  26.             if (resu != null) {  

  27.                 resu.close();  

  28.             }  

  29.             if (pstat != null) {  

  30.                 pstat.close();  

  31.             }  

  32.         }  

  33.         return user;  

  34.     }  

  35.   

  36.     // 获取用户  

  37.     private User getUser(ResultSet resu) throws SQLException {  

  38.         User user = new User();  

  39.         user.setId(resu.getString("USER_ID"));  

  40.         user.setName(resu.getString("USER_NAME"));  

  41.         user.setPassword(resu.getString("PASSWORD"));  

  42.         user.setContact_tel(resu.getString("CONTACT_TEL"));  

  43.         user.setEmail(resu.getString("EMAIL"));  

  44.         user.setCreate_date(resu.getTimestamp("CREATE_DATE"));  

  45.         return user;  

  46.     }  

  47. }  

 

Manager接口:

Java代码  收藏代码

  1. package gd.hz.manager;  

  2.   

  3. import gd.hz.model.User;  

  4.   

  5. public interface UserManager {  

  6.     public User findUser(String id) throws Exception;  

  7. }  

 

Manager实现类:

Java代码  收藏代码

  1. package gd.hz.manager;  

  2.   

  3. import java.sql.SQLException;  

  4.   

  5. import gd.hz.dao.UserDAO;  

  6. import gd.hz.dao.UserDAOImpl;  

  7. import gd.hz.model.User;  

  8.   

  9. public class UserManagerImpl implements UserManager {  

  10.     private UserDAO userDAO = null;  

  11.   

  12.     public UserManagerImpl() {  

  13.         userDAO = new UserDAOImpl();  

  14.     }  

  15.   

  16.     public User findUser(String id) throws SQLException {  

  17.         return userDAO.selUser(id);  

  18.     }  

  19. }  

 

创建代理类:

Java代码  收藏代码

  1. package gd.hz.util;  

  2.   

  3. import java.lang.reflect.InvocationHandler;  

  4. import java.lang.reflect.InvocationTargetException;  

  5. import java.lang.reflect.Method;  

  6. import java.lang.reflect.Proxy;  

  7. import java.sql.Connection;  

  8.   

  9. //Manager代理类  

  10. public class TransctionProxy implements InvocationHandler {  

  11.     private Object obj = null;  

  12.   

  13.     // obj:需要代理的类  

  14.     public Object newProxyInstance(Object obj) {  

  15.         this.obj = obj;  

  16.         return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(),  

  17.                 this.obj.getClass().getInterfaces(), this);  

  18.     }  

  19.   

  20.     @Override  

  21.     public Object invoke(Object proxy, Method method, Object[] args)  

  22.             throws Throwable {  

  23.         // 用于接收参数  

  24.         Object param = null;  

  25.         // 如果是以下方法开头,则代理事务  

  26.         if (method.getName().startsWith("add")  

  27.                 || method.getName().startsWith("modify")  

  28.                 || method.getName().startsWith("find")  

  29.                 || method.getName().startsWith("del")) {  

  30.             Connection conn = ConnectionManager.getConnection();  

  31.             try {  

  32.                 // 手动提交事务  

  33.                 ConnectionManager.benigTransction(conn);  

  34.                 param = method.invoke(obj, args);  

  35.                 // 提交事务  

  36.                 ConnectionManager.endTransction(conn);  

  37.             } catch (Exception e) {  

  38.                 // 回滚事务  

  39.                 ConnectionManager.rollback(conn);  

  40.                 if (e instanceof InvocationTargetException) {  

  41.                     InvocationTargetException inv = (InvocationTargetException) e;  

  42.                     throw inv.getTargetException();  

  43.                 } else {  

  44.                     throw new Exception("操作失败!");  

  45.                 }  

  46.             } finally {  

  47.                 // 还原状态  

  48.                 ConnectionManager.recoverTransction(conn);  

  49.                 ConnectionManager.close();  

  50.             }  

  51.         }  

  52.         return param;  

  53.     }  

  54. }  

 

测试:

Java代码  收藏代码

  1. package gd.hz.util;  

  2.   

  3. import gd.hz.manager.UserManager;  

  4. import gd.hz.manager.UserManagerImpl;  

  5. import gd.hz.model.User;  

  6.   

  7. public class Test {  

  8.     public static void main(String[] args) throws Exception {  

  9.         TransctionProxy transctionProxy = new TransctionProxy();  

  10.   

  11.         // //产生代理对象  

  12.         UserManager userManager = (UserManager) transctionProxy  

  13.                 .newProxyInstance(new UserManagerImpl());  

  14.         User user = userManager.findUser("root");  

  15.         System.out.println("用户名:" + user.getName());  

  16.     }  

  17. }  

 


你可能感兴趣的:(设计模式之 动态代理 - ThreadLocal实现事务管理)