3、Hibernate的DAO实现
DAO对象是模块化的数据库访问组件,DAO对象通常包括:对持久化类的基本CRUD操作(插入、查询、更新、删除)操作。Spring对Hibernate的DAO实现提供了良好的支持。主要有如下两种方式的DAO实现:
继承HibernateDaoSupport的实现DAO
基于Hibernate3.0实现DAO
不管采用哪一种实现,这种DAO对象都极好地融合到Spring的ApplicationContext中,遵循依赖注入模式,提高解耦。
继承HibernateDaoSupport实现DAO
Spring为Hibernate的DAO提供工具类:HibernateDaoSupport。该类主要提供如下两个方法,方便DAO的实现:
public final HibernateTemplate getHibernateTemplate()
public final void setSessionFactory(SessionFactory sessionFactory)
其中,setSessionFactory方法用来接收Spring的ApplicationContext的依赖注入,可接收配置在Spring的SessionFactory实例,getHibernateTemplate方法则用来根据刚才的SessionFactory产生Session,最后生成HibernateTemplate来完成数据库访问。
HibernateTemplate的常规用法
HibernateTemplate提供非常多的常用方法来完成基本的操作,比如通常的增加、删除、修改、查询等操作,Spring 2.0更增加对命名SQL查询的支持,也增加对分页的支持。大部分情况下,使用Hibernate的常规用法,就可完成大多数DAO对象的CRUD操作。下面是HibernateTemplate的常用方法简介:
void delete(Object entity):删除指定持久化实例
deleteAll(Collection entities):删除集合内全部持久化类实例
find(String queryString):根据HQL查询字符串来返回实例集合
findByNamedQuery(String queryName):根据命名查询返回实例集合
get(Class entityClass, Serializable id):根据主键加载特定持久化类的实例
save(Object entity):保存新的实例
saveOrUpdate(Object entity):根据实例状态,选择保存或者更新
update(Object entity):更新实例的状态,要求entity是持久状态
setMaxResults(int maxResults):设置分页的大小
Hibernate的复杂用法HibernateCallback
HibernateTemplate还提供一种更加灵活的方式来操作数据库,通过这种方式可以完全使用Hibernate的操作方式。HibernateTemplate的灵活访问方式是通过如下两个方法完成:
Object execute(HibernateCallback action)
List execute(HibernateCallback action)
这两个方法都需要一个HibernateCallback的实例,HibernateCallback实例可在任何有效的Hibernate数据访问中使用。程序开发者通过HibernateCallback,可以完全使用Hibernate灵活的方式来访问数据库,解决Spring封装Hibernate后灵活性不足的缺陷。HibernateCallback是一个接口,该接口只有一个方法doInHibernate(org.hibernate.Session session),该方法只有一个参数Session。
通常,程序中采用实现HibernateCallback的匿名内部类来获取HibernateCallback的实例,方法doInHibernate的方法体就是Spring执行的持久化操作
注意:方法doInHibernate方法内可以访问Session,该Session对象是绑定到该线程的Session实例。该方法内的持久层操作,与不使用Spring时的持久层操作完全相同。这保证对于复杂的持久层访问,依然可以使用Hibernate的访问方式。
下面,让我们看一下接 CRUD的一些方法的实现吧:
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import test.dao.Dao;
public class DaoImpl extends HibernateDaoSupport implements Dao{
public List findAllBy(final Class clazz, final String name, final Object value) {
// 实现根据属性名和属性值查询对象,返回唯一对象
return getHibernateTemplate().executeFind(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException,SQLException{
Criteria criteria=session.createCriteria(clazz);
criteria.add(Restrictions.eq(name, value));
criteria.setCacheable(true);
return criteria.list();
}
});
}
public List findAllBy(final Class clazz, final Map filter,final Map sorMap,final int pageNo,final int pageSize) {
// 实现返回 根据Map中过滤条件和分页参数查询
return getHibernateTemplate().executeFind(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException,SQLException{
Criteria criteria=session.createCriteria(clazz);
filterCriteria(criteria, filter);
sortCriteria(criteria,sorMap);
if (pageNo != -1) {
criteria.setFirstResult(pageNo > 1
? (pageNo - 1) * pageSize
: 0);
criteria.setMaxResults(pageSize);
}
criteria.setCacheable(true);
return criteria.list();
}
});
}
/**
* 构造criteria的过滤条件的回调函数
*/
protected void filterCriteria(Criteria criteria, Map filter) {
if (MapUtils.isNotEmpty(filter)) {
for (Iterator iterator = filter.keySet().iterator(); iterator.hasNext();) {
String fieldName = (String) iterator.next();
criteria.add(Restrictions.eq(fieldName, filter.get(fieldName)));
}
}
}
/**
* 构造Criteria的排序条件.
*
* @param sortMap 排序条件.
* @param criteria Criteria实例.
*/
protected void sortCriteria(Criteria criteria, Map sortMap) {
if (MapUtils.isNotEmpty(sortMap)) {
for (Iterator iterator = sortMap.keySet().iterator(); iterator.hasNext();) {
String fieldName = (String) iterator.next();
String orderType = (String) sortMap.get(fieldName);
criteria.addOrder(StringUtils.equalsIgnoreCase("asc", orderType)
? Order.asc(fieldName)
: Order.desc(fieldName));
}
}
}
public Object findBy(final Class clazz, final String name, final Object value) {
// 实现根据对象属性名和属性值,返回唯一对象
return getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException, SQLException {
// TODO Auto-generated method stub
Criteria criteria=session.createCriteria(clazz);
criteria.add(Restrictions.eq(name,value));
List list=criteria.list();
return list==null ||list.isEmpty()?null:list.iterator().next();
}
});
}
public Object getObject(Class clazz, Serializable id) {
// 实现返回与此类对应主键为id的所有值
Object o=getHibernateTemplate().get(clazz, id);
if(o==null){
throw new ObjectRetrievalFailureException(clazz,id);
}
return o;
}
public List getObjects(Class clazz) {
// 实现返回entity类型值
return getHibernateTemplate().loadAll(clazz);
}
public void removeObject(Class clazz, Serializable id) {
// 实现根据数据库中与此类对应表的主键(id)删除此对象
getHibernateTemplate().delete(getObject(clazz,id));
}
public void removeObject(Object o) {
// 实现删除对象
getHibernateTemplate().delete(o);
}
public void removeObjects(Collection objects) {
// TODO Auto-generated method stub
getHibernateTemplate().deleteAll(objects);
}
public Serializable saveObject(Object o) {
// 实现序列化保存对象
return getHibernateTemplate().save(o);
}
public int total(Class clazz, Map filter) {
return 0;
// TODO Auto-generated method stub
}
public void updateObject(Object o) {
// 实现更新对象
getHibernateTemplate().update(o);
}
}
然后,我们要配置.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE
beans
PUBLIC
"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean
id="Dao"
class="test.dao.hibernate.DaoImpl">
<property
name="sessionFactory"
ref="sessionFactory" />
</bean>
</beans>
首先,我们先要理解一下相关知识点:
1、对象的序列化:Serializable
对象序列化是对象永久化的一种机制,可以把序列化当成一种深度克隆的方法,确切的说应该是对象的序列化,一般程序在运行时,产生对象,这些对象随着程序的停止运行而消失,但如果我们想把某些对象(因为是对象,所以有各自不同的特性)保存下来,在程序终止运行后,这些对象仍然存在,可以在程序再次运行时读取这些对象的值,或者在其他程序中利用这些保存下来的对象。这种情况下就要用到对象的序列化。一般对象序列化后会保存在存储设备(硬盘)上,以文件的形式出现。
2、CRUD
CRUD是增加、读取、更新和删除几个单词的首字母简写 即Create,Read,Update,Delete四个单词的缩写,主要被用在描述软件系统中数据库或者持久层的基本操作功能。
(In computing, CRUD is an acronym for
create, retrieve, update, and delete. It is used to refer to the basic
functions of a database or persistence layer in a software system.)
在进行Hibernate开发过程中,我们通常会使用DAO模式,有一些通用的数据操作方法,如CRUD,我们通常会将这些方法集中在一个DAO,这样会简便很多。DAO数据访问接口如下:
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface Dao {
List getObjects(Class clazz);//返回数据库中与此类对应的表的所有值,即entity类型中的所有信息
Object getObject(Class clazz, Serializable id);//返回与此类对应的表主键为id的所有值
Serializable saveObject(Object o);//序列化保存对象。
void updateObject(Object o);//更新此对象
void removeObject(Class clazz, Serializable id);//根据数据库中与此类对应表的主键(id)删除此对象
void removeObject(Object o);//删除此对象
void removeObjects(Collection objects);
/*
* 根据属性名和属性值查询对象,返回唯一对象
*/
Object findBy(Class clazz, String name, Object value);
/*
* 根据属性名和属性值查询对象,返回所以符合条件的对象
*/
List findAllBy(Class clazz, String name, Object value);
/**
* 根据Map中过滤条件和分页参数查询.
*
* @param filter 过滤条件.
* @param sortMap 排序条件.
* @param pageNo 当前页码
* @param pageSize 每页显示记录数.
*/
List findAllBy(Class clazz, Map filter, Map sorMap, int pageNo, int pageSize);
/**
* 符合filter过滤条件的记录总数
* @param clazz
* @param filter
* @return
*/
int total(Class clazz, Map filter);
}