JAVA破坏构架:手工配置Hibernate
我个人不是很喜欢Hibernate,主要是它的配置文件实在令人烦躁,但是我不能用JDK1.5,所以我想找个简单的办法配置
问题1、Spring和Hibernate同时需要数据库链接,如何只配置一份?
直接使用相同的配置信息文件,例如JDBC.Properties配置,Spring里面使用PropertyPlaceholderConfigurer配置Bean,而Hibernate则手工加载。
问题2、直接生成Hibernate HBM文件
从Class文件直接生成、
初始化JDBC
private void initJDBC()
throws DocumentException,ResourceException,IOException
{
m_jdbcProperty.load(ResourceHelper.getResourceAsStream("cfg/jdbc.properties"));
XMLHelper.each(new Node[]
{
cfg.Configuration.getInstance().getSystemNode(),
cfg.Configuration.getInstance().getModNode()
},
"hibernate/property",new IXMLNodeCallback()
{
public Object process(Node node)
throws DocumentException
{
String strPropertyName = node.valueOf("@name");
String strValue = node.valueOf("@value");
if(strPropertyName != null && strPropertyName.trim().length() > 0)
{
m_jdbcProperty.setProperty(strPropertyName,strValue);
}
return null;
}
});
}
配置HBM信息
private String getHibernateMapXml(Node node)
{
String strClassName = node.valueOf("@name");
String strTableName = node.valueOf("@table");
String strPrimaryTableField = node.valueOf("@idfield");
strPrimaryTableField = strPrimaryTableField == null || strPrimaryTableField.trim().length() < 1 ? null : strPrimaryTableField;
if(strClassName == null
|| strTableName == null
|| strClassName.trim().length() < 1
|| strTableName.trim().length() < 1)
{
log.error("不能完成映射,配置的映射信息必须包含name和table属性");
return null;
}
if(strPrimaryTableField == null)
{
log.error("不能完成映射,配置的映射信息" + strClassName + ">" + strTableName + "必须包含idfield属性");
return null;
}
log.info("开始映射" + strClassName + ">" + strTableName);
String strGenerator = node.valueOf("@idgenerator");
String[] strInitMaps = node.valueOf("@map").split(";");
StringHashtable mapClassField2Column = new StringHashtable();
for(int n = 0;null != strInitMaps && n < strInitMaps.length;n++)
{
String[] m = strInitMaps[n].split(":");
if(m.length > 1)
{
mapClassField2Column.put(m[0].trim().toUpperCase(),m[1].trim().toUpperCase());
}
}
try
{
Class class2Map = Class.forName(strClassName);
HBTable mapInfo = new HBTable(class2Map,strTableName);
PropertyInfo pInfo = PropertyInfoFactory.getInstance().getPropertyInfo(class2Map);
boolean bFoundPK = false;
StringBuffer buf = new StringBuffer();
StringCollection collFileds = pInfo.getFields();
for(int n = 0;n < collFileds.size();n++)
{
String strFieldName = collFileds.elementAt(n);
String strColumnName = mapClassField2Column.get(strFieldName.toUpperCase());
if(null == strColumnName)
{
strColumnName = strFieldName;
}
boolean isPK = strPrimaryTableField.equalsIgnoreCase(strColumnName) ||
strPrimaryTableField.equalsIgnoreCase(strFieldName);
Class cls = pInfo.getFieldClass(strFieldName);
if(null == cls || cls.isArray())
{
throw new ConfigurationException("类" + class2Map.getName() +
"中找不到字段" + strFieldName + "或者其类型为数组类型");
}
Class clsClassFieldType = DataTypes.boxedClass(cls);
mapInfo.addMap(strFieldName,strColumnName,isPK);
if(isPK)
{
bFoundPK = true;
String strID = ("<id name=\"" + strFieldName + "\" type=\"" + clsClassFieldType.getName() + "\">");
strID += ("<column name=\"" + strColumnName + "\" not-null=\"false\" />");
if(strGenerator != null && strGenerator.trim().length() > 0)
{
String strG = getGenerator(cls,strGenerator);
log.info(strTableName + "使用 " + strG + "作为 " + strColumnName + " 的自动生成参数");
strID += ("<generator class=\"" + strG + "\" />");
}
strID += ("</id>");
buf.insert(0,strID);
}
else
{
buf.append("<property name=\"" + strFieldName + "\" type=\"" + clsClassFieldType.getName() + "\">");
buf.append("<column name=\"" + strColumnName + "\" not-null=\"false\" />");
buf.append("</property>");
}
}
if(bFoundPK == false)
{
throw new ConfigurationException("配置中强制指定的idfield:" + strPrimaryTableField + "不存在");
}
if(buf.length() > 0)
{
buf.insert(0,"<class " +
"name=\"" + class2Map.getName() + "\" " +
"table=\"" + strTableName + "\" " +
"dynamic-update=\"true\" dynamic-insert=\"true\" >");
buf.append("</class>");
}
m_hash.put(mapInfo.getMapClass(),mapInfo);
return buf.toString();
}
catch(Exception excep)
{
log.error("映射" + strClassName + ">" + strTableName + "出现错误:" + excep.getMessage(),excep);
return null;
}
}
private String getGenerator(Class cls,String str)
throws ConfigurationException
{
if(null != str && str.length() > 0 && str.equals("#") == false)
{
return str;
}
DataTypes dt = DataTypes.fromClass(cls);
if(dt.getId() == DataTypes.DOUBLE.getId() || dt.getId() == DataTypes.INT.getId())
{
return "increment";
}
else if(dt.getId() == DataTypes.STRING.getId())
{
return "uuid.hex";
}
else
{
throw new ConfigurationException("不能找到类型" + cls.getName() + "的默认生成器!");
}
}
完成HIBernate配置
private static void initHibernateConfig()
{
getInstance();
if(null == sessionFactory)
{
synchronized(HibernateHelper.class)
{
if(null == sessionFactory)
{
// log.info(str);
Properties p = getInstance().m_jdbcProperty;
Properties p2 = new Properties();
for(java.util.Iterator it = p.keySet().iterator();it.hasNext();)
{
String strKey = (String) it.next();
String strValue = p.getProperty(strKey);
p2.setProperty(strKey,strValue);
if(strKey.toLowerCase().startsWith("hibernate.") == false)
{
p2.setProperty("hibernate." + strKey,strValue);
}
}
org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration();
cfg.setProperties(p2);
cfg.addXML("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE hibernate-mapping PUBLIC \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"" +
" \"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd\" ><hibernate-mapping>" +
getInstance().m_HibernateMapXMLs +
"</hibernate-mapping>");
sessionFactory = cfg.buildSessionFactory();
}
}
}
}