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

来源:互联网 发布:hd4800玩守望怎么优化 编辑:程序博客网 时间:2024/05/21 11:01
动态代理: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. }  
 
0 0