java 使用動態代理 - ThreadLocal實現事務管理(轉)

轉載 動態代理:JDK動態代理只能對實現了接口的類進入代理,採用JDK動態代理必須實現InvocationHandler接口,採用Proxy 類建立相應的代理類. 下面使用Model2(MVC)使用代理事務查詢用戶基本信息,使用DB2數據庫:java

創建表:
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 :數據庫鏈接管理類,實現對數據庫鏈接和事務的管理.sql

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());
	}
}
相關文章
相關標籤/搜索