ITEEDU

SessionFactory  注入

Spring 可以与Hibernate结合使用,Hibernate的连结、事务管理等是由建立SessionFactory开始的, SessionFactory在 应用程式中通常只需存在一个实例,因而SessionFactory底层的DataSource可以 使用Spring的 IoC注入,之后您再注入SessionFactory至相依的物件之中。

例如可以改写一下 第一个 Hibernate 程式,首先您可以删除hibernate.cfg.xml,因为这部份可以 由Spring在Bean定义档中撰写DataSource设定及依赖注入来取代,您可以如下撰写Spring的Bean 定义档:

•      beans‐config.xml
<?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,进行简单的资料存取:

•      SpringHibernateDemo.java
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>
...