📄 defaultpersistencemanager.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 + -