使用Hibernate Sync(以下简称HS)工具来生成hbm和pojo,由于他同时也能生成DAO,而且生成的DAO还不错,我计划使用它生成的DAO来构建DAO层
但是它和Spring配合使用有个小小的问题,就是由于Spring的动态代理是基于接口的,那么它生成的DAO就必须有个接口才行,可是它生成的DAO不是基于接口的
我觉得可能有两个方法:
1、就是通过Eclipse的重构功能,用HS生成的DAO来Extrect一个接口,然后再通过Spring管理
2、使用Spring的cglib进行代理的方式来代理它的DAO,不过不知道Spring是否有这个支持,因为Spring的IoC是基于setter的,而它生成的DAO中是没有set(Session session)方法的
解决方法一(已成功):在使用HS生成DAO之后,通过它来Extrect一个接口,然后在使用HS生成的根DAO(_BaseRootDAO,这是所有DAO的根)上添加继承关系,使它集成Spring的HibernateDaoSupport,然后把它跟HibernateDaoSupport冲突的所有方法都注释掉(也就是说,使用HibernateDaoSupport中的方法),这样,在Spring的配置文件中就可以使用所有HS生成的DAO了^_^!(good!)
步骤:(不包括安装HS)
1.建立库表
2.在Eclipse将HS的mapping file添加到new操作中
3.在entity中建立mapping文件(这时会要求连接数据库,使用JDBC连一下就可以了,HS要访问数据库获得表的属性)
(这里要注意一件事情:HS生成的映射文件是以hbm为后缀的,而不是hbm.xml,可以在生成时修改)
4.右击生成的hbm文件,选择HS-->Synchronize and Overview
5.这时,HS会在这个文件夹下添加两个包:Base和dao。
base包用来包含HS生成的所有Dao根类(_BaseRootDAO)、特定Dao的根类(如:BaseUserDAO)特定POJO的根类(如:BaseUser)
dao包用来包含Dao的实现类(如:UserDAO)实际上这里面的DAO实现类几乎没有东西,全部的方法都已经在base包中的两个根类中实现了
6.下面就是关键步骤了,下面我们把这些生成的DAO集成到Spring中,首先,更改base包中的Dao根类_BaseRootDAO,让它扩展Spring的HibernateDaoSupport抽象类,这时,会有一些方法冲突(因为HS也致力于解决统一管理的Session,难免有冲突),把冲突的方法都注释掉。
7.然后在特定DAO的根类上(如上面说到的BaseUserDAO)使用Eclipse的重构功能来Extract一个接口(如:命名为IUserDAO),这个接口就可以被Spring用来通过AOP来注入SessionFactory。
8.至此,一个几乎不用编码的DAO层便建立起来了。^_^!
解决方法二(已成功):在Spring的配置文件中,管理sessionFactory的时候会设置hibernateProperties属性,将
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>加入到它的属性列表中,如下:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
</props>
</property>
然后让BaseRootDAO extends HibernateDaoSupport,注释掉冲突的方法即可
接下来要解决的问题是:
l HS生成的baseDAO中有很多同HibernateDaoSupport冲突的方法,这些方法中包括最重要的setSessionFactory(),应该试试能否使用它来代替HibernateDaoSupport(试验结果:不可以)
2 HS是否可以生成多表关联的DAO和PO,是否能够在PO种保持这种关联?这关系到它生成的hbm中是否包含这种关联(解决:HS好像不支持一对多和多对多关系,但是这可以通过修改HS的模板来解决,下面会说到)
但是上面第一个问题可以通过修改HS的模板和配置来解决:
l 首先要修改HS的vm文件:
打开eclipse的安装目录,找到plugin下的com.hudson.hibernatesynchronizer_2.3.1目录,下面有一个hibernatesynchronizer.jar文件,这里面是hibernatesynchronizer的发布包,在其中有以vm结尾的文件,导出其中的BaseRootDAO.vm文件,然后使用UltraEdit修改之,使之
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
再让它继承虚拟类HibernateDaoSupport
把它放回到jar包中
2 然后选择windows-->preferences-->HS-->snippets,通过在这个模板中定义生成的DAO支持Spring的HibernateDaoSupport
在BaseRootDAOSessionMothed中注释掉一下方法:
protected static void setSessionFactory (SessionFactory sessionFactory) {
setSessionFactory((String) null, sessionFactory);
}
protected SessionFactory getSessionFactory() throws HibernateException {
return getSessionFactory (getConfigurationFileName());
}
protected Session getSession() throws HibernateException {
return createSession();
}
这样就可以让HS产生的DAO代码默认支持HibernateDaoSupport
下面我们来说说第二个问题,如何让HS支持一对多关系和多对多关系
这个需要手动修改hbm文件
例如定义User到Address的一对多联系(双向)
1 在生成User.hbm.xml中添加:
<set name="Address" lazy="true" inverse="true" cascade="all" >
<key column="id"/>
<one-to-many class="com.sxf.techSample.entity.Address" />
</set>
2 在Address.hbm.xml中添加:
<many-to-one name="user" column="userid" class="com.sxf.techSample.entity.User" cascade="save-update">
</many-to-one>
3 HS会为你在User.java文件中生成以下代码
/**
* Return the value associated with the column: Address
*/
public java.util.Set getAddress () {
return this._address;
}
/**
* Set the value related to the column: Address
* @param _address the Address value
*/
public void setAddress (java.util.Set _address) {
this._address = _address;
}