您的位置:首页 > 编程语言 > Java开发

改进版的hibernate泛型dao(依赖spring)

2009-03-11 15:58 288 查看
引用地址:http://blog.csdn.net/tom_221x/archive/2008/12/26/3611535.aspx

另提供IBM 社区基于Hibernate编写的GenericDao参考文章地址

中文版:http://www.ibm.com/developerworks/cn/java/j-genericdao.html

英文版:http://www.ibm.com/developerworks/java/library/j-genericdao.html

结构看图:



HinernateEntityDao和HibernateGenericDao都继承在spring的HibernateDaoSupport
一个提供和实体相关的操作,一个提供和实体类无关的操作。
然后以组合的方式在BaseDao中使用,这样程序中全部使用IBaseDao接口来操作数据,便于修改和维护.
xml配置实用如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-这个是和实体相关的dao,所以scope是prototype的每个实体对应一个对象->

<bean id="hedao"

class="com.hibernate.dao.extend.HibernateEntityDao" scope="prototype" lazy-init="true">

<property name="sessionFactory">

<ref bean="sessionFactory" />

</property>

</bean>



<!-这个和具体实体无关,所有dao共享->

<bean id="hgdao"

class="com.hibernate.dao.generic.HibernateGenericDao">

<property name="sessionFactory">

<ref bean="sessionFactory" />

</property>

</bean>

<!--使用泛型DAO作为抽象基类-->

<bean id="baseDao" class="com.hibernate.dao.base.BaseDao"

abstract="true" depends-on="hedao,hgdao">

<property name="hedao">

<ref bean="hedao" />

</property>

<property name="hgdao">

<ref bean="hgdao" />

</property>

</bean>



<!-- 配置实体Demodata的DAO -->

<bean id="demoDao" parent="baseDao">

<constructor-arg>

<value>com.hibernate.entityclass.Demodata</value>

</constructor-arg>

</bean>



</beans>

代码:
BaseDao.java

package com.hibernate.dao.base;

import java.io.Serializable;

import java.util.List;

import org.hibernate.Criteria;

import org.hibernate.Query;

import org.hibernate.criterion.Criterion;

import org.springframework.orm.hibernate3.HibernateTemplate;

import com.hibernate.dao.extend.HibernateEntityDao;

import com.hibernate.dao.generic.HibernateGenericDao;

import com.hibernate.dao.support.Page;

/**

* 提供hibernate dao的所有操作,<br>

* 实现类由spring注入HibernateEntityDao和HibernateGenericDao来实现

*

*/

public class BaseDao<T,PK extends Serializable> implements IBaseDao<T,PK> {

protected Class<T> entityClass;// DAO所管理的Entity类型.

private HibernateEntityDao<T,PK> hedao;

private HibernateGenericDao hgdao;



public void setHedao(HibernateEntityDao<T, PK> hedao) {

hedao.setEntityClass(entityClass);

this.hedao = hedao;

}

public void setHgdao(HibernateGenericDao hgdao) {

this.hgdao = hgdao;

}



/**

*让spring提供构造函数注入

*/

public BaseDao(Class<T> type) {

this.entityClass = type;

}



public BaseDao(){}



/**

* 清除所有对象缓存

*/

public void clear() {



hgdao.clear();

}

/**

* 创建Criteria对象.

* @param criterions 可变的Restrictions条件列表

*/

public Criteria createCriteria(Criterion... criterions) {



return hedao.createCriteria(criterions);

}

/**

* 创建Criteria对象,带排序字段与升降序字段.

*/

public Criteria createCriteria(String orderBy, boolean isAsc,

Criterion... criterions) {



return hedao.createCriteria(orderBy, isAsc, criterions);

}

/**

* 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.

* 留意可以连续设置,如下:

* <pre>

* dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();

* </pre>

* 调用方式如下:

* <pre>

* dao.createQuery(hql)

* dao.createQuery(hql,arg0);

* dao.createQuery(hql,arg0,arg1);

* dao.createQuery(hql,new Object[arg0,arg1,arg2])

* </pre>

*

* @param values 可变参数.

*/

public Query createQuery(String hql, Object... values) {



return hgdao.createQuery(hql, values);

}

/**

* @param hql 查询sql

* @param start 分页从哪一条数据开始

* @param pageSize 每一个页面的大小

* @param values 查询条件

* @return page对象

*/

public Page dataQuery(String hql, int start, int pageSize, Object... values) {



return hgdao.dataQuery(hql, start, pageSize, values);

}

/**

* 消除与 Hibernate Session 的关联

* @param entity

*/

public void evit(T entity) {



hedao.evict(entity);

}

/**

* 执行本地sql语句获得标量数值列表

*/

@SuppressWarnings("unchecked")

public List executeNativeSql(String sql) {



return hgdao.executeNativeSql(sql);

}

/**

* 根据hql查询,直接使用HibernateTemplate的find函数.

* @param values 可变参数

*/

@SuppressWarnings("unchecked")

public List find(String hql, Object... values) {



return hgdao.find(hql, values);

}

/**

* 根据属性名和属性值查询对象.

* @return 符合条件的对象列表

*/

public List<T> findBy(String propertyName, Object value) {



return hedao.findBy(propertyName, value);

}

/**

* 根据属性名和属性值查询对象,带排序参数.

*/

public List<T> findBy(String propertyName, Object value, String orderBy,

boolean isAsc) {



return hedao.findBy(propertyName, value, orderBy, isAsc);

}

/**

* 根据属性名和属性值查询唯一对象.

* @return 符合条件的唯一对象 or null if not found.

*/

public T findUniqueBy(String propertyName, Object value) {



return hedao.findUniqueBy(propertyName, value);

}

/**

* 执行一些必须的sql语句把内存中的对象同步到jdbc的链接中

*/

public void flush() {



hgdao.flush();

}



/**

* 根据Serializable类型的id获取实体对象<p/>

* 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.

* @param id

*/

public T get(PK id) {



return hedao.get(id);

}

/**

* 获取实体类型的全部对象

*/

public List<T> getAll() {



return hedao.getAll();

}

/**

* 获取全部对象,带排序字段与升降序参数.

*/

public List<T> getAll(String orderBy, boolean isAsc) {



return hedao.getAll(orderBy, isAsc);

}

/**

* 直接使用spring提供的HibernateTemplate

*/

public HibernateTemplate getHibernateTemplate() {



return hgdao.getHibernateTemplate();

}

/**

* 判断对象某些属性的值在数据库中是否唯一.

*

* @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"

*/

public boolean isUnique(T entity, String uniquePropertyNames) {



return hedao.isUnique(entity, uniquePropertyNames);

}

/**

* 分页查询函数,使用hql.

*

* @param pageNo 页号,从1开始.

*/

public Page pagedQuery(String hql, int pageNo, int pageSize,

Object... values) {



return hgdao.pagedQuery(hql, pageNo, pageSize, values);

}

/**

* 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {



return hedao.pagedQuery(criteria, pageNo, pageSize);

}

/**

* 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions) {



return hedao.pagedQuery(pageNo, pageSize, criterions);

}

/**

* 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(int pageNo, int pageSize, String orderBy,

boolean isAsc, Criterion... criterions) {



return hedao.pagedQuery(pageNo, pageSize, orderBy, isAsc, criterions);

}

/**

* 删除对象.

*/

public void remove(T entity) {



hedao.remove(entity);

}

/**

* 根据ID删除对象.

*/

public void removeById(PK id) {



hedao.removeById(id);

}

/**

* 保存对象.<br>

* 如果对象已在本session中持久化了,不做任何事。<br>

* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>

* 如果没有持久化标识属性,调用save()。<br>

* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>

* 如果是附带版本信息的(<version>或<timestamp>)且版本属性表明为新的实例化对象就save()。<br>

* 否则调用update()重新关联托管对象

*/

public void save(T entity) {

hedao.save(entity);

}



/**

* 在不同的session中关联修改过的托管对象

*/

public void update(T entity){



hedao.update(entity);

}

}

IBase.java

/**

*

*/

package com.hibernate.dao.base;

import java.io.Serializable;

import java.util.List;

import org.hibernate.Criteria;

import org.hibernate.Query;

import org.hibernate.criterion.Criterion;

import org.springframework.orm.hibernate3.HibernateTemplate;

import com.hibernate.dao.generic.HibernateGenericDao;

import com.hibernate.dao.support.Page;

/**

* 提供hibernate dao的所有操作,<br>

* 实现类由spring注入HibernateEntityDao和HibernateGenericDao来实现

*

*/

public interface IBaseDao<T,PK extends Serializable> {



/**

* 获取全部对象

*

* @see HibernateGenericDao#getAll(Class)

*/

public List<T> getAll();



/**

* 获取全部对象,带排序参数.

*/

public List<T> getAll(String orderBy, boolean isAsc);



/**

* 根据ID移除对象.

*/

public void removeById(PK id);



/**

* 取得Entity的Criteria.

*/

public Criteria createCriteria(Criterion... criterions);



/**

* 取得Entity的Criteria,带排序参数.

*/

public Criteria createCriteria(String orderBy, boolean isAsc,

Criterion... criterions);



/**

* 根据属性名和属性值查询对象.

*

* @return 符合条件的对象列表

*/

public List<T> findBy(String propertyName, Object value);



/**

* 根据属性名和属性值查询对象,带排序参数.

*

* @return 符合条件的对象列表

*/

public List<T> findBy(String propertyName, Object value, String orderBy,

boolean isAsc);



/**

* 根据属性名和属性值查询单个对象.

*

* @return 符合条件的唯一对象 or null

*/

public T findUniqueBy(String propertyName, Object value);



/**

* 判断对象某些属性的值在数据库中唯一.

*

* @param uniquePropertyNames

* 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"

* @see HibernateGenericDao#isUnique(Class,Object,String)

*/

public boolean isUnique(T entity, String uniquePropertyNames);



/**

* 消除与 Hibernate Session 的关联

*

*/

public void evit(T entity);





/**

* 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.

*/

public T get(PK id);



/**

* 保存对象.

*/

public void save(T o);



/**

* 删除对象.

*/

public void remove(T o);



public void flush();



public void clear();



/**

* 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.

* 留意可以连续设置,如下:

* <pre>

* dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();

* </pre>

* 调用方式如下:

* <pre>

* dao.createQuery(hql)

* dao.createQuery(hql,arg0);

* dao.createQuery(hql,arg0,arg1);

* dao.createQuery(hql,new Object[arg0,arg1,arg2])

* </pre>

*

* @param values 可变参数.

*/

public Query createQuery(String hql, Object... values);





/**

* 根据hql查询,直接使用HibernateTemplate的find函数.

*/

@SuppressWarnings("unchecked")

public List find(String hql, Object... values);



/**

* 分页查询函数,使用hql.

*

* @param pageNo 页号,从1开始.

*/

public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values);



/**

* @param hql 查询sql

* @param start 分页从哪一条数据开始

* @param pageSize 每一个页面的大小

* @param values 查询条件

* @return page对象

*/

public Page dataQuery(String hql, int start, int pageSize, Object... values);



/**

* 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(Criteria criteria, int pageNo, int pageSize);



/**

* 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions);



/**

* 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(int pageNo, int pageSize, String orderBy, boolean isAsc,

Criterion... criterions);



@SuppressWarnings("unchecked")

public List executeNativeSql(String sql);



public HibernateTemplate getHibernateTemplate();



/**

* 在不同的session中关联修改过的托管对象

*/

public void update(T entity);

}

HibernateEntityDao.java

/**

*

*/

package com.hibernate.dao.extend;

import java.io.Serializable;

import java.lang.reflect.InvocationTargetException;

import java.util.ArrayList;

import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;

import org.hibernate.Criteria;

import org.hibernate.criterion.CriteriaSpecification;

import org.hibernate.criterion.Criterion;

import org.hibernate.criterion.DetachedCriteria;

import org.hibernate.criterion.Order;

import org.hibernate.criterion.Projection;

import org.hibernate.criterion.Projections;

import org.hibernate.criterion.Restrictions;

import org.hibernate.impl.CriteriaImpl;

import org.hibernate.metadata.ClassMetadata;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import org.springframework.util.Assert;

import org.springframework.util.ReflectionUtils;

import com.hibernate.dao.support.BeanUtils;

import com.hibernate.dao.support.Page;

/**

* 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. <p/>

* 子类只要在类定义时指定所管理Entity的Class,

* 即拥有对单个Entity对象的CRUD操作.

*

* @see 继承自spring的HibernateDaoSupport

*/

public class HibernateEntityDao<T,PK extends Serializable> extends HibernateDaoSupport implements IEntityDao<T, PK> {

protected Class<T> entityClass;// DAO所管理的Entity类型.

public void setEntityClass(Class<T> type){

this.entityClass=type;

}

/**

* 在构造函数中将泛型T.class赋给entityClass.

*/

public HibernateEntityDao() {

//entityClass = GenericsUtils.getSuperClassGenricType(getClass());

}

/**

* 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。

*/

protected Class<T> getEntityClass() {

return entityClass;

}



/**

* 根据Serializable类型的id获取实体对象<p/>

* 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.

* @param id

*/

@SuppressWarnings("unchecked")

public T get(PK id) {



return (T) getHibernateTemplate().load(getEntityClass(), id);

}



/**

* 获取实体类型的全部对象

*/

@SuppressWarnings("unchecked")

public List<T> getAll() {

return (List<T>)(getHibernateTemplate().loadAll(getEntityClass()));

}



/**

* 获取全部对象,带排序字段与升降序参数.

*/

@SuppressWarnings("unchecked")

public List<T> getAll(String orderBy, boolean isAsc) {

Assert.hasText(orderBy);

if (isAsc)

return getHibernateTemplate().findByCriteria(

DetachedCriteria.forClass(getEntityClass()).addOrder(Order.asc(orderBy)));

else

return getHibernateTemplate().findByCriteria(

DetachedCriteria.forClass(getEntityClass()).addOrder(Order.desc(orderBy)));

}

/**

* 删除对象.

*/

public void remove(T entity) {

getHibernateTemplate().delete(entity);

}

/**

* 根据ID删除对象.

*/

public void removeById(PK id) {



remove(get(id));

}

/**

* 保存对象.<br>

* 如果对象已在本session中持久化了,不做任何事。<br>

* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>

* 如果没有持久化标识属性,调用save()。<br>

* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>

* 如果是附带版本信息的(<version>或<timestamp>)且版本属性表明为新的实例化对象就save()。<br>

* 否则调用update()重新关联托管对象

*/

public void save(T entity) {

getHibernateTemplate().saveOrUpdate(entity);

}

/**

* 在不同的session中关联修改过的托管对象

*/

public void update(T entity) {

getHibernateTemplate().update(entity);

}



/**

* 消除与 Hibernate Session 的关联

* @param entity

*/

public void evict(T entity) {

getHibernateTemplate().evict(entity);

}



/**

* 创建Criteria对象.

* @param criterions 可变的Restrictions条件列表

*/

public Criteria createCriteria(Criterion... criterions) {

Criteria criteria = getSession().createCriteria(getEntityClass());

for (Criterion c : criterions) {

criteria.add(c);

}

return criteria;

}

/**

* 创建Criteria对象,带排序字段与升降序字段.

*/

public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) {

Assert.hasText(orderBy);

Criteria criteria = createCriteria(criterions);

if (isAsc)

criteria.addOrder(Order.asc(orderBy));

else

criteria.addOrder(Order.desc(orderBy));

return criteria;

}



/**

* 根据属性名和属性值查询对象.

* @return 符合条件的对象列表

*/

@SuppressWarnings("unchecked")

public List<T> findBy(String propertyName, Object value) {

Assert.hasText(propertyName);

return createCriteria(Restrictions.eq(propertyName, value)).list();

}



/**

* 根据属性名和属性值查询对象,带排序参数.

*/

@SuppressWarnings("unchecked")

public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) {

Assert.hasText(propertyName);

Assert.hasText(orderBy);

return createCriteria(orderBy, isAsc, Restrictions.eq(propertyName, value)).list();

}



/**

* 根据属性名和属性值查询唯一对象.

* @return 符合条件的唯一对象 or null if not found.

*/

@SuppressWarnings("unchecked")

public T findUniqueBy(String propertyName, Object value) {

Assert.hasText(propertyName);

return (T) createCriteria(Restrictions.eq(propertyName, value)).uniqueResult();

}



/**

* 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

@SuppressWarnings("unchecked")

public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {

Assert.notNull(criteria);

Assert.isTrue(pageNo >= 1, "pageNo should start from 1");

CriteriaImpl impl = (CriteriaImpl) criteria;

// 先把Projection和OrderBy条件取出来,清空两者来执行Count操作

Projection projection = impl.getProjection();

List<CriteriaImpl.OrderEntry> orderEntries;

try {

orderEntries = (List) BeanUtils.forceGetProperty(impl, "orderEntries");

BeanUtils.forceSetProperty(impl, "orderEntries", new ArrayList());

} catch (Exception e) {

throw new InternalError(" Runtime Exception impossibility throw ");

}

// 执行查询

int totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();

// 将之前的Projection和OrderBy条件重新设回去

criteria.setProjection(projection);

if (projection == null) {

criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);

}

try {

BeanUtils.forceSetProperty(impl, "orderEntries", orderEntries);

} catch (Exception e) {

throw new InternalError(" Runtime Exception impossibility throw ");

}

// 返回分页对象

if (totalCount < 1)

return new Page();

int startIndex = Page.getStartOfPage(pageNo, pageSize);;

List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();

return new Page(startIndex, totalCount, pageSize, list);

}



/**

* 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions) {

Criteria criteria = createCriteria(criterions);

return pagedQuery(criteria, pageNo, pageSize);

}



/**

* 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.

*

* @param pageNo 页号,从1开始.

* @return 含总记录数和当前页数据的Page对象.

*/

public Page pagedQuery(int pageNo, int pageSize, String orderBy, boolean isAsc,

Criterion... criterions) {

Criteria criteria = createCriteria(orderBy, isAsc, criterions);

return pagedQuery(criteria, pageNo, pageSize);

}



/**

* 判断对象某些属性的值在数据库中是否唯一.

*

* @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"

*/

public boolean isUnique(T entity, String uniquePropertyNames) {

Assert.hasText(uniquePropertyNames);

Criteria criteria = createCriteria().setProjection(Projections.rowCount());

String[] nameList = uniquePropertyNames.split(",");

try {

// 循环加入唯一列

for (String name : nameList) {

criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name)));

}

// 以下代码为了如果是update的情况,排除entity自身.

String idName = getIdName(getEntityClass());

// 取得entity的主键值

PK id = getId(getEntityClass(), entity);

// 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断

if (id != null)

criteria.add(Restrictions.not(Restrictions.eq(idName, id)));

} catch (Exception e) {

ReflectionUtils.handleReflectionException(e);

}

return (Integer) criteria.uniqueResult() == 0;

}



/**

* 取得对象的主键值,辅助函数.

*/

@SuppressWarnings("unchecked")

public PK getId(Class<T> entityClass, T entity) throws NoSuchMethodException, IllegalAccessException,

InvocationTargetException {

Assert.notNull(entity);

Assert.notNull(entityClass);

return (PK) PropertyUtils.getProperty(entity, getIdName(entityClass));

}

/**

* 取得对象的主键名,辅助函数.

*/

public String getIdName(Class<T> clazz) {

Assert.notNull(clazz);

ClassMetadata meta = getSessionFactory().getClassMetadata(clazz);

Assert.notNull(meta, "Class " + clazz + " not define in hibernate session factory.");

String idName = meta.getIdentifierPropertyName();

Assert.hasText(idName, clazz.getSimpleName() + " has no identifier property define.");

return idName;

}

}

IEntityDao.java

package com.hibernate.dao.extend;

import java.io.Serializable;

import java.util.List;

/**

* 针对单个Entity对象的CRUD操作定义.

*/

public interface IEntityDao<T,PK extends Serializable> {

T get(PK id);

List<T> getAll();

void save(T entity);

void remove(T entity);

void removeById(PK id);



void update(T entity);

/**

* 获取Entity对象的主键名.

*/

String getIdName(Class<T> clazz);

}

HibernateGenericDao.java

/**

*

*/

package com.hibernate.dao.generic;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import org.hibernate.Query;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import org.springframework.util.Assert;

import com.hibernate.dao.support.Page;

/**

* 继承自spring的HibernateDaoSupport<br>

* 提供了和具体实体类无关的数据库操作,如分页函数和若干便捷查询方法

* @see HibernateDaoSupport

*/

public class HibernateGenericDao extends HibernateDaoSupport {

/**

* 分页查询函数,使用hql.

*

* @param pageNo 页号,从1开始.

*/

@SuppressWarnings("unchecked")

public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) {

Assert.hasText(hql);

Assert.isTrue(pageNo >= 1, "pageNo should start from 1");

// Count查询

String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));

List countlist = getHibernateTemplate().find(countQueryString, values);

long totalCount = (Long) countlist.get(0);

if (totalCount < 1)

return new Page();

// 实际查询返回分页对象

int startIndex = Page.getStartOfPage(pageNo, pageSize);

Query query = createQuery(hql, values);

List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();

return new Page(startIndex, totalCount, pageSize, list);

}



/**

* @param hql 查询sql

* @param start 分页从哪一条数据开始

* @param pageSize 每一个页面的大小

* @param values 查询条件

* @return page对象

*/

@SuppressWarnings("unchecked")

public Page dataQuery(String hql, int start, int pageSize, Object... values){

Assert.hasText(hql);

// Count查询

String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));

List countlist = getHibernateTemplate().find(countQueryString, values);

long totalCount = (Long) countlist.get(0);

if (totalCount < 1)

return new Page();

// 实际查询返回分页对象

int startIndex = start;

Query query = createQuery(hql, values);

List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();

return new Page(startIndex, totalCount, pageSize, list);

}



/**

* 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.

* 留意可以连续设置,如下:

* <pre>

* dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();

* </pre>

* 调用方式如下:

* <pre>

* dao.createQuery(hql)

* dao.createQuery(hql,arg0);

* dao.createQuery(hql,arg0,arg1);

* dao.createQuery(hql,new Object[arg0,arg1,arg2])

* </pre>

*

* @param values 可变参数.

*/

public Query createQuery(String hql, Object... values) {

Assert.hasText(hql);

Query query = getSession().createQuery(hql);

for (int i = 0; i < values.length; i++) {

query.setParameter(i, values[i]);

}

return query;

}



/**

* 根据hql查询,直接使用HibernateTemplate的find函数.

* @param values 可变参数

*/

@SuppressWarnings("unchecked")

public List find(String hql, Object... values) {

Assert.hasText(hql);

return getHibernateTemplate().find(hql, values);

}





/**

* 执行一些必须的sql语句把内存中的对象同步到jdbc的链接中

*/

public void flush() {

getHibernateTemplate().flush();

}



/**

* 清除所有对象缓存

*/

public void clear() {

getHibernateTemplate().clear();

}



/**

* 执行本地sql语句获得标量数值列表

*/

@SuppressWarnings("unchecked")

public List executeNativeSql(String sql){

return getSession().createSQLQuery(sql).list();

}

/**

* 去除hql的select 子句,未考虑union的情况,用于pagedQuery.

*/

private static String removeSelect(String hql) {

Assert.hasText(hql);

int beginPos = hql.toLowerCase().indexOf("from");

Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");

return hql.substring(beginPos);

}



/**

* 去除hql的orderby 子句,用于pagedQuery.

*/

private static String removeOrders(String hql) {

Assert.hasText(hql);

Pattern p = Pattern.compile("order//s*by[//w|//W|//s|//S]*", Pattern.CASE_INSENSITIVE);

Matcher m = p.matcher(hql);

StringBuffer sb = new StringBuffer();

while (m.find()) {

m.appendReplacement(sb, "");

}

m.appendTail(sb);

return sb.toString();

}

}

com.hibernate.dao.support下的3个类和如下的一致:
http://blog.csdn.net/tom_221x/archive/2008/12/05/3453312.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: