一个好用的hibernate泛型dao 收藏 以前从springside2.0上搞下来的很好用的,基本实现dao零编码只要配置xml文件就行了。
先看图:
一共4层,com.demonstration.hibernate.basedao是我加的用来进一步解耦hibernate和spring的耦合。 原来的官方解释如下: SpringSide对Hibernate做了三层封装:
第一层:HibernateGenericDao,基于spring的HibernateDaoSupport,但加入了分页函数与各种Finder函数,并使用泛型避免了返回值强制类型转换。
第二层:HibernateEntityDao,基于HibernateGenericDao,用泛型声明Dao所管理的Entity类,默认拥有该entity的CRUD方法。
第三层:HibernateExtendDao,基于HibernateEntityDao,主要扩展各种选择性的功能。
关于三个类的详细注解请看JavaDoc,大致描述如下:
1 HibernateGenericDao 在Spring HibernateDaoSupport基础上封装的DAO,功能如下:
1.应用泛型:使得find(), get() 这些函数不再返回Object,而是返回T,不再需要强制类型转换。
2.提供各种finder的简便函数 应用了JDK5可变参数的hsql查询函数:List find(String hql, Object... values),支持find(hql),find(hql, param1); find(hql,param1,param2);find(hql,new Object[] {param1,param2}) 四种接口。
简单查询的简化函数:findBy(Class entityClass,String name,Object value) ,findUniqueBy(Class entityClass,String name, Object value),findByLike(Class entityClass,String name,Object value)
3.获得设置好的Query和Criteria:createQuery(String hql,Object... values) 和 createCriteria(Class<T> entityClass,Criterion... criterions)
Spring并没有很好的接口封装支持firstResult, maxResult, fetchsize,cache,cacheRegion 等多个查询参数,所以springside宁愿返回已设置好查询条件的Query和Criteria,让大家继续剩下的参数设置,最后再执行 list(),注意那几个参数可以连续设置的,如:
createQuery(hql,param1).setFirstResult(10).setMaxResult(20).list(); 4.分页函数:Page pagedQuery(Criteria criteria, int pageNo, int pageSize) 和Page pagedQuery(String hql, int pageNo, int pageSize, Object... args)
Page是SpringSide自行封装的一个典型Page类,pagedQuery与hibernate自身分页查询的差别是先运行一次count,获得符合条件的总记录数。
如果查询不需要总记录数,用普通的hibernate API,加上setFirstResult(),setMaxResult()就解决,不需要pagedQuery()。
5.判别对象属性在数据库中唯一的函数:isUnique(Class<T> entityClass,Object entity,String names)。
2. HibernateEntityDao 所有UserManager, ProductManager之类只管理一类对象的Manager类的基类,只需要在类定义处声明Entity类型即可
public class BookManager extends HibernateEntityDao<Book> { } 通过<Book>的定义,避免了HibernateGenericDao类各方法中必有的Class entityClass参数。
如果需要操作其他的Entity,比如BookManager可能需要处理Category(图书目录),可以注入CategoryManager。无需担心事务的问题,JavaEE的默认事务模型已能很好处理。
如果没有对应的CategoryManager,或者各种原因不想注入的话,可以使用BookManager继承自 HibernateGenericDao的带entityClass参数的函数来操作Category的增删改,如Category category= this.get(Category.class, 1);
3. HibernateExtendDao 此类演示SpringSide 所作的一些扩展,大家可以按照自己的需要进行修改和扩展。
1. 支持对象不能被直接删除,只能设置状态列为无效。 接口UndeleteableEntityOperation,定义了要支持此功能必须实现的函数。
可以有接口(UndeletableEntity)和annotation(@Undeletable)两种形式来定义无效列,annotation列形式还可以定义标识对象已删除的状态属性的名称,用接口则必须实现setStatus()接口,在里面操作实际的状态属性。
第四层就是把HibernateEntityDao和HibernateExtendDao以属性注入的方式注入到basedao,IBasedao就全局接口程序中使用的就是它,这个接口的实现全调用HibernateEntityDao和HibernateExtendDao的方法。方便以后的更改和替换,这样IBasedao接口不变就不要修改业务层的代码了。
代码如下(从下到上):
Page.java
package com.demonstration.hibernate.dao.support;
import java.io.Serializable; import java.util.ArrayList; /** * 分页对象. 包含当前页数据及分页信息如总记录数. * * @author springside * */ @SuppressWarnings("serial") public class Page implements Serializable {
private static int DEFAULT_PAGE_SIZE = 20;
private int pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数
private long start; // 当前页第一条数据在List中的位置,从0开始
private Object data; // 当前页中存放的记录,类型一般为List
private long totalCount; // 总记录数
/** * 构造方法,只构造空页. */ @SuppressWarnings("unchecked") public Page() { this(0, 0, DEFAULT_PAGE_SIZE, new ArrayList()); }
/** * 默认构造方法. * * @param start 本页数据在数据库中的起始位置 * @param totalSize 数据库中总记录条数 * @param pageSize 本页容量 * @param data 本页包含的数据 */ public Page(long start, long totalSize, int pageSize, Object data) { this.pageSize = pageSize; this.start = start; this.totalCount = totalSize; this.data = data; }
/** * 取总记录数. */ public long getTotalCount() { return this.totalCount; }
/** * 取总页数. */ public long getTotalPageCount() { if (totalCount % pageSize == 0) return totalCount / pageSize; else return totalCount / pageSize + 1; }
/** * 取每页数据容量. */ public int getPageSize() { return pageSize; }
/** * 取当前页中的记录. */ public Object getResult() { return data; }
/** * 取该页当前页码,页码从1开始. */ public long getCurrentPageNo() { return start / pageSize + 1; }
/** * 该页是否有下一页. */ public boolean hasNextPage() { return this.getCurrentPageNo() < this.getTotalPageCount() - 1; }
/** * 该页是否有上一页. */ public boolean hasPreviousPage() { return this.getCurrentPageNo() > 1; }
/** * 获取任一页第一条数据在数据集的位置,每页条数使用默认值. * * @see #getStartOfPage(int,int) */ protected static int getStartOfPage(int pageNo) { return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE); }
/** * 获取任一页第一条数据在数据集的位置. * * @param pageNo 从1开始的页号 * @param pageSize 每页记录条数 * @return 该页第一条数据 */ public static int getStartOfPage(int pageNo, int pageSize) { return (pageNo - 1) * pageSize; } } GenericsUtils.java
package com.demonstration.hibernate.dao.support;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
/** * Generics的util类. * * @author springside * */ public class GenericsUtils { private static final Log log = LogFactory.getLog(GenericsUtils.class);
private GenericsUtils() { }
/** * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book> * * @param clazz The class to introspect * @return the first generic declaration, or <code>Object.class</code> if cannot be determined */ @SuppressWarnings("unchecked") public static Class getSuperClassGenricType(Class clazz) { return getSuperClassGenricType(clazz, 0); }
/** * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book> * * @param clazz clazz The class to introspect * @param index the Index of the generic ddeclaration,start from 0. * @return the index generic declaration, or <code>Object.class</code> if cannot be determined */ @SuppressWarnings("unchecked") public static Class getSuperClassGenricType(Class clazz, int index) {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) { log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); return Object.class; }
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) { log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); return Object.class; } return (Class) params[index]; } }
BeanUtils.java
package com.demonstration.hibernate.dao.support;
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils;
/** * 扩展Apache Commons BeanUtils, 提供一些反射方面缺失功能的封装. * @author springside * */ public class BeanUtils extends org.apache.commons.beanutils.BeanUtils {
protected static final Log logger = LogFactory.getLog(BeanUtils.class);
private BeanUtils() { }
/** * 循环向上转型,获取对象的DeclaredField. * * @throws NoSuchFieldException 如果没有该Field时抛出. */ public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException { Assert.notNull(object); Assert.hasText(propertyName); return getDeclaredField(object.getClass(), propertyName); }
/** * 循环向上转型,获取对象的DeclaredField. * * @throws NoSuchFieldException 如果没有该Field时抛出. */ @SuppressWarnings("unchecked") public static Field getDeclaredField(Class clazz, String propertyName) throws NoSuchFieldException { Assert.notNull(clazz); Assert.hasText(propertyName); for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) { try { return superClass.getDeclaredField(propertyName); } catch (NoSuchFieldException e) { // Field不在当前类定义,继续向上转型 } } throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName); }
/** * 暴力获取对象变量值,忽略private,protected修饰符的限制. * * @throws NoSuchFieldException 如果没有该Field时抛出. */ public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException { Assert.notNull(object); Assert.hasText(propertyName);
Field field = getDeclaredField(object, propertyName);
boolean accessible = field.isAccessible(); field.setAccessible(true);
Object result = null; try { result = field.get(object); } catch (IllegalAccessException e) { logger.info("error wont' happen"); } field.setAccessible(accessible); return result; }
/** * 暴力设置对象变量值,忽略private,protected修饰符的限制. * * @throws NoSuchFieldException 如果没有该Field时抛出. */ public static void forceSetProperty(Object object, String propertyName, Object newValue) throws NoSuchFieldException { Assert.notNull(object); Assert.hasText(propertyName);
Field field = getDeclaredField(object, propertyName); boolean accessible = field.isAccessible(); field.setAccessible(true); try { field.set(object, newValue); } catch (IllegalAccessException e) { logger.info("Error won't happen"); } field.setAccessible(accessible); }
/** * 暴力调用对象函数,忽略private,protected修饰符的限制. * * @throws NoSuchMethodException 如果没有该Method时抛出. */ @SuppressWarnings("unchecked") public static Object invokePrivateMethod(Object object, String methodName, Object... params) throws NoSuchMethodException { Assert.notNull(object); Assert.hasText(methodName); Class[] types = new Class[params.length]; for (int i = 0; i < params.length; i++) { types[i] = params[i].getClass(); }
Class clazz = object.getClass(); Method method = null; for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) { try { method = superClass.getDeclaredMethod(methodName, types); break; } catch (NoSuchMethodException e) { // 方法不在当前类定义,继续向上转型 } }
if (method == null) throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + methodName);
boolean accessible = method.isAccessible(); method.setAccessible(true); Object result = null; try { result = method.invoke(object, params); } catch (Exception e) { ReflectionUtils.handleReflectionException(e); } method.setAccessible(accessible); return result; }
/** * 按Filed的类型取得Field列表. */ @SuppressWarnings("unchecked") public static List<Field> getFieldsByType(Object object, Class type) { List<Field> list = new ArrayList<Field>(); Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { if (field.getType().isAssignableFrom(type)) { list.add(field); } } return list; }
/** * 按FiledName获得Field的类型. */ @SuppressWarnings("unchecked") public static Class getPropertyType(Class type, String name) throws NoSuchFieldException { return getDeclaredField(type, name).getType(); }
/** * 获得field的getter函数名称. */ @SuppressWarnings("unchecked") public static String getGetterName(Class type, String fieldName) { Assert.notNull(type, "Type required"); Assert.hasText(fieldName, "FieldName required");
if (type.getName().equals("boolean")) { return "is" + StringUtils.capitalize(fieldName); } else { return "get" + StringUtils.capitalize(fieldName); } }
/** * 获得field的getter函数,如果找不到该方法,返回null. */ @SuppressWarnings("unchecked") public static Method getGetterMethod(Class type, String fieldName) { try { return type.getMethod(getGetterName(type, fieldName)); } catch (NoSuchMethodException e) { logger.error(e.getMessage(), e); } return null; } }
IUndeleteableEntityOperation.java
package com.demonstration.hibernate.dao.extend;
import java.util.List;
import org.hibernate.criterion.Criterion;
/** * 定义如果支持Entity不被直接删除必须支持的Operation. * * @author springside * */ public interface IUndeleteableEntityOperation<T> { /* * Undelete Entity用到的几个常量,因为要同时兼顾Interface与Annotation,所以集中放此. */ String UNVALID_VALUE = "-1";
String NORMAL_VALUE = "0";
String STATUS = "status";
/** * 取得所有状态为有效的对象. */ List<T> getAllValid();
/** * 删除对象,但如果是Undeleteable的entity,设置对象的状态而不是直接删除. */ void remove(Object entity);
/** * 获取过滤已删除对象的hql条件语句. */ String getUnDeletableHQL(); /** * 获取过滤已删除对象的Criterion条件语句. */ Criterion getUnDeletableCriterion(); }
IUndeletableEntity.java
package com.demonstration.hibernate.dao.extend;
/** * 标识商业对象不能被删除,只能被设为无效的接口. * * @author springside * */ public interface IUndeletableEntity { void setStatus(String status); }
IUndeletable.java
package com.demonstration.hibernate.dao.extend;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
/** * 标识商业对象不能被删除,只能被设为无效的Annoation. * <p/> * 相比inferface的标示方式,annotation 方式更少侵入性,可以定义任意属性代表status,而默认为status属性. */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface IUndeletable { String status() default IUndeleteableEntityOperation.STATUS; }
HibernateEntityExtendDao.java
package com.demonstration.hibernate.dao.extend;
import java.util.List; import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils; import org.hibernate.Criteria; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Restrictions; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils;
import com.demonstration.hibernate.dao.HibernateEntityDao;
/** * 加强版的entity dao. * <p>自动处理Undeletable Entity.<br> * Undeletable Entity 在删除时只把状态设为无效,不会真正执行删除.<br> * Undeletable Entity 可以通过annotation或接口两种形式来声明.<br> * 其中annotation模式不限制状态列的属性名必须为"status",可以用注释来确定任意属性为状态属性.<br> * </p> * * @author springside * * @see HibernateEntityDao * @see EntityInfo * @see IUndeleteableEntityOperation * @see IUndeletable * @see IUndeletableEntity */ @SuppressWarnings("unchecked") public class HibernateEntityExtendDao<T> extends HibernateEntityDao<T> implements IUndeleteableEntityOperation<T> { /** * 保存所管理的Entity的信息. */ protected EntityInfo entityInfo;
/** * 构造函数,初始化entity信息. */ public HibernateEntityExtendDao() { entityInfo = new EntityInfo(entityClass); }
/** * 取得所有状态为有效的对象. * * @see IUndeleteableEntityOperation#getAllValid() */ public List<T> getAllValid() { Criteria criteria = createCriteria(); if (entityInfo.isUndeletable) criteria.add(getUnDeletableCriterion()); return criteria.list(); }
/** * 获取过滤已删除对象的hql条件语句. * * @see IUndeleteableEntityOperation#getUnDeletableHQL() */ public String getUnDeletableHQL() { return entityInfo.statusProperty + "<>" + UNVALID_VALUE; }
/** * 获取过滤已删除对象的Criterion条件语句. * * @see UndeleteableEntityOperation# */ public Criterion getUnDeletableCriterion() { return Restrictions.not(Restrictions.eq(entityInfo.statusProperty, UNVALID_VALUE)); }
/** * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验. * * @see #onValid(Object) * @see HibernateEntityDao#save(Object) */ @Override public void save(Object entity) { Assert.isInstanceOf(getEntityClass(), entity); onValid((T) entity); super.save(entity); }
/** * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除. * * @see HibernateEntityDao#remove(Object) */ @Override public void remove(Object entity) { if (entityInfo.isUndeletable) { try { PropertyUtils.setProperty(entity, entityInfo.statusProperty, UNVALID_VALUE); save(entity); } catch (Exception e) { ReflectionUtils.handleReflectionException(e); } } else super.remove(entity); }
/** * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载. * * @see #save(Object) */ public void onValid(T entity) { }
/** * 根据Map中的条件的Criteria查询. * * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。 */ public List<T> find(Map map) { Criteria criteria = createCriteria(); return find(criteria, map); }
/** * 根据Map中的条件的Criteria查询. * * @param map Map中仅包含条件名与条件值,默认全部相同,可重载. */ public List<T> find(Criteria criteria, Map map) { Assert.notNull(criteria); criteria.add(Restrictions.allEq(map)); return criteria.list(); } }
EntityInfo.java package com.demonstration.hibernate.dao.extend;
/** * 装载Entity信息的内部类. * * @author springside * */ class EntityInfo { boolean isUndeletable = false; // entity是否undeleteable的标志
String statusProperty; // 标识状态的属性名
@SuppressWarnings("unchecked") public EntityInfo(Class entityClass) { init(entityClass); }
/** * 初始函数,判断EntityClass是否UndeletableEntity. */ @SuppressWarnings("unchecked") private void init(Class entityClass) { // 通过EntityClass的interface判断entity是否undeletable if (IUndeletableEntity.class.isAssignableFrom(entityClass)) { isUndeletable = true; statusProperty = IUndeleteableEntityOperation.STATUS; }
// 通过EntityClass的annotation判断entity是否undeletable if (entityClass.isAnnotationPresent(IUndeletable.class)) { isUndeletable = true; IUndeletable anno = (IUndeletable) entityClass.getAnnotation(IUndeletable.class); statusProperty = anno.status(); } } }
IEntityDao.java package com.demonstration.hibernate.dao;
import java.io.Serializable; import java.util.List;
/** * 针对单个Entity对象的操作定义.不依赖于具体ORM实现方案. * * @author springside * */ public interface IEntityDao<T> {
T get(Serializable id);
List<T> getAll();
void save(Object o);
void remove(Object o);
void removeById(Serializable id);
/** * 获取Entity对象的主键名. */ @SuppressWarnings("unchecked") String getIdName(Class clazz); }
HibernateGenericDao.java package com.demonstration.hibernate.dao;
import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;
import org.apache.commons.beanutils.PropertyUtils; import org.hibernate.Criteria; import org.hibernate.Query; 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.demonstration.hibernate.dao.support.BeanUtils; import com.demonstration.hibernate.dao.support.Page;
/** * Hibernate Dao的泛型基类. * <p/> * 继承于Spring的<code>HibernateDaoSupport</code>,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换. * * @author springside * * @see HibernateDaoSupport * @see HibernateEntityDao */ @SuppressWarnings("unchecked") public class HibernateGenericDao extends HibernateDaoSupport { /** * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常. */ public <T> T get(Class<T> entityClass, Serializable id) { return (T) getHibernateTemplate().load(entityClass, id); }
/** * 获取全部对象. */ public <T> List<T> getAll(Class<T> entityClass) { return getHibernateTemplate().loadAll(entityClass); }
/** * 获取全部对象,带排序字段与升降序参数. */ public <T> List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) { Assert.hasText(orderBy); if (isAsc) return getHibernateTemplate().findByCriteria( DetachedCriteria.forClass(entityClass).addOrder(Order.asc(orderBy))); else return getHibernateTemplate().findByCriteria( DetachedCriteria.forClass(entityClass).addOrder(Order.desc(orderBy))); }
/** * 保存对象. */ public void save(Object o) { getHibernateTemplate().saveOrUpdate(o); }
/** * 删除对象. */ public void remove(Object o) { getHibernateTemplate().delete(o); }
/** * 根据ID删除对象. */ public <T> void removeById(Class<T> entityClass, Serializable id) { remove(get(entityClass, id)); }
public void flush() { getHibernateTemplate().flush(); }
public void clear() { getHibernateTemplate().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) { Assert.hasText(hql); Query query = getSession().createQuery(hql); for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } return query; }
/** * 创建Criteria对象. * * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)} */ public <T> Criteria createCriteria(Class<T> entityClass, Criterion... criterions) { Criteria criteria = getSession().createCriteria(entityClass); for (Criterion c : criterions) { criteria.add(c); } return criteria; }
/** * 创建Criteria对象,带排序字段与升降序字段. * * @see #createCriteria(Class,Criterion[]) */ public <T> Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions) { Assert.hasText(orderBy);
Criteria criteria = createCriteria(entityClass, criterions);
if (isAsc) criteria.addOrder(Order.asc(orderBy)); else criteria.addOrder(Order.desc(orderBy));
return criteria; }
/** * 根据hql查询,直接使用HibernateTemplate的find函数. * * @param values 可变参数,见{@link #createQuery(String,Object...)} */ public List find(String hql, Object... values) { Assert.hasText(hql); return getHibernateTemplate().find(hql, values); }
/** * 根据属性名和属性值查询对象. * * @return 符合条件的对象列表 */ public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value) { Assert.hasText(propertyName); return createCriteria(entityClass, Restrictions.eq(propertyName, value)).list(); }
/** * 根据属性名和属性值查询对象,带排序参数. */ public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc) { Assert.hasText(propertyName); Assert.hasText(orderBy); return createCriteria(entityClass, orderBy, isAsc, Restrictions.eq(propertyName, value)).list(); }
/** * 根据属性名和属性值查询唯一对象. * * @return 符合条件的唯一对象 or null if not found. */ public <T> T findUniqueBy(Class<T> entityClass, String propertyName, Object value) { Assert.hasText(propertyName); return (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult(); }
/** * 分页查询函数,使用hql. * * @param pageNo 页号,从1开始. */ 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); } /** * @author Scott.wanglei * @since 2008-7-21 * @param hql 查询sql * @param start 分页从哪一条数据开始 * @param pageSize 每一个页面的大小 * @param values 查询条件 * @return page对象 */ public Page dataQuery(String hql, int start, int pageSize, Object... values){ // 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); } /** * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>. * * @param pageNo 页号,从1开始. * @return 含总记录数和当前页数据的Page对象. */ 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(Class entityClass, int pageNo, int pageSize, Criterion... criterions) { Criteria criteria = createCriteria(entityClass, criterions); return pagedQuery(criteria, pageNo, pageSize); }
/** * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>. * * @param pageNo 页号,从1开始. * @return 含总记录数和当前页数据的Page对象. */ public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc, Criterion... criterions) { Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions); return pagedQuery(criteria, pageNo, pageSize); }
/** * 判断对象某些属性的值在数据库中是否唯一. * * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" */ public <T> boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames) { Assert.hasText(uniquePropertyNames); Criteria criteria = createCriteria(entityClass).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(entityClass);
// 取得entity的主键值 Serializable id = getId(entityClass, 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; }
/** * 取得对象的主键值,辅助函数. */ public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Assert.notNull(entity); Assert.notNull(entityClass); return (Serializable) PropertyUtils.getProperty(entity, getIdName(entityClass)); }
/** * 取得对象的主键名,辅助函数. */ public String getIdName(Class 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; }
/** * 去除hql的select 子句,未考虑union的情况,用于pagedQuery. * * @see #pagedQuery(String,int,int,Object[]) */ 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. * * @see #pagedQuery(String,int,int,Object[]) */ 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(); } } HibernateEntityDao.java package com.demonstration.hibernate.dao;
import java.io.Serializable; import java.util.List; import org.hibernate.Criteria; import org.hibernate.criterion.Criterion;
import com.demonstration.hibernate.dao.support.GenericsUtils;
/** * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. <p/> 子类只要在类定义时指定所管理Entity的Class, * 即拥有对单个Entity对象的CRUD操作. * * <pre> * public class UserManager extends HibernateEntityDao<User> { * } * </pre> * * @author springside * * @see HibernateGenericDao */ @SuppressWarnings("unchecked") public class HibernateEntityDao<T> extends HibernateGenericDao implements IEntityDao<T> {
protected Class<T> entityClass;// DAO所管理的Entity类型.
/** * 在构造函数中将泛型T.class赋给entityClass. */ public HibernateEntityDao() { entityClass = GenericsUtils.getSuperClassGenricType(getClass()); }
/** * 重载构造函数 让spring提供构造函数注入 */ public HibernateEntityDao(Class<T> type) { this.entityClass = type; } /** * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。 */ protected Class<T> getEntityClass() { return entityClass; } public void setEntityClass(Class<T> type){ this.entityClass=type; }
/** * 根据ID获取对象. * * @see HibernateGenericDao#getId(Class,Object) */ public T get(Serializable id) { return get(getEntityClass(), id); }
/** * 获取全部对象 * * @see HibernateGenericDao#getAll(Class) */ public List<T> getAll() { return getAll(getEntityClass()); }
/** * 获取全部对象,带排序参数. * * @see HibernateGenericDao#getAll(Class,String,boolean) */ public List<T> getAll(String orderBy, boolean isAsc) { return getAll(getEntityClass(), orderBy, isAsc); }
/** * 根据ID移除对象. * * @see HibernateGenericDao#removeById(Class,Serializable) */ public void removeById(Serializable id) { removeById(getEntityClass(), id); }
/** * 取得Entity的Criteria. * * @see HibernateGenericDao#createCriteria(Class,Criterion[]) */ public Criteria createCriteria(Criterion... criterions) { return createCriteria(getEntityClass(), criterions); }
/** * 取得Entity的Criteria,带排序参数. * * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[]) */ public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) { return createCriteria(getEntityClass(), orderBy, isAsc, criterions); }
/** * 根据属性名和属性值查询对象. * * @return 符合条件的对象列表 * @see HibernateGenericDao#findBy(Class,String,Object) */ public List<T> findBy(String propertyName, Object value) { return findBy(getEntityClass(), propertyName, value); }
/** * 根据属性名和属性值查询对象,带排序参数. * * @return 符合条件的对象列表 * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean) */ public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) { return findBy(getEntityClass(), propertyName, value, orderBy, isAsc); }
/** * 根据属性名和属性值查询单个对象. * * @return 符合条件的唯一对象 or null * @see HibernateGenericDao#findUniqueBy(Class,String,Object) */ public T findUniqueBy(String propertyName, Object value) { return findUniqueBy(getEntityClass(), propertyName, value); }
/** * 判断对象某些属性的值在数据库中唯一. * * @param uniquePropertyNames * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" * @see HibernateGenericDao#isUnique(Class,Object,String) */ public boolean isUnique(Object entity, String uniquePropertyNames) { return isUnique(getEntityClass(), entity, uniquePropertyNames); }
/** * 消除与 Hibernate Session 的关联 * * @param entity */ public void evit(Object entity) { getHibernateTemplate().evict(entity); } }
IBaseDao.java /** * */ package com.demonstration.hibernate.basedao;
import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map;
import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.criterion.Criterion;
import com.demonstration.hibernate.dao.HibernateEntityDao; import com.demonstration.hibernate.dao.HibernateGenericDao; import com.demonstration.hibernate.dao.extend.IUndeleteableEntityOperation; import com.demonstration.hibernate.dao.support.Page;
/** * @author * * 提供hibernate dao的所有操作, * 实现类由spring注入HibernateEntityDao和HibernateEntityExtendDao来实现 * 最大限度的解耦hibernate持久层的操作 */ public interface IBaseDao<T> {
/** * 根据ID获取对象. * * @see HibernateGenericDao#getId(Class,Object) */ public T get(Serializable id); /** * 获取全部对象 * * @see HibernateGenericDao#getAll(Class) */ public List<T> getAll(); /** * 获取全部对象,带排序参数. * * @see HibernateGenericDao#getAll(Class,String,boolean) */ public List<T> getAll(String orderBy, boolean isAsc); /** * 根据ID移除对象. * * @see HibernateGenericDao#removeById(Class,Serializable) */ public void removeById(Serializable id); /** * 取得Entity的Criteria. * * @see HibernateGenericDao#createCriteria(Class,Criterion[]) */ public Criteria createCriteria(Criterion... criterions); /** * 取得Entity的Criteria,带排序参数. * * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[]) */ public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions); /** * 根据属性名和属性值查询对象. * * @return 符合条件的对象列表 * @see HibernateGenericDao#findBy(Class,String,Object) */ public List<T> findBy(String propertyName, Object value); /** * 根据属性名和属性值查询对象,带排序参数. * * @return 符合条件的对象列表 * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean) */ public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc); /** * 根据属性名和属性值查询单个对象. * * @return 符合条件的唯一对象 or null * @see HibernateGenericDao#findUniqueBy(Class,String,Object) */ public T findUniqueBy(String propertyName, Object value); /** * 判断对象某些属性的值在数据库中唯一. * * @param uniquePropertyNames * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" * @see HibernateGenericDao#isUnique(Class,Object,String) */ public boolean isUnique(Object entity, String uniquePropertyNames); /** * 消除与 Hibernate Session 的关联 * * @param entity */ public void evit(Object entity); /*******************************************************************************************/ /** * 取得所有状态为有效的对象. * * @see IUndeleteableEntityOperation#getAllValid() */ public List<T> getAllValid(); /** * 获取过滤已删除对象的hql条件语句. * * @see IUndeleteableEntityOperation#getUnDeletableHQL() */ public String getUnDeletableHQL(); /** * 获取过滤已删除对象的Criterion条件语句. * * @see UndeleteableEntityOperation# */ public Criterion getUnDeletableCriterion(); /** * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验. * * @see #onValid(Object) * @see HibernateEntityDao#save(Object) */ public void saveOnValid(Object entity); /** * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除. * * @see HibernateEntityDao#remove(Object) */ public void removeUndeleteable(Object entity); /** * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载. * * @see #save(Object) */ public void onValid(T entity); /** * 根据Map中的条件的Criteria查询. * * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。 */ @SuppressWarnings("unchecked") public List<T> find(Map map); /** * 根据Map中的条件的Criteria查询. * * @param map Map中仅包含条件名与条件值,默认全部相同,可重载. */ @SuppressWarnings("unchecked") public List<T> find(Criteria criteria, Map map); /*******************************************************************************************/ /** * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常. */ public T get(Class<T> entityClass, Serializable id); /** * 获取全部对象. */ public List<T> getAll(Class<T> entityClass); /** * 获取全部对象,带排序字段与升降序参数. */ public List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc); /** * 保存对象. */ public void save(Object o); /** * 删除对象. */ public void remove(Object 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); /** * 创建Criteria对象. * * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)} */ public Criteria createCriteria(Class<T> entityClass, Criterion... criterions); /** * 创建Criteria对象,带排序字段与升降序字段. * * @see #createCriteria(Class,Criterion[]) */ public Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions); /** * 根据hql查询,直接使用HibernateTemplate的find函数. * * @param values 可变参数,见{@link #createQuery(String,Object...)} */ @SuppressWarnings("unchecked") public List find(String hql, Object... values); /** * 根据属性名和属性值查询对象. * * @return 符合条件的对象列表 */ public List<T> findBy(Class<T> entityClass, String propertyName, Object value); /** * 根据属性名和属性值查询对象,带排序参数. */ public List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc); /** * 根据属性名和属性值查询唯一对象. * * @return 符合条件的唯一对象 or null if not found. */ public T findUniqueBy(Class<T> entityClass, String propertyName, Object value); /** * 分页查询函数,使用hql. * * @param pageNo 页号,从1开始. */ public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values); /** * @author Scott.wanglei * @since 2008-7-21 * @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对象. */ @SuppressWarnings("unchecked") public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions); /** * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>. * * @param pageNo 页号,从1开始. * @return 含总记录数和当前页数据的Page对象. */ @SuppressWarnings("unchecked") public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc, Criterion... criterions); /** * 判断对象某些属性的值在数据库中是否唯一. * * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" */ public boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames); /** * 取得对象的主键值,辅助函数. */ @SuppressWarnings("unchecked") public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException ; /** * 取得对象的主键名,辅助函数. */ @SuppressWarnings("unchecked") public String getIdName(Class clazz); }
BaseDao.java /** * */ package com.demonstration.hibernate.basedao;
import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map;
import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.criterion.Criterion;
import com.demonstration.hibernate.dao.HibernateEntityDao; import com.demonstration.hibernate.dao.HibernateGenericDao; import com.demonstration.hibernate.dao.extend.HibernateEntityExtendDao; import com.demonstration.hibernate.dao.extend.IUndeleteableEntityOperation; import com.demonstration.hibernate.dao.support.Page;
/** * @author * * IBaseDao的实现类通过spring注入HibernateEntityDao和HibernateEntityExtendDao来实现 */ public class BaseDao<T> implements IBaseDao<T> {
protected Class<T> entityClass;// DAO所管理的Entity类型. private HibernateEntityDao<T> hedao; private HibernateEntityExtendDao<T> hexdao; public void setHedao(HibernateEntityDao<T> hedao) { hedao.setEntityClass(entityClass); this.hedao=hedao; }
public void setHexdao(HibernateEntityExtendDao<T> hexdao) { hexdao.setEntityClass(entityClass); this.hexdao=hexdao; } /** *让spring提供构造函数注入 */ public BaseDao(Class<T> type) { this.entityClass = type; } public BaseDao(){} /** * 根据ID获取对象. * * @see HibernateGenericDao#getId(Class,Object) */ public T get(Serializable id) { return hedao.get(id); }
/** * 获取全部对象 * * @see HibernateGenericDao#getAll(Class) */ public List<T> getAll() { return hedao.getAll(); }
/** * 获取全部对象,带排序参数. * * @see HibernateGenericDao#getAll(Class,String,boolean) */ public List<T> getAll(String orderBy, boolean isAsc) { return hedao.getAll(orderBy, isAsc); }
/** * 根据ID移除对象. * * @see HibernateGenericDao#removeById(Class,Serializable) */ public void removeById(Serializable id) { hedao.removeById(id); }
/** * 取得Entity的Criteria. * * @see HibernateGenericDao#createCriteria(Class,Criterion[]) */ public Criteria createCriteria(Criterion... criterions) { return hedao.createCriteria(criterions); }
/** * 取得Entity的Criteria,带排序参数. * * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[]) */ public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) { return hedao.createCriteria(orderBy, isAsc, criterions); }
/** * 根据属性名和属性值查询对象. * * @return 符合条件的对象列表 * @see HibernateGenericDao#findBy(Class,String,Object) */ public List<T> findBy(String propertyName, Object value) { return hedao.findBy(propertyName, value); }
/** * 根据属性名和属性值查询对象,带排序参数. * * @return 符合条件的对象列表 * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean) */ public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) { return hedao.findBy(propertyName, value, orderBy, isAsc); }
/** * 根据属性名和属性值查询单个对象. * * @return 符合条件的唯一对象 or null * @see HibernateGenericDao#findUniqueBy(Class,String,Object) */ public T findUniqueBy(String propertyName, Object value) { return hedao.findUniqueBy(propertyName, value); }
/** * 判断对象某些属性的值在数据库中唯一. * * @param uniquePropertyNames * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" * @see HibernateGenericDao#isUnique(Class,Object,String) */ public boolean isUnique(Object entity, String uniquePropertyNames) { return hedao.isUnique(entity, uniquePropertyNames); }
/** * 消除与 Hibernate Session 的关联 * * @param entity */ public void evit(Object entity) { hedao.evit(entity); }
/** * 取得所有状态为有效的对象. * * @see IUndeleteableEntityOperation#getAllValid() */ public List<T> getAllValid() { return hexdao.getAllValid(); }
/** * 获取过滤已删除对象的hql条件语句. * * @see IUndeleteableEntityOperation#getUnDeletableHQL() */ public String getUnDeletableHQL() { return hexdao.getUnDeletableHQL(); }
/** * 获取过滤已删除对象的Criterion条件语句. * * @see UndeleteableEntityOperation# */ public Criterion getUnDeletableCriterion() { return hexdao.getUnDeletableCriterion(); }
/** * 重载保存函数,在保存前先调用onValid(T),进行书名不重复等数据库相关的校验. * * @see #onValid(Object) * @see HibernateEntityDao#save(Object) */ public void saveOnValid(Object entity) { hexdao.save(entity); }
/** * 删除对象,如果是Undeleteable的entity,设置对象的状态而不是直接删除. * * @see HibernateEntityDao#remove(Object) */ public void removeUndeleteable(Object entity) { hexdao.remove(entity); }
/** * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在此可重写. * * @see #save(Object) */ public void onValid(T entity) { }
/** * 根据Map中的条件的Criteria查询. * * @param map Map中仅包含条件名与条件值,默认全部相同,可重载。 */ @SuppressWarnings("unchecked") public List<T> find(Map map) { return hexdao.find(map); }
/** * 根据Map中的条件的Criteria查询. * * @param map Map中仅包含条件名与条件值,默认全部相同,可重载. */ @SuppressWarnings("unchecked") public List<T> find(Criteria criteria, Map map) { return hexdao.find(criteria, map); }
/** * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常. */ public T get(Class<T> entityClass, Serializable id) { return hedao.get(entityClass, id); }
/** * 获取全部对象. */ public List<T> getAll(Class<T> entityClass) { return hedao.getAll(entityClass); }
/** * 获取全部对象,带排序字段与升降序参数. */ public List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) { return hedao.getAll(entityClass, orderBy, isAsc); }
/** * 保存对象. */ public void save(Object o) { hedao.save(o); }
/** * 删除对象. */ public void remove(Object o) { hedao.remove(o); } public void flush(){ hedao.flush(); } public void clear(){ hedao.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) { return hedao.createQuery(hql, values); }
/** * 创建Criteria对象. * * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)} */ public Criteria createCriteria(Class<T> entityClass, Criterion... criterions) { return hedao.createCriteria(entityClass, criterions); }
/** * 创建Criteria对象,带排序字段与升降序字段. * * @see #createCriteria(Class,Criterion[]) */ public Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions) { return hedao.createCriteria(entityClass, orderBy, isAsc, criterions); }
/** * 根据hql查询,直接使用HibernateTemplate的find函数. * * @param values 可变参数,见{@link #createQuery(String,Object...)} */ @SuppressWarnings("unchecked") public List find(String hql, Object... values) { return hedao.find(hql, values); }
/** * 根据属性名和属性值查询对象. * * @return 符合条件的对象列表 */ public List<T> findBy(Class<T> entityClass, String propertyName, Object value) { return hedao.findBy(entityClass, propertyName, value); }
/** * 根据属性名和属性值查询对象,带排序参数. */ public List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc) { return hedao.findBy(entityClass, propertyName, value, orderBy, isAsc); }
/** * 根据属性名和属性值查询唯一对象. * * @return 符合条件的唯一对象 or null if not found. */ public T findUniqueBy(Class<T> entityClass, String propertyName, Object value) { return hedao.findUniqueBy(propertyName, value); }
/** * 分页查询函数,使用hql. * * @param pageNo 页号,从1开始. */ public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) { return hedao.pagedQuery(hql, pageNo, pageSize, values); }
/** * @author Scott.wanglei * @since 2008-7-21 * @param hql 查询sql * @param start 分页从哪一条数据开始 * @param pageSize 每一个页面的大小 * @param values 查询条件 * @return page对象 */ public Page dataQuery(String hql, int start, int pageSize, Object... values) { return hedao.dataQuery(hql, start, 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对象. */ @SuppressWarnings("unchecked") public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions) { return hedao.pagedQuery(entityClass, pageNo, pageSize, criterions); }
@SuppressWarnings("unchecked") public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc, Criterion... criterions) { return hedao.pagedQuery(entityClass, pageNo, pageSize, orderBy, isAsc, criterions); }
/** * 判断对象某些属性的值在数据库中是否唯一. * * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" */ public boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames) { return hedao.isUnique(entity, uniquePropertyNames); }
/** * 取得对象的主键值,辅助函数. */ @SuppressWarnings("unchecked") public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return hedao.getId(entityClass, entity); }
/** * 取得对象的主键名,辅助函数. */ @SuppressWarnings("unchecked") public String getIdName(Class clazz) { return hedao.getIdName(clazz); }
}
使用时候的xml配置: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www./schema/beans" xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:schemaLocation="http://www./schema/beans http://www./schema/beans/spring-beans.xsd">
<bean id="hedao" class="com.demonstration.hibernate.dao.HibernateEntityDao" scope="prototype"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean>
<bean id="hexdao" class="com.demonstration.hibernate.dao.extend.HibernateEntityExtendDao" scope="prototype"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean>
<!--使用泛型DAO作为抽象基类--> <bean id="baseDao" class="com.demonstration.hibernate.basedao.BaseDao" abstract="true" depends-on="hedao,hexdao"> <property name="hedao"> <ref bean="hedao" /> </property> <property name="hexdao"> <ref bean="hexdao" /> </property> </bean> <!--下面这个dao没有写任何java代码完全有spring搞定 --> <!-- 配置实体类的DAO --> <bean id="demoDao" parent="baseDao"> <constructor-arg> <!--根据这个生成某一个实体的dao --> <value>com.demonstration.entityclass.Demodata</value> </constructor-arg> </bean>
</beans>
发表于 @ 2010年03月12日 14:08:00 | 评论( 2 ) | 编辑| 举报| 收藏
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jie8991/archive/2010/03/12/5373849.aspx
|