/**
作者:Willpower
来源:Rifoo Technology(http://www.rifoo.com)
时间:2006-02-19
备注:转载请保留以上声明
**/
对于Spring开发者来说,使用Hibernate作为持久层框架的越来越多。尽管Spring还可以集成JDO,iBatis等持久层框架,但是Hibernate是使用最为广泛的。这两个轻量级框架彼此能够很好的协调和集成在一起。接下来,我们一起看看是如何集成Spring和Hibernate的。
Hibernate是一个优秀的持久层框架。目前它非常流行,而且相对其他框架而言速度比较快,更是免费的。 它提供大量的映射支持和便捷的模型使得它被大受推崇。Hibernate尤其非常使用于中小型项目。但是,我们也不一定非要使用Hibernate,它并没有成为一种标准,但是目前来说它是最流行的。
下面我们开始配置Spring使用ORM(对象关系映射)。我们需要从Spring的dist目录(其他的来源也可以)中复制以下几个文件到工程文件中的lib下:hibernate2.jar,aopalliance.jar,cglib-full-2.0.2.jar,dom4j.jar,ehcache-1.1.jar和odmg.jar.
既然Hibernate是使用到了JAVA反射技术,因此在字节码的性能上并没有太大提高。我们要使得模型(model)持久化所需要做的工作是:创建映射,并在上下文中引用它们。
下面是映射文件的代码:
Example 5-12. Bike.hbm.xml
<hibernate-mapping>
<class name="com.springbook.Bike" table="bikes">
<id name="bikeId" column="bikeid" type="java.lang.Integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="manufacturer" column="manufacturer" type="string"/>
<property name="model" column="model" type="string"/>
<property name="frame" column="frame" type="int"/>
<property name="serialNo" column="serialno" type="string"/>
<property name="weight" column="weight" type="java.lang.Double"/>
<property name="status" column="status" type="string"/>
<set name="reservations">
<key column="bikeId"/>
<one-to-many class="com.springbook.Reservation"/>
</set>
</class>
</hibernate-mapping>
Example 5-13. Customer.hbm.xml
<hibernate-mapping>
<class name="com.springbook.Customer" table="customers">
<id name="custId" column="custid" type="java.lang.Integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="firstName" column="firstname" type="string"/>
<property name="lastName" column="lastname" type="string"/>
<set name="reservations">
<key column="custId"/>
<one-to-many class="com.springbook.Reservation"/>
</set>
</class>
</hibernate-mapping>
Example 5-14. Reservation.hbm.xml
<hibernate-mapping>
<class name="com.springbook.Reservation" table="reservations">
<id name="reservationId" column="resid" type="java.lang.Integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="reservationDate" column="resdate" type="date"/>
<many-to-one name="bike" column="bikeId" class="com.springbook.Bike"
cascade="none"/>
<many-to-one name="customer" column="custId"
class="com.springbook.Customer"
cascade="none"/>
</class>
</hibernate-mapping>
在上下文中,我们需要配置Hibernate properties,配置session factory并且将session factory以插件的形式加到facade中。 在事务处理上,JDO,iBATIS 和Hibernate都是一样的,是由依赖注入来完成的。
下面的代码显示上下文文件的改变:
Example 5-15. RentABikeApp-servlet.xml
<bean name="rentaBike" class="com.springbook.HibRentABike">
<property name="storeName"><value>Bruce's Bikes</value></property>
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/springbook/Bike.hbm.xml</value>
<value>com/springbook/Customer.hbm.xml</value>
<value>com/springbook/Reservation.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
因为我们前面都完成了一个facade接口,那么现在我们仅仅需要一个Hibernate的实现类来实现这个facade接口。我们可以使用模板(templates)技术。针对查找方法,指定一个HQL语句。针对更新,指定一个用来存储的新对象。
下面是Hibernate实现facade类的代码:
Example 5-16. HibRentABike.java
package com.springbook;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
import java.util.List;
import java.util.Date;
import java.util.Set;
import net.sf.hibernate.Query;
public class HibRentABike extends HibernateDaoSupport implements RentABike {
private String name;
public List getBikes( ) {
return getHibernateTemplate( ).find("from Bike");
}
public Bike getBike(String serialNo) {
Bike b = null;
List bikes = getHibernateTemplate( ).
find("from Bike where serialNo = ?", serialNo);
if(bikes.size( ) > 0) {
b = (Bike)bikes.get(0);
}
return b;
}
public Bike getBike(int bikeId) {
return (Bike)getHibernateTemplate( ).
load(Bike.class, new Integer(bikeId));
}
public void saveBike(Bike bike) {
getHibernateTemplate( ).saveOrUpdate(bike);
}
public void deleteBike(Bike bike) {
getHibernateTemplate( ).delete(bike);
}
public void setStoreName(String name) {
this.name = name;
}
public String getStoreName( ) {
return this.name;
}
public List getCustomers( ) {
return getHibernateTemplate( ).find("from Customer");
}
public Customer getCustomer(int custId) {
return (Customer)getHibernateTemplate( ).
load(Customer.class, new Integer(custId));
}
public List getReservations( ) {
return getHibernateTemplate( ).find("from Reservation");
}
public List getReservations(Customer customer) {
return getHibernateTemplate( ).
find("from Reservation where custId = ?", customer.getCustId( ));
}
public List getReservations(Bike bike) {
return getHibernateTemplate( ).
find("from Reservation where bikeId = ?", bike.getBikeId( )); }
public List getReservations(Date date) {
return getHibernateTemplate( ).
find("from Reservation where resdate = ?", date);
}
public Reservation getReservation(int resId) {
return (Reservation)getHibernateTemplate( ).
load(Reservation.class, new Integer(resId)); }
}
下面,我们看看Hibernate的传统写法,即不和Spring集成时的写法:
Example 5-17. HibRentABike.java
public List getBikesOldWay( ) throws Exception {
// Relies on other static code for configuration
// and generation of SessionFactory. Might look like:
// Configuration config = new Configuration( );
// config.addClass(Bike.class).addClass(Customer.class).
// addClass(Reservation.class);
// SessionFactory mySessionFactory = Configuration.
// buildSessionFactory( );
List bikes = null;
Session s = null;
try {
s = mySessionFactory.openSession( );
bikes = s.find("from Bike");
}catch (Exception ex) {
//handle exception gracefully
}finally {
s.close( );
}
return bikes;
}
Spring的Hibernate模板处理写法,和Hibernate传统写法几乎一样:
Example 5-18. HibRentABike.java
public List getBikes( ) {
return getHibernateTemplate( ).find("from Bike");
}
大家可以看到在Spring下,编写这样的代码量减少了很多,而且更多有关事务处理的事情都由Spring来完成了,我们程序员只需要关注业务实现。
作者:Willpower
来源:Rifoo Technology(http://www.rifoo.com)
时间:2006-02-19
备注:转载请保留以上声明
**/
对于Spring开发者来说,使用Hibernate作为持久层框架的越来越多。尽管Spring还可以集成JDO,iBatis等持久层框架,但是Hibernate是使用最为广泛的。这两个轻量级框架彼此能够很好的协调和集成在一起。接下来,我们一起看看是如何集成Spring和Hibernate的。
Hibernate是一个优秀的持久层框架。目前它非常流行,而且相对其他框架而言速度比较快,更是免费的。 它提供大量的映射支持和便捷的模型使得它被大受推崇。Hibernate尤其非常使用于中小型项目。但是,我们也不一定非要使用Hibernate,它并没有成为一种标准,但是目前来说它是最流行的。
下面我们开始配置Spring使用ORM(对象关系映射)。我们需要从Spring的dist目录(其他的来源也可以)中复制以下几个文件到工程文件中的lib下:hibernate2.jar,aopalliance.jar,cglib-full-2.0.2.jar,dom4j.jar,ehcache-1.1.jar和odmg.jar.
既然Hibernate是使用到了JAVA反射技术,因此在字节码的性能上并没有太大提高。我们要使得模型(model)持久化所需要做的工作是:创建映射,并在上下文中引用它们。
下面是映射文件的代码:
Example 5-12. Bike.hbm.xml
<hibernate-mapping>
<class name="com.springbook.Bike" table="bikes">
<id name="bikeId" column="bikeid" type="java.lang.Integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="manufacturer" column="manufacturer" type="string"/>
<property name="model" column="model" type="string"/>
<property name="frame" column="frame" type="int"/>
<property name="serialNo" column="serialno" type="string"/>
<property name="weight" column="weight" type="java.lang.Double"/>
<property name="status" column="status" type="string"/>
<set name="reservations">
<key column="bikeId"/>
<one-to-many class="com.springbook.Reservation"/>
</set>
</class>
</hibernate-mapping>
Example 5-13. Customer.hbm.xml
<hibernate-mapping>
<class name="com.springbook.Customer" table="customers">
<id name="custId" column="custid" type="java.lang.Integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="firstName" column="firstname" type="string"/>
<property name="lastName" column="lastname" type="string"/>
<set name="reservations">
<key column="custId"/>
<one-to-many class="com.springbook.Reservation"/>
</set>
</class>
</hibernate-mapping>
Example 5-14. Reservation.hbm.xml
<hibernate-mapping>
<class name="com.springbook.Reservation" table="reservations">
<id name="reservationId" column="resid" type="java.lang.Integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="reservationDate" column="resdate" type="date"/>
<many-to-one name="bike" column="bikeId" class="com.springbook.Bike"
cascade="none"/>
<many-to-one name="customer" column="custId"
class="com.springbook.Customer"
cascade="none"/>
</class>
</hibernate-mapping>
在上下文中,我们需要配置Hibernate properties,配置session factory并且将session factory以插件的形式加到facade中。 在事务处理上,JDO,iBATIS 和Hibernate都是一样的,是由依赖注入来完成的。
下面的代码显示上下文文件的改变:
Example 5-15. RentABikeApp-servlet.xml
<bean name="rentaBike" class="com.springbook.HibRentABike">
<property name="storeName"><value>Bruce's Bikes</value></property>
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/springbook/Bike.hbm.xml</value>
<value>com/springbook/Customer.hbm.xml</value>
<value>com/springbook/Reservation.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
因为我们前面都完成了一个facade接口,那么现在我们仅仅需要一个Hibernate的实现类来实现这个facade接口。我们可以使用模板(templates)技术。针对查找方法,指定一个HQL语句。针对更新,指定一个用来存储的新对象。
下面是Hibernate实现facade类的代码:
Example 5-16. HibRentABike.java
package com.springbook;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
import java.util.List;
import java.util.Date;
import java.util.Set;
import net.sf.hibernate.Query;
public class HibRentABike extends HibernateDaoSupport implements RentABike {
private String name;
public List getBikes( ) {
return getHibernateTemplate( ).find("from Bike");
}
public Bike getBike(String serialNo) {
Bike b = null;
List bikes = getHibernateTemplate( ).
find("from Bike where serialNo = ?", serialNo);
if(bikes.size( ) > 0) {
b = (Bike)bikes.get(0);
}
return b;
}
public Bike getBike(int bikeId) {
return (Bike)getHibernateTemplate( ).
load(Bike.class, new Integer(bikeId));
}
public void saveBike(Bike bike) {
getHibernateTemplate( ).saveOrUpdate(bike);
}
public void deleteBike(Bike bike) {
getHibernateTemplate( ).delete(bike);
}
public void setStoreName(String name) {
this.name = name;
}
public String getStoreName( ) {
return this.name;
}
public List getCustomers( ) {
return getHibernateTemplate( ).find("from Customer");
}
public Customer getCustomer(int custId) {
return (Customer)getHibernateTemplate( ).
load(Customer.class, new Integer(custId));
}
public List getReservations( ) {
return getHibernateTemplate( ).find("from Reservation");
}
public List getReservations(Customer customer) {
return getHibernateTemplate( ).
find("from Reservation where custId = ?", customer.getCustId( ));
}
public List getReservations(Bike bike) {
return getHibernateTemplate( ).
find("from Reservation where bikeId = ?", bike.getBikeId( )); }
public List getReservations(Date date) {
return getHibernateTemplate( ).
find("from Reservation where resdate = ?", date);
}
public Reservation getReservation(int resId) {
return (Reservation)getHibernateTemplate( ).
load(Reservation.class, new Integer(resId)); }
}
下面,我们看看Hibernate的传统写法,即不和Spring集成时的写法:
Example 5-17. HibRentABike.java
public List getBikesOldWay( ) throws Exception {
// Relies on other static code for configuration
// and generation of SessionFactory. Might look like:
// Configuration config = new Configuration( );
// config.addClass(Bike.class).addClass(Customer.class).
// addClass(Reservation.class);
// SessionFactory mySessionFactory = Configuration.
// buildSessionFactory( );
List bikes = null;
Session s = null;
try {
s = mySessionFactory.openSession( );
bikes = s.find("from Bike");
}catch (Exception ex) {
//handle exception gracefully
}finally {
s.close( );
}
return bikes;
}
Spring的Hibernate模板处理写法,和Hibernate传统写法几乎一样:
Example 5-18. HibRentABike.java
public List getBikes( ) {
return getHibernateTemplate( ).find("from Bike");
}
大家可以看到在Spring下,编写这样的代码量减少了很多,而且更多有关事务处理的事情都由Spring来完成了,我们程序员只需要关注业务实现。