java 使用动态代理 和ThreadLocal实现事务管理实例

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

invoke方法签名:invoke(Object Proxy,Method method,Object[] args)

 public static Object newProxyInstance(ClassLoader loader,Class[] interfaces, InvocationHandler h)
 throws IllegalArgumentException

ClassLoader loader
----指定被代理对象的类加载器
Class[] Interfaces
----指定被代理对象所实现的接口
InvocationHandler h ----指定需要调用的InvocationHandler对象

注意本文是用的mysql5.0之后版本,并且别忘了数据库驱动

创建表:

/*DDL 信息*/------------

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) DEFAULT NULL,
  `EMAIL` varchar(30) DEFAULT NULL,
  `CREATE_DATE` date DEFAULT NULL,
  PRIMARY KEY (`USER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

插入的字段

INSERT INTO t_user(user_id, user_name, PASSWORD) VALUES('110', '系统管理员', 'root');

创建事务管理类(单例模式

ConnectionManager

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

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionManager {
	private static ThreadLocal 
	threadConn=new ThreadLocal<>();

	private ConnectionManager() {
	}
	/**
	 * @return 获取数据库连接
	 * @author mine_song
	 */
	public static Connection getConnection() {
		Connection conn = threadConn.get();
		if (conn == null) {
			try {
				Class.forName("com.mysql.jdbc.Driver");
				conn = DriverManager.getConnection("jdbc:mysql:///erpdb","root","123");
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			threadConn.set(conn);
		}
		return conn;
	}

	/**
	 * 设置事务手动提交
	 * 
	 * @param conn
	 *            数据库连接
	 * @author mine_song
	 */
	public static void benigTransction(Connection conn) {
		try {
			if (conn != null) {
				if (conn.getAutoCommit()) {
					conn.setAutoCommit(false);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 提交事务
	 * 
	 * @param conn
	 *            数据库连接
	 * @author mine_song
	 */
	public static void endTransction(Connection conn) {
		try {
			if (conn != null) {
				if (!conn.getAutoCommit()) {
					conn.commit();
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 设置Connection的原始状态 即设置事务手动提交
	 * 
	 * @param conn
	 *            数据库连接
	 * @author mine_song
	 */
	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();
		}
	}

	/**
	 * 发生异常回滚事务
	 * 
	 * @param conn
	 *            数据库连接
	 * @author mine_song
	 */
	public static void rollback(Connection conn) {
		try {
			if (conn != null) {
				conn.rollback();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭连接,并将其从当前线程删除
	 * 
	 * @param conn
	 *            数据库连接
	 * @author mine_song
	 */
	public static void close() {
		Connection conn = threadConn.get();
		if (conn != null) {
			try {
				conn.close();
				conn = null;
				threadConn.remove();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

UserModel类(Bean)

import java.util.Date;

/**
 * 用户model类
 * 
 * @author mine_song
 *
 */
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;
	}
}

UserDao(数据访问层)

注意:模仿查询,使用事务,实际开发查询可以不需事务。

import java.sql.SQLException;

public interface IUserDao {
	public User selUser(String id) throws  SQLException;
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDaoImpl implements IUserDao {
	/**
	 * 根据ID查询用户
	 * 
	 * @param id
	 *            需要查询的用户ID
	 * @author mine_song
	 */
	public User selUser(String id) throws SQLException {
		ResultSet resultSet = null;
		String sql = "SELECT * FROM T_USER WHERE USER_ID = ?";
		Connection conn = ConnectionManager.getConnection();
		PreparedStatement pst = conn.prepareStatement(sql);
		User user = null;
		try {
			pst.setString(1, id);
			resultSet = pst.executeQuery();
			if (resultSet.next()) {
				user = getUser(resultSet);
			}
		} finally {
			if (resultSet != null) {
				resultSet.close();
			}
			if (pst != null) {
				pst.close();
			}
		}
		return user;
	}

	/**
	 * 获取用户信息
	 * 
	 * @param resultSet
	 *            结果集对象
	 * @author mine_song
	 */
	private User getUser(ResultSet resultSet) throws SQLException {
		User user = new User();
		user.setId(resultSet.getString("USER_ID"));
		user.setName(resultSet.getString("USER_NAME"));
		user.setPassword(resultSet.getString("PASSWORD"));
		user.setContact_tel(resultSet.getString("CONTACT_TEL"));
		user.setEmail(resultSet.getString("EMAIL"));
		user.setCreate_date(resultSet.getTimestamp("CREATE_DATE"));
		return user;
	}

}

manager层(service层)

public interface IUserManager {
	public User findUser(String id) throws Exception;
}

import java.sql.SQLException;

public class UserManagerImpl implements IUserManager {

	private IUserDao userDao = null;

	public UserManagerImpl() {
		userDao = new UserDaoImpl();
	}

	/**
	 * 根据ID查询用户
	 * 
	 * @param id
	 *            需要查询的用户ID
	 * @author mine_song
	 */
	public User findUser(String id) throws SQLException {
		return userDao.selUser(id);
	}

}

动态代理类(重点)

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

public class TransctionProxy implements InvocationHandler {
	private Object obj = null;

	/**
	 * 
	 * @param obj
	 *            obj需要代理的类
	 * @return 返回代理类对象
	 * @author mine_song
	 */
	public Object newProxyInstance(Object obj) {
		this.obj = obj;
		return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(), 
				this.obj.getClass().getInterfaces(), 
				this);
	}

	public Object invoke(Object proxy, 
			Method method, Object[] args) throws Throwable {
		// 用于接收参数
		Object param = null;
		System.out.println("Method.name : "+method.getName());
		// 如果是以下方法开头,则代理事务
		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;
	}
}

测试

注意:模仿查询,使用事务,实际开发查询可以不需事务。

public class Test {
	public static void main(String[] args) throws Exception {
		TransctionProxy transctionProxy = new TransctionProxy();
		// 产生代理对象
		IUserManager userManager = 
				(IUserManager) transctionProxy.
				newProxyInstance(new UserManagerImpl());
		
		
		User user = userManager.findUser("110");
		System.out.println("用户名  : " + user.getName());
		System.out.println("用户id: " + user.getId());
		System.out.println("创建日期:" + user.getCreate_date());
	}
}
Method.name : findUser
用户名  : 系统管理员
用户id: 110
创建日期:2017-04-18 00:00:00.0

本文参考:http://itindex.net/detail/44008-java-%E4%BB%A3%E7%90%86-threadlocal

你可能感兴趣的:(mysql)