⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultpersistencemanager.java

📁 软件设计课做的一个类似Hibernate的O/R Mapping的框架
💻 JAVA
字号:
package cn.edu.nju.software.sd.torm.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.edu.nju.software.sd.torm.PersistenceException;
import cn.edu.nju.software.sd.torm.PersistenceManager;
import cn.edu.nju.software.sd.torm.cfg.PersistenceClass;
import cn.edu.nju.software.sd.torm.cfg.PersistenceProperty;
import cn.edu.nju.software.sd.torm.exception.FieldAccessException;
import cn.edu.nju.software.sd.torm.exception.UnRegisteredClassException;
import cn.edu.nju.software.sd.torm.util.IDGeneratorFactory;

/**
 * The DefaultPersistenceManager class is the default implementation
 * of the <tt>PersistenceManager<tt>. Which supports ID auto-generation,
 * object buffering. And it's thread safe. That means, it is safe in the
 * cross-thread situation. For example. Two threads loaded the same record
 * and one of the threads modified the properties of the object. The other
 * thread will immediately receive the modification of the object. In the
 * purpose of interact with different databases correctly, it has three
 * template methods to deal with the database-specified actions. There are
 * two subclasses which have override these methods: SQLServerPersistenceManager
 * and MySQLPersistenceManager.
 * 
 * @author YinfeiXU
 * @version 1.0.0
 *
 */
public class DefaultPersistenceManager extends PersistenceManager {

	BufferPool pool;

	Map<Class, PersistenceObjectMethodInterceptor> interceptors;

	

	public DefaultPersistenceManager() {
		pool = new BufferPool(configuration.getClassMap().keySet());
		interceptors = new HashMap<Class, PersistenceObjectMethodInterceptor>();
	}

	/* (non-Javadoc)
	 * @see cn.edu.nju.software.sd.torm.PersistenceManager#delete(java.lang.Object)
	 */
	@Override
	public void delete(Object obj) throws PersistenceException {

		if (obj == null)
			throw new NullPointerException();
		// For CGLIB...
		Class realClass = obj.getClass();
		// End for CGLIB
		PersistenceClass cl = (PersistenceClass) configuration.getClassMap()
				.get(realClass);
		if (cl == null) {
			cl = (PersistenceClass) configuration.getClassMap().get(
					(realClass = realClass.getSuperclass()));
		}
		if (cl == null)
			throw new UnRegisteredClassException("The class "
					+ realClass.getName()
					+ " hasn't been registered as a persistentable class");
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = getConnection();
			con.setAutoCommit(false);

			PersistenceProperty idPro = cl.getID();

			String s = "delete from " + cl.getTableName() + " where "
					+ idPro.getColumnName() + "=?;";
			stmt = con.prepareStatement(s);

			// Set the ID parameter
			int id = ((Integer) this.getPropertyValue(realClass, obj, idPro))
					.intValue();

			stmt.setObject(1, id, java.sql.Types.INTEGER);
			stmt.execute();
			con.commit();
			synchronized (this) {
				if (pool.exists(obj, id)) {
					Object o = pool.delete(obj, id);
					interceptors.get(realClass).addDeletedObject(o);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			try {
				con.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		} finally {
			try {
				stmt.close();
				con.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}
	}

	/* (non-Javadoc)
	 * @see cn.edu.nju.software.sd.torm.PersistenceManager#insert(java.lang.Object)
	 */
	@Override
	public void insert(Object obj) throws PersistenceException {

		if (obj == null)
			throw new NullPointerException();
		// For CGLIB...
		Class realClass = obj.getClass();
		// End for CGLIB
		PersistenceClass cl = (PersistenceClass) configuration.getClassMap()
				.get(realClass);
		if (cl == null) {
			cl = (PersistenceClass) configuration.getClassMap().get(
					(realClass = realClass.getSuperclass()));
		}
		if (cl == null)
			throw new UnRegisteredClassException("The class "
					+ realClass.getName()
					+ " hasn't been registered as a persistentable class");
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = getConnection();
			con.setAutoCommit(false);

			List<PersistenceProperty> pList = cl.getProperties();
			String columns = "(", values = "(?";
			PersistenceProperty idPro = cl.getID();
			columns += idPro.getColumnName();
			Iterator<PersistenceProperty> itr = pList.iterator();
			while (itr.hasNext()) {
				columns += ("," + itr.next().getColumnName());
				values += ",?";
			}
			columns += ")";
			values += ")";
			String s = "insert into " + cl.getTableName() + columns + "values"
					+ values + ";";
			stmt = con.prepareStatement(s);

			// Set the ID parameter
			int id = IDGeneratorFactory.createIDGenerator(cl.getGeneratorName()).nextID(con,
					cl.getTableName(), idPro.getColumnName());
			this.setPropertyValue(realClass, obj, idPro, id);
			stmt.setObject(1, id, idPro.getPropertyType());
			int index = 2;
			itr = pList.iterator();
			while (itr.hasNext()) {
				PersistenceProperty p = itr.next();
				Object val = getPropertyValue(realClass, obj, p);
				if(val == null){
					try{
						String name = p.getPropertyName();
						val = realClass.getDeclaredField(name).getType().getConstructor(new Class[]{}).newInstance(new Object[]{});
					}catch(Exception e){
						e.printStackTrace();
					}
				}
				stmt.setObject(index++,val, p.getPropertyType() );
			}
			stmt.execute();
			con.commit();

			// synchronized(this){
			// pool.add(obj, id);
			// }
		} catch (Exception e) {
			e.printStackTrace();
			try {
				con.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		} finally {
			try {
				stmt.close();
				con.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}

	}

	/* (non-Javadoc)
	 * @see cn.edu.nju.software.sd.torm.PersistenceManager#load(java.lang.Class, int)
	 */
	@Override
	public Object load(Class clazz, int id) throws PersistenceException {

		// For CGLIB...
		Class realClass = clazz;
		// End for CGLIB
		PersistenceClass cl = (PersistenceClass) configuration.getClassMap()
				.get(realClass);
		if (cl == null){
			cl = (PersistenceClass) configuration.getClassMap()
			.get((realClass = realClass.getSuperclass()));
		}
		if (cl== null)
			throw new UnRegisteredClassException("The class "
					+ realClass.getName()
					+ " hasn't been registered as a persistentable class");
		
		synchronized(this){
			if(pool.exists(realClass, id)){
				return pool.get(realClass, id);
			}
		}
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		Object o = null;

		try {
			con = getConnection();
			con.setAutoCommit(false);

			List<PersistenceProperty> pList = cl.getProperties();
			String columns = "";
			PersistenceProperty idPro = cl.getID();
			columns += idPro.getColumnName();
			Iterator<PersistenceProperty> itr = pList.iterator();
			while (itr.hasNext()) {
				columns += ("," + itr.next().getColumnName());
			}
			String s = "select " + columns + " from " + cl.getTableName()
					+ " where " + idPro.getPropertyName() + "=?;";

			stmt = con.prepareStatement(s);
			stmt.setObject(1, id, java.sql.Types.INTEGER);

			rs = stmt.executeQuery();
			o = newInstance(realClass,this.getPropertyGetter(realClass, idPro));
			System.out.println(net.sf.cglib.proxy.Proxy.isProxyClass(o.getClass()));
			if (rs.next() && o != null) {
				this.setPropertyValue(realClass,o, idPro, id);
				itr = pList.iterator();
				while (itr.hasNext()) {
					PersistenceProperty p = itr.next();
					Object val = rs.getObject(p.getColumnName());
					this
							.setPropertyValue(realClass,o, p,val );
				}
			}
			con.commit();
			synchronized(this){
				pool.add(o, id);
			}
		} catch (Exception e) {
			e.printStackTrace();
			try {
				con.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		} finally {
			try {
				stmt.close();
				con.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}
		return o;
	}

	/* (non-Javadoc)
	 * @see cn.edu.nju.software.sd.torm.PersistenceManager#update(java.lang.Object)
	 */
	@Override
	public void update(Object obj) throws PersistenceException {

		if (obj == null)
			throw new NullPointerException();
		// For CGLIB...
		Class realClass = obj.getClass();
		// End for CGLIB
		PersistenceClass cl = (PersistenceClass) configuration.getClassMap()
				.get(realClass);
		if (cl == null) {
			cl = (PersistenceClass) configuration.getClassMap().get(
					(realClass = realClass.getSuperclass()));
		}
		if (cl == null)
			throw new UnRegisteredClassException("The class "
					+ realClass.getName()
					+ " hasn't been registered as a persistentable class");
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = getConnection();
			con.setAutoCommit(false);

			List<PersistenceProperty> pList = cl.getProperties();
			PersistenceProperty idPro = cl.getID();
			Iterator<PersistenceProperty> itr = pList.iterator();
			String s = "update " + cl.getTableName() + " set ";
			while (itr.hasNext()) {
				PersistenceProperty p = itr.next();
				s += (p.getColumnName() + "=?,");
			}
			s = s.substring(0, s.length() - 1);
			s += (" where " + idPro.getColumnName() + "=?;");

			stmt = con.prepareStatement(s);

			int index = 1;
			itr = pList.iterator();
			while (itr.hasNext()) {
				PersistenceProperty p = itr.next();
				stmt.setObject(index++, this
						.getPropertyValue(realClass, obj, p));
			}
			int id = ((Integer) this.getPropertyValue(realClass, obj, idPro))
					.intValue();
			stmt.setObject(index, id);

			stmt.execute();
			con.commit();
			// synchronized(this){
			// pool.add(obj, id);
			// }
		} catch (Exception e) {
			e.printStackTrace();
			try {
				con.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		} finally {
			try {
				stmt.close();
				con.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}
	}

	/**
	 * Get the property value of the obj, the property information
	 * is specified by the PesistenceProperty p. 
	 * 
	 * @param c
	 * @param obj
	 * @param p
	 * @return
	 */
	protected Object getPropertyValue(Class c, Object obj, PersistenceProperty p) {
		String name = p.getPropertyName();
		Object o = null;
		try {
			Field f = c.getDeclaredField(name);
			f.setAccessible(true);
			o = f.get(obj);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			throw new FieldAccessException("The field " + name
					+ " can't be accessed.");
		} catch (IllegalAccessException e) {
			throw new FieldAccessException("The field " + name
					+ " can't be accessed.");
		} catch (NoSuchFieldException e) {
			throw new cn.edu.nju.software.sd.torm.exception.NoSuchFieldException(
					"The field " + name + " can't be found.");
		}

		return o;
	}

	/**
	 * Set the property value of the obj, the property information
	 * is specified by the PesistenceProperty p. 
	 * @param c
	 * @param obj
	 * @param p
	 * @param value
	 */
	protected void setPropertyValue(Class c, Object obj, PersistenceProperty p,
			Object value) {
		if (value == null)
			return;
		String name = p.getPropertyName();
		try {
			Field f = c.getDeclaredField(name);
			f.setAccessible(true);
			f.set(obj, value);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			throw new FieldAccessException("The field " + name
					+ " can't be accessed.");
		} catch (IllegalAccessException e) {
			throw new FieldAccessException("The field " + name
					+ " can't be accessed.");
		} catch (NoSuchFieldException e) {
			throw new cn.edu.nju.software.sd.torm.exception.NoSuchFieldException(
					"The field " + name + " can't be found.");
		}

	}
	
	/**
	 * Get a connection to the database which has been determined in the
	 * configure file.
	 * 
	 * @return A connection to the database which has been determined in the
	 *         configure file.
	 * @throws SQLException
	 *             It will be throwed if there there are some exceptions while
	 *             creating the connection.
	 */
	protected Connection getConnection() throws SQLException {
		Map<String, String> cfg = configuration.getConfiguration();
		try {
			System.out.println(cfg.get("torm.connection.driver_class").trim());
			Class.forName(cfg.get(
					"torm.connection.driver_class").trim());
		} catch (ClassNotFoundException e) {
			throw new PersistenceException("Driver class "
					+ cfg.get("torm.connection.driver_class")
							.trim() + " not found.");
		}
		System.out.println(cfg
				.get("torm.connection.url")+"\n"+ cfg
				.get("torm.connection.username")+"\n"+ cfg
				.get("torm.connection.password"));
		return java.sql.DriverManager.getConnection(cfg
				.get("torm.connection.url"), cfg
				.get("torm.connection.username"), cfg
				.get("torm.connection.password"));
	}

	/**
	 * Get the getter of the Property p.
	 * @param c
	 * @param p
	 * @return
	 */
	private Method getPropertyGetter(Class c, PersistenceProperty p) {
		String pName = p.getPropertyName();
		String formatName = pName.substring(0, 1).toUpperCase()
				+ pName.substring(1).toLowerCase();
		Method m = null;
		try {
			Field property = c.getDeclaredField(p.getPropertyName());
			m = c.getMethod("set" + formatName, new Class[] { property
					.getType() });
		} catch (Exception e) {
			e.printStackTrace();
		}
		return m;

	}



	/**
	 * Create a new instance of class c, and the instance is enhanced by
	 * the Enhancer. This is for the purpose of method interception.
	 * @param c
	 * @param interceptedMethod
	 * @return
	 */
	private Object newInstance(Class c, Method interceptedMethod) {
		System.out.println(c.getName());
		PersistenceObjectMethodInterceptor interceptor = interceptors.get(c);
		if (interceptor == null) {
			interceptor = new PersistenceObjectMethodInterceptor(c,
					interceptedMethod);
			interceptors.put(c, interceptor);
		}
		return interceptor.getEnhancedObject();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -