Spring 可以与Hibernate结合使用,Hibernate的连结、事务管理等是由建立SessionFactory开始的, SessionFactory在 应用程式中通常只需存在一个实例,因而SessionFactory底层的DataSource可以 使用Spring的 IoC注入,之后您再注入SessionFactory至相依的物件之中。
例如可以改写一下 第一个 Hibernate 程式,首先您可以删除hibernate.cfg.xml,因为这部份可以 由Spring在Bean定义档中撰写DataSource设定及依赖注入来取代,您可以如下撰写Spring的Bean 定义档:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN""http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="dataSource" class="org.springframework.jdbc. → datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/demo</value> </property> <property name="username"> <value>caterpillar</value> </property> <property name="password"> <value>123456</value> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm. → hibernate3.LocalSessionFactoryBean" destroy-method="destroy"> <property name="dataSource"> <ref bean="dataSource"/> </property> <property name="mappingResources"> <list> <value>onlyfun/caterpillar/User.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> </props> </property> </bean> <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> </beans>
可以看到 使用 Spring 整合 Hibernate 的好处,可 以直接将 DataSource 注入至 org.springframework.orm.hibernate3.LocalSessionFactoryBean 中,至于 Hibernate 所 需的相关设定, 则可透过 LocalSessionFactoryBean 的相关属性来设定,像是设定资料库名称、使用者名称、密码 等, LocalSessionFactoryBean 会建立 SessionFactory 的实例,并在执行依赖注入时将这个实例设 定给 UserDAO。
Hibernate 的物件与关联表格的映射文件之位置与名称,则指定于"mappingResources"属性中,如 果您自行提供 Hibernate 本 身的设定档(hibernate.cfg.xml),您也可以使用 "configLocation"属性 来指定设定档的位置,而这边则使用"hibernateProperties"属性在 Spring 的 Bean 定义档中直接指 定,可以藉此减少对 XML 组态档案的管理。
注意!在 Spring 1.2.6 中可以选择要整合 Hibernate 2 或 Hibernate 3(Hibernate 3 在套件名称上与 Hibernate 2 是 不相容的 ),因而在 Spring 中 整合时会 有两种版 本的 API ,例 如 org.springframework.orm.hibernate.LocalSessionFactoryBean 是在整合 Hibernate 2 时所使用的类别, 而 org.springframework.orm.hibernate3.LocalSessionFactoryBean 则是在整 合 Hibernate 3 时使用的 类别,因为主要类别名称是相同的(例如 LocalSessionFactoryBean),所以撰写时要注意套件名称 的设定是否正确。
专案中剩下的部份都不用修改,可以撰写一个简单的测试程式来看看如何使用 Spring 整合 Hibernate,进行简单的资料存取:
package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.FileSystemXmlApplicationContext; public class SpringHibernateDemo { public static void main(String[] args) { ApplicationContext context =new FileSystemXmlApplicationContext( "beans-config.xml"); // 建立 DAO 物件 IUserDAO userDAO = (IUserDAO) context.getBean("userDAO"); User user = new User(); user.setName("caterpillar"); user.setAge(new Integer(30)); userDAO.insert(user); user = userDAO.find(new Integer(1)); System.out.println("name: " + user.getName()); } }
执行的结果基本上与 HibernateDemo 专案是相同的。如果您不是选择加入 spring.jar 的话,则您 必须个别加入以下的档案至 Classpath 路径之中:sping‐core.jar、spring‐beans.jar、spring‐context.jar、 spring‐ jdbc.jar、spring‐dao.jar、spring‐hibernate.jar。
在映射文件的指定上,除了使用 "mappingResources" 属性设 定之外,您也可以使 用 "mappingDirectoryLocations"属性设定,一次指定某个路径下的所有.hbm.xml 档案,例如:
... <bean id="sessionFactory" class="org.springframework.orm.hibernate3. →?LocalSessionFactoryBean " destroy-method= "destroy"> <property name="dataSource"> <ref bean="dataSource"/> </property> <property name="mappingDirectoryLocations"> <list> <value>classpath:/onlyfun/caterpillar</value> </list> </property> ... </bean> ...