动态代理:JDK动态代理只能对实现了接口的类进入代理,采用JDK动态代理必须实现InvocationHandler接口,采用Proxy 类创建相应的代理类.
下面使用Model2(MVC)使用代理事务查询用户基本信息,使用DB2数据库:
- 建立表:
- create table T_USER
- (
- USER_ID VARCHAR(10) not null,
- USER_NAME VARCHAR(30) not null,
- PASSWORD VARCHAR(20) not null,
- CONTACT_TEL VARCHAR(30),
- EMAIL VARCHAR(30),
- CREATE_DATE DATE,
- constraint P_KEY_1 primary key (USER_ID)
- );
- 初始化数据:
- insert into t_user(user_id, user_name, password) values('root', '系统管理员', 'root');
ConnectionManager :数据库连接管理类,实现对数据库连接和事务的管理.
- package gd.hz.util;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- public class ConnectionManager {
- private ConnectionManager() {
- }
- private static ThreadLocal<Connection> threadConn = new ThreadLocal<Connection>();
- // 获取数据库连接
- public static Connection getConnection() {
- Connection conn = threadConn.get();
- if (conn == null) {
- try {
- Class.forName("com.ibm.db2.jcc.DB2Driver");
- conn = DriverManager.getConnection(
- "jdbc:db2://127.0.0.1:50000/DRP", "db2admin", "619100");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- threadConn.set(conn);
- }
- return conn;
- }
- // 设置事务手动提交
- public static void benigTransction(Connection conn) {
- try {
- if (conn != null) {
- if (conn.getAutoCommit()) {
- conn.setAutoCommit(false);
- }
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- // 提交事务
- public static void endTransction(Connection conn) {
- try {
- if (conn != null) {
- if (!conn.getAutoCommit()) {
- conn.commit();
- }
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- // 设置Connection的原始状态
- public static void recoverTransction(Connection conn) {
- try {
- if (conn != null) {
- if (conn.getAutoCommit()) {
- conn.setAutoCommit(false);
- } else {
- conn.setAutoCommit(true);
- }
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- // 发生异常回滚事务
- public static void rollback(Connection conn) {
- try {
- if (conn != null) {
- conn.rollback();
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- // 关闭连接,并将其从当前线程删除
- public static void close() {
- Connection conn = threadConn.get();
- if (conn != null) {
- try {
- conn.close();
- conn = null;
- threadConn.remove();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
Model:
- package gd.hz.model;
- import java.util.Date;
- //用户实体类
- public class User {
- // 用户ID
- private String id;
- // 用户名称
- private String name;
- // 登陆密码
- private String password;
- // 联系电话
- private String contact_tel;
- // 电子邮件
- private String email;
- // 用户创建日期
- private Date create_date;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public String getContact_tel() {
- return contact_tel == null ? "" : contact_tel;
- }
- public void setContact_tel(String contact_tel) {
- this.contact_tel = contact_tel;
- }
- public String getEmail() {
- return email == null ? "" : email;
- }
- public void setEmail(String email) {
- this.email = email;
- }
- public Date getCreate_date() {
- return create_date;
- }
- public void setCreate_date(Date create_date) {
- this.create_date = create_date;
- }
- }
DAO接口:
- package gd.hz.dao;
- import gd.hz.model.User;
- import java.sql.SQLException;
- public interface UserDAO {
- public User selUser(String id) throws SQLException;
- }
DAO实现类:
- package gd.hz.dao;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import gd.hz.model.User;
- import gd.hz.util.ConnectionManager;
- public class UserDAOImpl implements UserDAO {
- // 根据ID查询用户
- public User selUser(String id) throws SQLException {
- ResultSet resu = null;
- String sql = "SELECT * FROM DB2ADMIN.T_USER WHERE USER_ID = ?";
- Connection conn = ConnectionManager.getConnection();
- PreparedStatement pstat = conn.prepareStatement(sql);
- User user = null;
- try {
- pstat.setString(1, id);
- resu = pstat.executeQuery();
- if (resu.next()) {
- user = getUser(resu);
- }
- } finally {
- if (resu != null) {
- resu.close();
- }
- if (pstat != null) {
- pstat.close();
- }
- }
- return user;
- }
- // 获取用户
- private User getUser(ResultSet resu) throws SQLException {
- User user = new User();
- user.setId(resu.getString("USER_ID"));
- user.setName(resu.getString("USER_NAME"));
- user.setPassword(resu.getString("PASSWORD"));
- user.setContact_tel(resu.getString("CONTACT_TEL"));
- user.setEmail(resu.getString("EMAIL"));
- user.setCreate_date(resu.getTimestamp("CREATE_DATE"));
- return user;
- }
- }
Manager接口:
- package gd.hz.manager;
- import gd.hz.model.User;
- public interface UserManager {
- public User findUser(String id) throws Exception;
- }
Manager实现类:
- package gd.hz.manager;
- import java.sql.SQLException;
- import gd.hz.dao.UserDAO;
- import gd.hz.dao.UserDAOImpl;
- import gd.hz.model.User;
- public class UserManagerImpl implements UserManager {
- private UserDAO userDAO = null;
- public UserManagerImpl() {
- userDAO = new UserDAOImpl();
- }
- public User findUser(String id) throws SQLException {
- return userDAO.selUser(id);
- }
- }
创建代理类:
- package gd.hz.util;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.sql.Connection;
- //Manager代理类
- public class TransctionProxy implements InvocationHandler {
- private Object obj = null;
- // obj:需要代理的类
- public Object newProxyInstance(Object obj) {
- this.obj = obj;
- return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(),
- this.obj.getClass().getInterfaces(), this);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // 用于接收参数
- Object param = null;
- // 如果是以下方法开头,则代理事务
- if (method.getName().startsWith("add")
- || method.getName().startsWith("modify")
- || method.getName().startsWith("find")
- || method.getName().startsWith("del")) {
- Connection conn = ConnectionManager.getConnection();
- try {
- // 手动提交事务
- ConnectionManager.benigTransction(conn);
- param = method.invoke(obj, args);
- // 提交事务
- ConnectionManager.endTransction(conn);
- } catch (Exception e) {
- // 回滚事务
- ConnectionManager.rollback(conn);
- if (e instanceof InvocationTargetException) {
- InvocationTargetException inv = (InvocationTargetException) e;
- throw inv.getTargetException();
- } else {
- throw new Exception("操作失败!");
- }
- } finally {
- // 还原状态
- ConnectionManager.recoverTransction(conn);
- ConnectionManager.close();
- }
- }
- return param;
- }
- }
测试:
- package gd.hz.util;
- import gd.hz.manager.UserManager;
- import gd.hz.manager.UserManagerImpl;
- import gd.hz.model.User;
- public class Test {
- public static void main(String[] args) throws Exception {
- TransctionProxy transctionProxy = new TransctionProxy();
- // //产生代理对象
- UserManager userManager = (UserManager) transctionProxy
- .newProxyInstance(new UserManagerImpl());
- User user = userManager.findUser("root");
- System.out.println("用户名:" + user.getName());
- }
- }