下面还是通过一个简单的例子来介绍,如下:
1.新建工程 SpringHibernate01,引入Spring框架的开发包和配置文件,如果使用的是MyEclipse工具,这里需要引入 Spring core Libraries 和 Spring Persistence Libraries两个包,我这里引入的是 Spring 3.1 core Libraries 和
Spring 3.1 Persistence Libraries
2.然后引入Hibernate框架的开发包和连接数据库的驱动包
3.接下来先根据数据表编写相应的实体类,并为其添加hbm.xml映射描述文件
我的数据表名为 COST,如下是我的实体类 Cost.java :
package com.jeason.entity;
import java.sql.Date;
public class Cost {
private Integer cost_id;
private String name;
private Integer base_duration;
private Double base_cost;
private Double unit_cost;
private String status;
private String descr;
private Date creatime;
private Date startime;
private String cost_type;
//这里别忘了添加属性的get()、set()方法
............
}
如下是映射描述文件 cost.hbm.xml :
<?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>
<class name="com.jeason.entity.Cost" table="COST">
<id name="cost_id" type="integer" column="COST_ID">
<generator class="native">
<param name="sequence">COST_SEQ</param>
</generator>
</id>
<property name="base_cost" type="double" column="BASE_COST" />
<property name="base_duration" type="integer" column="BASE_DURATION" />
<property name="unit_cost" type="double" column="UNIT_COST" />
<property name="cost_type" type="string" column="COST_TYPE" />
<property name="creatime" type="date" column="CREATIME" />
<property name="descr" type="string" column="DESCR" />
<property name="name" type="string" column="NAME" />
<property name="startime" type="date" column="STARTIME" />
<property name="status" type="string" column="STATUS" />
</class>
</hibernate-mapping>
4.然后编写DAO接口和其实现类
(在上一篇介绍Spring整合JDBC的时候,说过DAO接口的实现类要继承自JdbcDAOSupport类,而这里的实现类 继承自HibernateDaoSupport类,利用其提供的HibernateTemplate进行增删改查操作)
我的DAO接口 CostDAO.java 如下:
package com.jeason.dao;
public interface CostDAO {
public List<Cost> findAll();
public Cost findByID(int costID);
public Cost findByName(String name);
public void save(Cost cost);
public void modify(Cost cost);
public void delete(int id);
}
实现类如下:
package com.jeason.dao.impl;
public class HibernateCostDAO extends HibernateDaoSupport implements CostDAO {
@Override
public List<Cost> findAll() {
String hql = "from Cost";
List<Cost> list = getHibernateTemplate().find(hql);
return list;
}
@Override
public Cost findByID(int costID) {
Cost cost = (Cost)getHibernateTemplate()
.get(Cost.class, costID);
return cost;
}
/* 注意:在Spring整合Hibernate应用时,如果需要用到Hibernate中的session,可以调用HibernateTemplate对象的execute方法采用函数回调的方式实现,execute()方法的参数为一个匿名内部类,这个匿名类实现的是HibernateCallBack接口,而它的doInHibernate()方法中有一个传入的Session类型的参数,然后在重写的doInHibernate()方法中就可以像使用Hibernate的时候一样使用session了,使用如下:*/
@Override
public Cost findByName(final String name) {
List<Cost> list = (List)getHibernateTemplate().execute(
new HibernateCallback<Object>(){
@Override
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
String hql = "from Cost where name=?";
Query query = session.createQuery(hql);
query.setString(0, name);
List<Cost> list = query.list();
return list;
}
});
return list.get(0);
}
@Override
public void save(Cost cost) {
getHibernateTemplate().save(cost);
}
@Override
public void modify(Cost cost) {
getHibernateTemplate().update(cost);
}
@Override
public void delete(int id) {
Cost cost = findByID(id);
getHibernateTemplate().delete(cost);
}
}
5.接下来是最后一步,也是最重要的一步了,要将DAO组件交给Spring容器进行管理,
==“层层注入”==:
DAO组件配置时,需要采用下面的注入关系:
dataSource(dbcp连接池)
---> 注入给SessionFactory(Spring提供了一个SessionFactory的bean组件)
----> 注入给DAO组件
我的 applicationContext.xml 的主要配置如下:
<!-- 配置连接池对象,这里需要引入dbcp连接池的jar包 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="oracle.jdbc.OracleDriver">
</property>
<property name="url"
value="jdbc:oracle:thin:@localhost:1521:xe">
</property>
<property name="username" value="******"></property>
<property name="password" value="******"></property>
</bean>
<!-- LocalSessionFactoryBean是Hibernate中的sessionFactory的一个子类 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 注入数据库连接信息 -->
<property name="dataSource">
<ref bean="dataSource" />
</property>
<!-- 注入Hibernate参数 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<!-- 注入映射描述信息 -->
<property name="mappingResources">
<list>
<value>com/jeason/entity/cost.hbm.xml</value>
</list>
</property>
</bean>
<!-- 配置DAO组件 -->
<bean id="hibernateCostDao"
class="com.jeason.dao.impl.HibernateCostDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
这样,一个简单的Spring+Hibernate的工程就配置成功了,经本人测试已成功。
上面的例子采用的是xml配置的方式实现的,这里当然也可以使用注解的方式实现,注解实现的方式与Spring整合JDBC时相同,这里不再说明。
注意:
1.上面提到了在Spring整合Hibernate时,在DAO组件中也可以使用session来进行操作数据,其实在Spring+Hibernate中使用session可以采用两种方式:
A.由于DAO的实现类继承自HibernateDaoSupport类,而HibernateDaoSupport类中提供了一个getSession()方法,因此我们可以在DAO的实现类中直接使用getSession()方法获得session
B.第二种方式就是如同上面的例子一样采用HibernateTemplate对象的execute()方法采用函数回调的方式
看起来感觉第一种方式使用起来比较容易,但是在使用第一种方式时需要手动的关闭session连接,每用一次都要手动的调用close()方法,否则太浪费内存;而第二种方式虽然看似麻烦,但是用完之后不需要手动的关闭session,所以,如果在你的业务中需要使用到session,推荐使用第二种方式。
2.在上面的例子中我直接省去了hibernate.cfg.xml配置文件,而是将数据库的连接信息,数据库方言等信息配置在了Spring的SessionFactory配置中,这里也可以采用原来的hiberntae.cfg.xml配置文件,只需要在Spring中的SessionFactory配置中指定hibernate.cfg.xml的路径就OK,如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocations">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>