Hibernate根据持久化对象获取对应数据库表信息(表名,主键等)

Hibernate根据持久化对象获取对应数据库表信息(表名,主键等)
 这几天要写个DAO层自动记录数据库操作日志的功能,兼容Hibernate及JDBC。

  Hibernate开发中需要根据持久层对象获取所映射的数据库表相关信息,如表名,主键,外键对象等相关系。

一、核心的几个方法如下:

获取对象映射缓存管理类

AbstractEntityPersister classMetadata = (AbstractEntityPersister)super.getSessionFactory().getClassMetadata(object.getClass());  

//表名

String tableName = classMetadata.getTableName();

//对象名称  

String entityName = classMetadata.getEntityName();  

//主键列映射属性

String pkPropertyName = classMetadata.getIdentifierPropertyName();

//数据库主键列

String[] pkColumns = classMetadata.getIdentifierColumnNames();

//反射调用获取主键值

String pkPropertyValue = BeanUtils.getProperty(object, pkPropertyName);

hibernate自带反射取值函数

classMetadata.getPropertyValue(object, propertyName, org.hibernate.EntityMode.POJO);

非主键属性

String[] propertyNames = classMetadata.getPropertyNames();

非主键数据库列

String[] propertyColumns = classMetadata.getPropertyColumnNames(propertyName);

非主键属性是否可修改bool值有序集合

boolean[] isUpdateFalgs = classMetadata.getPropertyUpdateability();

非主键属性是否可添加bool值有序集合

boolean[] isInsertFlags = classMetadata.getPropertyInsertability();

获取属性数据类型

Type propertyType = classMetadata.getPropertyType(pkPropertyName)

是否是集合类型

propertyType.isCollectionType()

是否是对象类型

propertyType.isEntityType()

是否是时间类型

propertyType instanceof DateType

获取外键对象

Object fkObj = classMetadata.getPropertyValue(object, propertyName, org.hibernate.EntityMode.POJO);

二、下边是日志记录的核心代码块:

/**

* @Description:  初始化

* @param sessionFactory

* @param object

*/

public HibernateResourceLog(SessionFactory sessionFactory, Object object)

{

HibernateResourceLog.sessionFactory = sessionFactory;

this.object = object;

super.dbInfoBean = getTableInfoByObj();

}

/**

* @Description: 设置操作后信息(事务管理)

* @author: wubin

* @return

* @date: 2012-9-27

*/

@Override

public DBInfoBean setNextInfo()

{

// 事务管理

// 1.获取数据库字段, 并生成Map对象

LinkedHashMap<String, Object> nextInfoMap = new LinkedHashMap<String, Object>();

Object[] colNames = new Object[0];

if(!dbInfoBean.getOperateType().equals(BusinessConstants.RESOURCE_OPERATE_TYPE_INSERT))

{

colNames = dbInfoBean.getPreInfo().keySet().toArray();

for(int i = 0; i < colNames.length; i++)

{

nextInfoMap.put(String.valueOf(colNames[i]), "");

}

}

try {

// 2.根据字段查询Hibernate中对应属性

AbstractEntityPersister classMetadata = (AbstractEntityPersister)sessionFactory.getClassMetadata(object.getClass());

// 3.主键填值

// 3.1获取主键列映射属性

String pkPropertyName = classMetadata.getIdentifierPropertyName();

// 3.2非集合类属性

if(!classMetadata.getPropertyType(pkPropertyName).isCollectionType())

{

//3.3 获取数据库主键列

String[] pkColumns = classMetadata.getIdentifierColumnNames();

//3.4 反射调用获取主键值

String pkPropertyValue = BeanUtils.getProperty(object, pkPropertyName);

nextInfoMap.put(pkColumns[0], pkPropertyValue);

}

// 4.非主键填值

String[] propertyNames = classMetadata.getPropertyNames();

boolean[] isUpdateFalgs = classMetadata.getPropertyUpdateability();

boolean[] isInsertFlags = classMetadata.getPropertyInsertability();

for(int i = 0; i < propertyNames.length; i++)

{

String propertyName = propertyNames[i];

String[] propertyColumns = classMetadata.getPropertyColumnNames(propertyName);

// 如果需要更新或添加则判断数据类型获取对象属性,否则设置标志,为后续日志记录做准备

if((!isUpdateFalgs[i] || !isInsertFlags[i])

&& !dbInfoBean.getOperateType().equals(BusinessConstants.RESOURCE_OPERATE_TYPE_INSERT))

{

nextInfoMap.put(propertyColumns[0], dbInfoBean.getPreInfo().get(propertyColumns[0]));

}

else

{

parseObjectCache(nextInfoMap, propertyName);

}

}

} catch (IllegalAccessException e) {

logger.error(e);

} catch (InvocationTargetException e) {

logger.error(e);

} catch (NoSuchMethodException e) {

logger.error(e);

}

dbInfoBean.setNextInfo(nextInfoMap);

return dbInfoBean;

}

/**

* @Description: 获取对象对应数据库表信息

* @author: wubin

* @return

* @date: 2012-9-27

*/

private DBInfoBean getTableInfoByObj() {

// SessionFactory获取持久对象表信息对象

AbstractEntityPersister classMetadata = (AbstractEntityPersister)sessionFactory.getClassMetadata(object.getClass());

DBInfoBean dbInfoBean = new DBInfoBean();

// 获取表名

dbInfoBean.setTableName(classMetadata.getTableName());

// 获取主键列映射属性

String pkPropertyName = classMetadata.getIdentifierPropertyName();

// 非集合类属性

if(!classMetadata.getPropertyType(pkPropertyName).isCollectionType())

{

// 获取数据库主键列

String[] pkColumns = classMetadata.getIdentifierColumnNames();

dbInfoBean.setPkColumns(pkColumns);

// 反射调用获取主键值

String pkPropertyValue = "";

try {

pkPropertyValue = BeanUtils.getProperty(object, pkPropertyName);

} catch (IllegalAccessException e) {

logger.error(e);

} catch (InvocationTargetException e) {

logger.error(e);

} catch (NoSuchMethodException e) {

logger.error(e);

}

String[] pkPropertyValues = new String[]{pkPropertyValue};

dbInfoBean.setPkColumnsValue(pkPropertyValues);

}

else 

{

return null;

}

return dbInfoBean;

}

/**

* @Description: 将对象缓存属性转换成Map对象

* @author: wubin

* @param nextInfoMap

* @param propertyName

* @param classMetadata

* @param object

* @throws IllegalAccessException

* @throws InvocationTargetException

* @throws NoSuchMethodException

* @date: 2012-9-27

*/

private void parseObjectCache(LinkedHashMap<String, Object> nextInfoMap, String propertyName) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException

{

AbstractEntityPersister classMetadata = (AbstractEntityPersister)sessionFactory.getClassMetadata(object.getClass());

String[] propertyColumns = classMetadata.getPropertyColumnNames(propertyName);

Type propertyType = classMetadata.getPropertyType(propertyName);

// 4.1 对象属性取外键对象主键值

if(propertyType.isEntityType())

{

// 获取外键对象

Object fkObj = classMetadata.getPropertyValue(object, propertyName, org.hibernate.EntityMode.POJO);

AbstractEntityPersister fKclassMetadata = (AbstractEntityPersister)sessionFactory.getClassMetadata(fkObj.getClass());

// 获取主键属性

String fKPkPropertyName = fKclassMetadata.getIdentifierPropertyName();

if(propertyColumns.length > 0)

{

// 获取主键列值

String fkPkPropertyValue = BeanUtils.getProperty(fkObj, fKPkPropertyName);

nextInfoMap.put(propertyColumns[0], fkPkPropertyValue);

}

}

else if(propertyType.isCollectionType())

{

// 4.2 赞不考虑主键为集合属性,复合主键后期统一修改

}

else if (propertyType instanceof DateType) {

// 4.3 时间类型需转换

Date date = (Date)classMetadata.getPropertyValue(object, propertyName, org.hibernate.EntityMode.POJO);

String dateStr = DateUtil.getDateTime(date);

if(propertyColumns.length > 0)

{

nextInfoMap.put(propertyColumns[0], dateStr);

}

}

else 

{

// 4.3 字符串等普通类型直接取值

String propertyValue = BeanUtils.getProperty(object, propertyName);

if(propertyColumns.length > 0)

{

nextInfoMap.put(propertyColumns[0], propertyValue);

}

}

}

 

posted @ 2014-11-28 09:03  流氓剑客  阅读(2266)  评论(0编辑  收藏  举报