- 浏览: 199554 次
- 性别:
- 来自: 厦门
文章分类
最新评论
-
huaxialonger:
根结点怎么不能折起来啊
JavaScript树型菜单 dtree -
yan578351314:
这东西好呀!!!顶。。。。。
JavaScript树型菜单 dtree -
s524141771:
LZ,当在一个页面内生成2个或多个树时,展开节点会出问题,即: ...
JavaScript树型菜单 dtree -
tss0823:
我遇到了文件路径的问题。哈哈。谢谢!
java平台下通过jacob对excel,word进行打印等操作(转exceljava*^__^) -
qingfeng_101:
呵呵 我也有个分页的东东 是个JavaBean+JSP标签的 ...
Hibernate+Spring+Struts2整合开发中的一个分页显示方案
泛型是JDK1.5的一个新的特性,使用泛型机制编写的程序代码要比那些杂乱的使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性。如果你的系统运行在JDK1.5以上的版本上,建议多使用泛型来代替无休止的对象转换。
在软件设计中我们开始对系统进行三层甚至是多层架构了,目的是职责更加的明确,功能更加的分离。而常常使用的三层架构就是将表现层、业务逻辑层和持久层进行分离,每一层关注点不同,职能更加的清晰。所以DAO的设计模式现在已经被我们所接受,下面就介绍一下泛型DAO的设计和实现。
这次的DAO例子是基于接口的.很多工具, 像Hibernate已经提供了数据库的便携访问,所以我们不是为持久层的轻便而设计接口. 然而, DAO接口在较为复杂的应用中更有意义, 当有几个持久化服务被封装到一个持久层的时候, 我想在很多情况下你应该直接使用Hibernate或者JPA, 而使用外加的DAO层最好的理由是为了实现更高的抽象化(例如:定义方法名findAll(String hql)而不是无数次地重复session.createQuery(...))
通用DAO接口:
package com.baiyyy.util.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
/**
* 承有业务数据的基础访问接口
* <p>
* 承有CRUD (创建,读取,修改和删陿)基本数据的操作在这个接口中都是独立的_ 并且承有的DAO都可以使用这些基本实玿
*
* @author yongtree
*
* @date:2008-03-04
*/
public interface IBaseDAO<T, ID extends Serializable> {
/***************************************************************************
* -------------------基本棿索㿁增加㿁修改㿁删除操使---------------------------- *
**************************************************************************/
// --------findById()方法是鿚过get(ID id)得到实体对象-----------------------
/**
* 通过ID来得到实体对豿
*
* @param id
* 实体对象的标识符
* @param lock
* 使用的锁模式
* @return 该主键忼对应的实体对象
*/
public T findById(ID id, LockMode lock);
/**
* 通过ID来得到实体对豿
*
* @param id
* @return T
*/
public T findById(ID id);
/**
* 通过ID来得到实体对豿(为兼容其他开发成员的原有程序,保留使甿)
*
* @param c
* @param id
* @return T
*/
public T findById(Class c, ID id);
// -------------loadById()是调用hibernate的load方法------------
public T loadById(ID id);
/**
* 通过id load对象
*
* @param id
* @param lock
* @return
*/
public T loadById(ID id, LockMode lock);
/**
* 获取全部的实使
*
* @return
*/
public List<T> loadAll();
/**
* 保存丿个实体对豿
*
* @param entity
*/
public T saveEntity(T entity);
/**
* 更新丿个实体对豿
*
* @param entity
*/
public void updateEntity(T entity);
public void updateEntity(T entity, LockMode lock);
/**
* 增加或更新集合中的全部实使
*
* @param entities
*/
public void saveOrUpdateAll(Collection<T> entities);
/**
* 删除丿个实使
*
* @param entity
* @throws Exception
*/
public void deleteEntity(T entity);
public void deleteEntity(T entity, LockMode lock);
/**
* 根据主键删除指定实体
*
* @param id
*/
public void deleteEntityById(ID id);
public void deleteEntityById(ID id, LockMode lock);
/**
* 批量删除
*
* @param entities
*/
public void deleteAll(Collection<T> entities);
/**
* 通过合并的方式更新对豿
*
* @param entity
* void
*/
public void merge(T entity);
/***************************************************************************
* ------------------------------使用HQL语句-------------------------------- *
**************************************************************************/
/**
* 使用HQL语句进行对象的查诿
*
* @param hsql
* 查询语句
* @return 符合条件的对豿
*/
public T getEntity(String hsql);
/**
* 使用HQL语句进行查询
*
* @param hsql
* 查询语句
* @return 符合条件的对象集吿
*/
public List<T> getEntities(String hsql);
/**
* 使用带参数的HQL语句进行查询
*
* @param hsql
* @param obj
* @return
*/
public List<T> getEntities(String hsql, Object[] values);
public List<T> getEntities(String hql, int start, int number);
public List<T> getEntities(String hql, int start, int number,
Object[] values);
/**
* 使用命名的HQL语句棿索数捿
*
* @param queryName
* @return
*/
public List<T> findByNamedQuery(String queryName);
/**
* 使用带参数的命名HSQL语句棿索数捿
*
* @param queryName
* @param values
* @return
*/
public List<T> findByNamedQuery(String queryName, Object[] values);
/**
* 使用带命名参数的命名HSQL语句棿索数捿
*
* @param queryName
* @param paramNames
* @param values
* @return
*/
public List<T> findByNamedQuery(String queryName, String[] paramNames,
Object[] values);
/**
* 使用HQL语句棿索数据,返回 Iterator
*
* @param queryString
* @return
*/
public Iterator<T> iterate(String queryString);
/**
* 使用带参数HSQL语句棿索数据,返回 Iterator
*
* @param queryString
* @param values
* @return
*/
public Iterator<T> iterate(String queryString, Object[] values);
/***************************************************************************
* -----------------------------Criteria动濁查诿---------------------------- *
**************************************************************************/
/**
* 创建与会话无关的棿索标准对豿
*/
public DetachedCriteria createDetachedCriteria();
/**
* 创建与会话绑定的棿索标准对豿
*
* @return
*/
public Criteria createCriteria();
/**
* 使用指定的检索标准检索数捿
*
* @param criteria
* @return
*/
public List<T> findByCriteria(DetachedCriteria criteria);
/**
* 使用指定的检索标准检索数据,返回部分记录
*
* @param criteria
* @param firstResult
* @param maxResults
* @return
*/
public List<T> findByCriteria(DetachedCriteria criteria, int firstResult,
int maxResults);
/**
* 通过动濁查询条件进行查诿
*
* @param criterion
* @return List<T>
*/
@SuppressWarnings("unchecked")
public List<T> findByCriteria(Criterion... criterion);
/**
* 使用指定的检索标准检索数据,返回指定范围的记彿
*
* @param criteria
* @return
*/
public Integer getRowCount(DetachedCriteria criteria);
/**
* 使用指定的检索标准检索数据,返回指定统计倿
*
* @param criteria
* @param propertyName
* @param StatName
* (max,min,avg,sum)
* @return
*/
public Object getStatValue(DetachedCriteria criteria, String propertyName,
String StatName);
/**
* 通过给定的一个对象,查找与其匹配的对象,表关联比较多时,用户可以自己根据霿要扩展㿿
*
* @param entity
* @return List<T>
*/
public List<T> findByExample(T entity);
/***************************************************************************
* -------------------------Others ----------------------------------------*
**************************************************************************/
/**
* 加锁指定的实使
*
* @param entity
* @param lockMode
*/
public void lock(T entity, LockMode lockMode);
/**
* 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
*/
public void flush();
/**
* 清空缓存
*
* void
*/
public void clear();
/***************************************************************************
* --------------------------------相关知识炿--------------------------------*
*
* 1、Session的load方法和get方法都是通过给定的ID从数据库中加载一个持久化的对象㿂但两个斿*
* 法的区别在于:当数据库不存在于ID对应的记录时,load()方法抛出异常,迌get()方法返回null*
***************************************************************************/
}
设计完接口,我们就要实现我们创建的接口,我们如果使用Hibernate,那么就做一个hibernate的实现,如果使用JPA,那么就做一个JPA实现。以下采用hibernate进行实现。
通用Hibernate DAO实现:
package com.baiyyy.util.dao;
/**
* @filename:BaseHibernateDAO.java
*/
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import com.baiyyy.workflow.pojo.TWfPackage;
/**
* 用Hibernate实现通用DAO接口
*
* @author yongtree
* @date 2008-3-10
* @param <T>
* @param <ID>
*/
public class BaseHibernateDAO<T, ID extends Serializable> implements
IBaseDAO<T, ID> {
// 保持实体对象类的类型
private Class<T> persistentClass;
private Session session;
/**
* 构鿠方泿
*/
@SuppressWarnings("unchecked")
public BaseHibernateDAO() {
//下面这种方式丿直有错误,不能得到真正的T.class,迌是Object.class
// this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
// System.out.println(obj.getClass().getName());
}
@SuppressWarnings("unchecked")
public BaseHibernateDAO(Class clazz) {
this.persistentClass = clazz;
}
/**
* @param session
* the session to set
*/
public void setSession(Session session) {
this.session = session;
}
/**
* 得到当前线程的Session对象的实便
*
* @return
*/
protected Session getSession() {
System.out.println("get session");
return HibernateUtil.getCurrentSession();
}
/**
* 得到持久化对象的类型
*
* @return 持久化类的类垿
*/
protected Class<T> getPersistentClass() {
return persistentClass;
}
@SuppressWarnings("unchecked")
public T findById(ID id, LockMode lock) {
// TODO Auto-generated method stub
T entity = (T) getSession().get(getPersistentClass(), id, lock);
if (entity != null) {
this.flush();
}
return entity;
}
@SuppressWarnings("unchecked")
public T findById(Class c, ID id) {
// TODO Auto-generated method stub
T entity;
entity = (T) getSession().get(c, id);
return entity;
}
@SuppressWarnings("unchecked")
public T findById(ID id) {
// TODO Auto-generated method stub
T entity = (T) getSession().get(getPersistentClass(), id);
return entity;
}
@SuppressWarnings("unchecked")
public T loadById(ID id) {
// TODO Auto-generated method stub
T entity = (T) getSession().load(getPersistentClass(), id);
return entity;
}
@SuppressWarnings("unchecked")
public T loadById(Class c, ID id) {
// TODO Auto-generated method stub
T entity = (T) getSession().load(c, id);
return entity;
}
@SuppressWarnings("unchecked")
public T loadById(ID id, LockMode lock) {
// TODO Auto-generated method stub
T entity = (T) getSession().load(getPersistentClass(), id, lock);
return entity;
}
@SuppressWarnings("unchecked")
public List<T> loadAll() {
List<T> list = getSession().createQuery(
"from " + getPersistentClass().getName()).list();
return list;
}
public T saveEntity(T entity) {
// TODO Auto-generated method stub
getSession().save(entity);
this.flush();
return entity;
}
public void updateEntity(T entity) {
// TODO Auto-generated method stub
getSession().saveOrUpdate(entity);
this.flush();
}
/**
* 该实现类暂时没有实现更新加锁的操使
*/
public void updateEntity(T entity, LockMode lock) {
// TODO Auto-generated method stub
getSession().saveOrUpdate(entity);
this.flush();
}
public void saveOrUpdateAll(Collection<T> entities) {
getSession().saveOrUpdate(entities);
this.flush();
}
public void deleteEntity(T entity) {
// TODO Auto-generated method stub
getSession().delete(entity);
this.flush();
}
/**
* 该实现没有实现加锁删除对象的操作,在spring的DAO实现中已经实玿
*/
public void deleteEntity(T entity, LockMode lock) {
// TODO Auto-generated method stub
getSession().delete(entity);
this.flush();
}
public void deleteEntityById(ID id) {
this.deleteEntity(this.loadById(id));
this.flush();
}
// 该实现没有实现加锁的删除,在spring的dao中已经实现了
public void deleteEntityById(ID id, LockMode lock) {
this.deleteEntity(this.loadById(id));
this.flush();
}
public void deleteAll(Collection<T> entities) {
this.flush();
getSession().delete(entities);
}
public void merge(T entity){
getSession().merge(entity);
this.flush();
}
@SuppressWarnings("unchecked")
public T getEntity(String hsql) {
T uniqueResult = (T) getSession().createQuery(hsql).uniqueResult();
// TODO Auto-generated method stub
return uniqueResult;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hsql) {
// TODO Auto-generated method stub
List list = getSession().createQuery(hsql).list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hql, int start, int number,
Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
query.setFirstResult(start);
query.setMaxResults(number);
List list = query.list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hql, int start, int number) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
query.setFirstResult(start);
query.setMaxResults(number);
List list = query.list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hql, Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
return query.list();
}
@SuppressWarnings("unchecked")
public List<T> findByNamedQuery(String queryName) {
// TODO Auto-generated method stub
return getSession().getNamedQuery(queryName).list();
}
@SuppressWarnings("unchecked")
public List<T> findByNamedQuery(String queryName, Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().getNamedQuery(queryName);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values);
}
return query.list();
}
/**
* 注意:该方法是鿚过设置参数来进行命名查询,承以在传参数时,一定要注意paramNames和values的长度,位置要一丿对应〿
*/
@SuppressWarnings("unchecked")
public List<T> findByNamedQuery(String queryName, String[] paramNames,
Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().getNamedQuery(queryName);
for (int i = 0; i < paramNames.length; i++) {
query.setParameter(paramNames[i], values[i]);
}
return query.list();
}
@SuppressWarnings("unchecked")
public Iterator<T> iterate(String hql) {
// TODO Auto-generated method stub
return getSession().createQuery(hql).iterate();
}
@SuppressWarnings("unchecked")
public Iterator<T> iterate(String hql, Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
return query.iterate();
}
public DetachedCriteria createDetachedCriteria() {
// TODO Auto-generated method stub
return DetachedCriteria.forClass(this.persistentClass);
}
public Criteria createCriteria() {
// TODO Auto-generated method stub
return this.createDetachedCriteria().getExecutableCriteria(
this.getSession());
}
/**
* 该方法没有经过验证,不能保证正确,在spring的实现中已经实现亿
*/
@SuppressWarnings("unchecked")
public List<T> findByCriteria(DetachedCriteria criteria) {
// TODO Auto-generated method stub
return criteria.getExecutableCriteria(this.getSession()).list();
}
@SuppressWarnings("unchecked")
public List<T> findByCriteria(DetachedCriteria criteria, int firstResult,
int maxResults) {
// TODO Auto-generated method stub
return criteria.getExecutableCriteria(this.getSession())
.setFirstResult(firstResult).setMaxResults(maxResults).list();
}
/**
* 动濁查诿
*
* @param criterion
* @return
*/
public @SuppressWarnings("unchecked")
List<T> findByCriteria(Criterion... criterion) {
Criteria crit = getSession().createCriteria(getPersistentClass());
for (Criterion c : criterion) {
if (c != null) {
crit.add(c);
}
}
List list = crit.list();
return list;
}
@SuppressWarnings("unchecked")
public Integer getRowCount(DetachedCriteria criteria) {
// TODO Auto-generated method stub
criteria.setProjection(Projections.rowCount());
List list = this.findByCriteria(criteria, 0, 1);
return (Integer) list.get(0);
}
@SuppressWarnings("unchecked")
public Object getStatValue(DetachedCriteria criteria, String propertyName,
String StatName) {
// TODO Auto-generated method stub
if (StatName.toLowerCase().equals("max"))
criteria.setProjection(Projections.max(propertyName));
else if (StatName.toLowerCase().equals("min"))
criteria.setProjection(Projections.min(propertyName));
else if (StatName.toLowerCase().equals("avg"))
criteria.setProjection(Projections.avg(propertyName));
else if (StatName.toLowerCase().equals("sum"))
criteria.setProjection(Projections.sum(propertyName));
else
return null;
List list = this.findByCriteria(criteria, 0, 1);
return list.get(0);
}
@SuppressWarnings("unchecked")
public List<T> findByExample(T exampleInstance) {
// TODO Auto-generated method stub
Criteria crit = getSession().createCriteria(getPersistentClass());
Example example = Example.create(exampleInstance);
example.ignoreCase().enableLike(MatchMode.ANYWHERE);// 忽略大小写,并进行模糊比辿
example.excludeZeroes();// 对于属濧中有数字类型的,如果exampleInstance的属性忼为0,就把它添加到查询中
crit.add(example);
return crit.list();
}
public void lock(T entity, LockMode lockMode) {
// TODO Auto-generated method stub
getSession().lock(entity, lockMode);
}
public void flush() {
// TODO Auto-generated method stub
getSession().flush();
}
public void clear() {
// TODO Auto-generated method stub
getSession().clear();
}
}
到现在为止,Hibernate通用DAO已经建立完成,作为一个通用的工具类,我们希望每个实体DAO都能继承这个DAO。继续发扬接口编程,每一个持久化实体类我们都建立一个接口,并且让这些接口都继承IBaseDAO。
ParticipantDAO的写法:
public interface ParticipantDAO extends IBaseDAO<TWfParticipants, Integer>{
//自定义该实体的接口
}
ParticipantDAO实现类的写法:
public class ParticipantDAOImpl extends
BaseHibernateDAO<TWfParticipants, Integer> implements
ParticipantDAO {
public ParticipantDAOImpl() {
super(TWfParticipants.class);
}
//实现自定义的方法
}
注:在BaseHibernateDAO的无参数构造函数中
public BaseHibernateDAO() {
//下面这种方式一直有错误,不能得到真正的T.class,迌是Object.class
// this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
}
这种方式的写法在springside中使用过,但是自己调试始终有错误,始终无法得到T.class,得到的只是Oject.class,不知道怎么解决,还请高人指点。
以下是我的替代方法,可能不是太好。构建一个带有Class参数的构造函数,让每个DAO硬性传入class。
public BaseHibernateDAO(Class clazz) {
this.persistentClass = clazz;
}
然后在子类DAO的构造参数中向父类传递一个class,因为一个DAO对应着一个实体,所以传入一个实体的class也是没有什么不可以的。
public ParticipantDAOImpl() {
super(TWfParticipants.class);
}
补充GenericsUtils.java:
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
*/
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.
*/
public static Class getSuperClassGenricType(Class clazz, int index)
throws IndexOutOfBoundsException {
Type genType = clazz.getGenericSuperclass();
// Type genType = clazz;
if (!(genType instanceof ParameterizedType)) {
log.warn(clazz.getSimpleName()
+ "'s superclass not ParameterizedType");
return clazz;
}
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];
}
}
在实际的项目中,我们常常忽略了业务逻辑层,我们有人喜欢将大部分的逻辑放在表现层的Java Bean中,也有人喜欢在DAO中编写自己的业务逻辑,虽然功能都能实现,但是职责不明,让我们面对这些杂乱无章的代码,我们无所适从。泛型DAO的设计我感觉很大程度上可以强制程序员不要在DAO中书写自己的逻辑代码,也让我们慢慢的建立自己业务逻辑层(在EJB,spring这样的框架没有引入的情况下)。
当然为了系统的可扩展性、可移植性和系统的松耦合,我们可以采用DAO工厂模式和反射机制来架构我们的系统,由于篇幅有限,这里就不做介绍了。这部分内容我将在以后的时间里进行整理并发布在我的csdn博客和javaeye博客上。
yongtree 2008-3-11 晚
在软件设计中我们开始对系统进行三层甚至是多层架构了,目的是职责更加的明确,功能更加的分离。而常常使用的三层架构就是将表现层、业务逻辑层和持久层进行分离,每一层关注点不同,职能更加的清晰。所以DAO的设计模式现在已经被我们所接受,下面就介绍一下泛型DAO的设计和实现。
这次的DAO例子是基于接口的.很多工具, 像Hibernate已经提供了数据库的便携访问,所以我们不是为持久层的轻便而设计接口. 然而, DAO接口在较为复杂的应用中更有意义, 当有几个持久化服务被封装到一个持久层的时候, 我想在很多情况下你应该直接使用Hibernate或者JPA, 而使用外加的DAO层最好的理由是为了实现更高的抽象化(例如:定义方法名findAll(String hql)而不是无数次地重复session.createQuery(...))
通用DAO接口:
package com.baiyyy.util.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
/**
* 承有业务数据的基础访问接口
* <p>
* 承有CRUD (创建,读取,修改和删陿)基本数据的操作在这个接口中都是独立的_ 并且承有的DAO都可以使用这些基本实玿
*
* @author yongtree
*
* @date:2008-03-04
*/
public interface IBaseDAO<T, ID extends Serializable> {
/***************************************************************************
* -------------------基本棿索㿁增加㿁修改㿁删除操使---------------------------- *
**************************************************************************/
// --------findById()方法是鿚过get(ID id)得到实体对象-----------------------
/**
* 通过ID来得到实体对豿
*
* @param id
* 实体对象的标识符
* @param lock
* 使用的锁模式
* @return 该主键忼对应的实体对象
*/
public T findById(ID id, LockMode lock);
/**
* 通过ID来得到实体对豿
*
* @param id
* @return T
*/
public T findById(ID id);
/**
* 通过ID来得到实体对豿(为兼容其他开发成员的原有程序,保留使甿)
*
* @param c
* @param id
* @return T
*/
public T findById(Class c, ID id);
// -------------loadById()是调用hibernate的load方法------------
public T loadById(ID id);
/**
* 通过id load对象
*
* @param id
* @param lock
* @return
*/
public T loadById(ID id, LockMode lock);
/**
* 获取全部的实使
*
* @return
*/
public List<T> loadAll();
/**
* 保存丿个实体对豿
*
* @param entity
*/
public T saveEntity(T entity);
/**
* 更新丿个实体对豿
*
* @param entity
*/
public void updateEntity(T entity);
public void updateEntity(T entity, LockMode lock);
/**
* 增加或更新集合中的全部实使
*
* @param entities
*/
public void saveOrUpdateAll(Collection<T> entities);
/**
* 删除丿个实使
*
* @param entity
* @throws Exception
*/
public void deleteEntity(T entity);
public void deleteEntity(T entity, LockMode lock);
/**
* 根据主键删除指定实体
*
* @param id
*/
public void deleteEntityById(ID id);
public void deleteEntityById(ID id, LockMode lock);
/**
* 批量删除
*
* @param entities
*/
public void deleteAll(Collection<T> entities);
/**
* 通过合并的方式更新对豿
*
* @param entity
* void
*/
public void merge(T entity);
/***************************************************************************
* ------------------------------使用HQL语句-------------------------------- *
**************************************************************************/
/**
* 使用HQL语句进行对象的查诿
*
* @param hsql
* 查询语句
* @return 符合条件的对豿
*/
public T getEntity(String hsql);
/**
* 使用HQL语句进行查询
*
* @param hsql
* 查询语句
* @return 符合条件的对象集吿
*/
public List<T> getEntities(String hsql);
/**
* 使用带参数的HQL语句进行查询
*
* @param hsql
* @param obj
* @return
*/
public List<T> getEntities(String hsql, Object[] values);
public List<T> getEntities(String hql, int start, int number);
public List<T> getEntities(String hql, int start, int number,
Object[] values);
/**
* 使用命名的HQL语句棿索数捿
*
* @param queryName
* @return
*/
public List<T> findByNamedQuery(String queryName);
/**
* 使用带参数的命名HSQL语句棿索数捿
*
* @param queryName
* @param values
* @return
*/
public List<T> findByNamedQuery(String queryName, Object[] values);
/**
* 使用带命名参数的命名HSQL语句棿索数捿
*
* @param queryName
* @param paramNames
* @param values
* @return
*/
public List<T> findByNamedQuery(String queryName, String[] paramNames,
Object[] values);
/**
* 使用HQL语句棿索数据,返回 Iterator
*
* @param queryString
* @return
*/
public Iterator<T> iterate(String queryString);
/**
* 使用带参数HSQL语句棿索数据,返回 Iterator
*
* @param queryString
* @param values
* @return
*/
public Iterator<T> iterate(String queryString, Object[] values);
/***************************************************************************
* -----------------------------Criteria动濁查诿---------------------------- *
**************************************************************************/
/**
* 创建与会话无关的棿索标准对豿
*/
public DetachedCriteria createDetachedCriteria();
/**
* 创建与会话绑定的棿索标准对豿
*
* @return
*/
public Criteria createCriteria();
/**
* 使用指定的检索标准检索数捿
*
* @param criteria
* @return
*/
public List<T> findByCriteria(DetachedCriteria criteria);
/**
* 使用指定的检索标准检索数据,返回部分记录
*
* @param criteria
* @param firstResult
* @param maxResults
* @return
*/
public List<T> findByCriteria(DetachedCriteria criteria, int firstResult,
int maxResults);
/**
* 通过动濁查询条件进行查诿
*
* @param criterion
* @return List<T>
*/
@SuppressWarnings("unchecked")
public List<T> findByCriteria(Criterion... criterion);
/**
* 使用指定的检索标准检索数据,返回指定范围的记彿
*
* @param criteria
* @return
*/
public Integer getRowCount(DetachedCriteria criteria);
/**
* 使用指定的检索标准检索数据,返回指定统计倿
*
* @param criteria
* @param propertyName
* @param StatName
* (max,min,avg,sum)
* @return
*/
public Object getStatValue(DetachedCriteria criteria, String propertyName,
String StatName);
/**
* 通过给定的一个对象,查找与其匹配的对象,表关联比较多时,用户可以自己根据霿要扩展㿿
*
* @param entity
* @return List<T>
*/
public List<T> findByExample(T entity);
/***************************************************************************
* -------------------------Others ----------------------------------------*
**************************************************************************/
/**
* 加锁指定的实使
*
* @param entity
* @param lockMode
*/
public void lock(T entity, LockMode lockMode);
/**
* 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
*/
public void flush();
/**
* 清空缓存
*
* void
*/
public void clear();
/***************************************************************************
* --------------------------------相关知识炿--------------------------------*
*
* 1、Session的load方法和get方法都是通过给定的ID从数据库中加载一个持久化的对象㿂但两个斿*
* 法的区别在于:当数据库不存在于ID对应的记录时,load()方法抛出异常,迌get()方法返回null*
***************************************************************************/
}
设计完接口,我们就要实现我们创建的接口,我们如果使用Hibernate,那么就做一个hibernate的实现,如果使用JPA,那么就做一个JPA实现。以下采用hibernate进行实现。
通用Hibernate DAO实现:
package com.baiyyy.util.dao;
/**
* @filename:BaseHibernateDAO.java
*/
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import com.baiyyy.workflow.pojo.TWfPackage;
/**
* 用Hibernate实现通用DAO接口
*
* @author yongtree
* @date 2008-3-10
* @param <T>
* @param <ID>
*/
public class BaseHibernateDAO<T, ID extends Serializable> implements
IBaseDAO<T, ID> {
// 保持实体对象类的类型
private Class<T> persistentClass;
private Session session;
/**
* 构鿠方泿
*/
@SuppressWarnings("unchecked")
public BaseHibernateDAO() {
//下面这种方式丿直有错误,不能得到真正的T.class,迌是Object.class
// this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
// System.out.println(obj.getClass().getName());
}
@SuppressWarnings("unchecked")
public BaseHibernateDAO(Class clazz) {
this.persistentClass = clazz;
}
/**
* @param session
* the session to set
*/
public void setSession(Session session) {
this.session = session;
}
/**
* 得到当前线程的Session对象的实便
*
* @return
*/
protected Session getSession() {
System.out.println("get session");
return HibernateUtil.getCurrentSession();
}
/**
* 得到持久化对象的类型
*
* @return 持久化类的类垿
*/
protected Class<T> getPersistentClass() {
return persistentClass;
}
@SuppressWarnings("unchecked")
public T findById(ID id, LockMode lock) {
// TODO Auto-generated method stub
T entity = (T) getSession().get(getPersistentClass(), id, lock);
if (entity != null) {
this.flush();
}
return entity;
}
@SuppressWarnings("unchecked")
public T findById(Class c, ID id) {
// TODO Auto-generated method stub
T entity;
entity = (T) getSession().get(c, id);
return entity;
}
@SuppressWarnings("unchecked")
public T findById(ID id) {
// TODO Auto-generated method stub
T entity = (T) getSession().get(getPersistentClass(), id);
return entity;
}
@SuppressWarnings("unchecked")
public T loadById(ID id) {
// TODO Auto-generated method stub
T entity = (T) getSession().load(getPersistentClass(), id);
return entity;
}
@SuppressWarnings("unchecked")
public T loadById(Class c, ID id) {
// TODO Auto-generated method stub
T entity = (T) getSession().load(c, id);
return entity;
}
@SuppressWarnings("unchecked")
public T loadById(ID id, LockMode lock) {
// TODO Auto-generated method stub
T entity = (T) getSession().load(getPersistentClass(), id, lock);
return entity;
}
@SuppressWarnings("unchecked")
public List<T> loadAll() {
List<T> list = getSession().createQuery(
"from " + getPersistentClass().getName()).list();
return list;
}
public T saveEntity(T entity) {
// TODO Auto-generated method stub
getSession().save(entity);
this.flush();
return entity;
}
public void updateEntity(T entity) {
// TODO Auto-generated method stub
getSession().saveOrUpdate(entity);
this.flush();
}
/**
* 该实现类暂时没有实现更新加锁的操使
*/
public void updateEntity(T entity, LockMode lock) {
// TODO Auto-generated method stub
getSession().saveOrUpdate(entity);
this.flush();
}
public void saveOrUpdateAll(Collection<T> entities) {
getSession().saveOrUpdate(entities);
this.flush();
}
public void deleteEntity(T entity) {
// TODO Auto-generated method stub
getSession().delete(entity);
this.flush();
}
/**
* 该实现没有实现加锁删除对象的操作,在spring的DAO实现中已经实玿
*/
public void deleteEntity(T entity, LockMode lock) {
// TODO Auto-generated method stub
getSession().delete(entity);
this.flush();
}
public void deleteEntityById(ID id) {
this.deleteEntity(this.loadById(id));
this.flush();
}
// 该实现没有实现加锁的删除,在spring的dao中已经实现了
public void deleteEntityById(ID id, LockMode lock) {
this.deleteEntity(this.loadById(id));
this.flush();
}
public void deleteAll(Collection<T> entities) {
this.flush();
getSession().delete(entities);
}
public void merge(T entity){
getSession().merge(entity);
this.flush();
}
@SuppressWarnings("unchecked")
public T getEntity(String hsql) {
T uniqueResult = (T) getSession().createQuery(hsql).uniqueResult();
// TODO Auto-generated method stub
return uniqueResult;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hsql) {
// TODO Auto-generated method stub
List list = getSession().createQuery(hsql).list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hql, int start, int number,
Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
query.setFirstResult(start);
query.setMaxResults(number);
List list = query.list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hql, int start, int number) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
query.setFirstResult(start);
query.setMaxResults(number);
List list = query.list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> getEntities(String hql, Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
return query.list();
}
@SuppressWarnings("unchecked")
public List<T> findByNamedQuery(String queryName) {
// TODO Auto-generated method stub
return getSession().getNamedQuery(queryName).list();
}
@SuppressWarnings("unchecked")
public List<T> findByNamedQuery(String queryName, Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().getNamedQuery(queryName);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values);
}
return query.list();
}
/**
* 注意:该方法是鿚过设置参数来进行命名查询,承以在传参数时,一定要注意paramNames和values的长度,位置要一丿对应〿
*/
@SuppressWarnings("unchecked")
public List<T> findByNamedQuery(String queryName, String[] paramNames,
Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().getNamedQuery(queryName);
for (int i = 0; i < paramNames.length; i++) {
query.setParameter(paramNames[i], values[i]);
}
return query.list();
}
@SuppressWarnings("unchecked")
public Iterator<T> iterate(String hql) {
// TODO Auto-generated method stub
return getSession().createQuery(hql).iterate();
}
@SuppressWarnings("unchecked")
public Iterator<T> iterate(String hql, Object[] values) {
// TODO Auto-generated method stub
Query query = getSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
return query.iterate();
}
public DetachedCriteria createDetachedCriteria() {
// TODO Auto-generated method stub
return DetachedCriteria.forClass(this.persistentClass);
}
public Criteria createCriteria() {
// TODO Auto-generated method stub
return this.createDetachedCriteria().getExecutableCriteria(
this.getSession());
}
/**
* 该方法没有经过验证,不能保证正确,在spring的实现中已经实现亿
*/
@SuppressWarnings("unchecked")
public List<T> findByCriteria(DetachedCriteria criteria) {
// TODO Auto-generated method stub
return criteria.getExecutableCriteria(this.getSession()).list();
}
@SuppressWarnings("unchecked")
public List<T> findByCriteria(DetachedCriteria criteria, int firstResult,
int maxResults) {
// TODO Auto-generated method stub
return criteria.getExecutableCriteria(this.getSession())
.setFirstResult(firstResult).setMaxResults(maxResults).list();
}
/**
* 动濁查诿
*
* @param criterion
* @return
*/
public @SuppressWarnings("unchecked")
List<T> findByCriteria(Criterion... criterion) {
Criteria crit = getSession().createCriteria(getPersistentClass());
for (Criterion c : criterion) {
if (c != null) {
crit.add(c);
}
}
List list = crit.list();
return list;
}
@SuppressWarnings("unchecked")
public Integer getRowCount(DetachedCriteria criteria) {
// TODO Auto-generated method stub
criteria.setProjection(Projections.rowCount());
List list = this.findByCriteria(criteria, 0, 1);
return (Integer) list.get(0);
}
@SuppressWarnings("unchecked")
public Object getStatValue(DetachedCriteria criteria, String propertyName,
String StatName) {
// TODO Auto-generated method stub
if (StatName.toLowerCase().equals("max"))
criteria.setProjection(Projections.max(propertyName));
else if (StatName.toLowerCase().equals("min"))
criteria.setProjection(Projections.min(propertyName));
else if (StatName.toLowerCase().equals("avg"))
criteria.setProjection(Projections.avg(propertyName));
else if (StatName.toLowerCase().equals("sum"))
criteria.setProjection(Projections.sum(propertyName));
else
return null;
List list = this.findByCriteria(criteria, 0, 1);
return list.get(0);
}
@SuppressWarnings("unchecked")
public List<T> findByExample(T exampleInstance) {
// TODO Auto-generated method stub
Criteria crit = getSession().createCriteria(getPersistentClass());
Example example = Example.create(exampleInstance);
example.ignoreCase().enableLike(MatchMode.ANYWHERE);// 忽略大小写,并进行模糊比辿
example.excludeZeroes();// 对于属濧中有数字类型的,如果exampleInstance的属性忼为0,就把它添加到查询中
crit.add(example);
return crit.list();
}
public void lock(T entity, LockMode lockMode) {
// TODO Auto-generated method stub
getSession().lock(entity, lockMode);
}
public void flush() {
// TODO Auto-generated method stub
getSession().flush();
}
public void clear() {
// TODO Auto-generated method stub
getSession().clear();
}
}
到现在为止,Hibernate通用DAO已经建立完成,作为一个通用的工具类,我们希望每个实体DAO都能继承这个DAO。继续发扬接口编程,每一个持久化实体类我们都建立一个接口,并且让这些接口都继承IBaseDAO。
ParticipantDAO的写法:
public interface ParticipantDAO extends IBaseDAO<TWfParticipants, Integer>{
//自定义该实体的接口
}
ParticipantDAO实现类的写法:
public class ParticipantDAOImpl extends
BaseHibernateDAO<TWfParticipants, Integer> implements
ParticipantDAO {
public ParticipantDAOImpl() {
super(TWfParticipants.class);
}
//实现自定义的方法
}
注:在BaseHibernateDAO的无参数构造函数中
public BaseHibernateDAO() {
//下面这种方式一直有错误,不能得到真正的T.class,迌是Object.class
// this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass());
}
这种方式的写法在springside中使用过,但是自己调试始终有错误,始终无法得到T.class,得到的只是Oject.class,不知道怎么解决,还请高人指点。
以下是我的替代方法,可能不是太好。构建一个带有Class参数的构造函数,让每个DAO硬性传入class。
public BaseHibernateDAO(Class clazz) {
this.persistentClass = clazz;
}
然后在子类DAO的构造参数中向父类传递一个class,因为一个DAO对应着一个实体,所以传入一个实体的class也是没有什么不可以的。
public ParticipantDAOImpl() {
super(TWfParticipants.class);
}
补充GenericsUtils.java:
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
*/
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.
*/
public static Class getSuperClassGenricType(Class clazz, int index)
throws IndexOutOfBoundsException {
Type genType = clazz.getGenericSuperclass();
// Type genType = clazz;
if (!(genType instanceof ParameterizedType)) {
log.warn(clazz.getSimpleName()
+ "'s superclass not ParameterizedType");
return clazz;
}
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];
}
}
在实际的项目中,我们常常忽略了业务逻辑层,我们有人喜欢将大部分的逻辑放在表现层的Java Bean中,也有人喜欢在DAO中编写自己的业务逻辑,虽然功能都能实现,但是职责不明,让我们面对这些杂乱无章的代码,我们无所适从。泛型DAO的设计我感觉很大程度上可以强制程序员不要在DAO中书写自己的逻辑代码,也让我们慢慢的建立自己业务逻辑层(在EJB,spring这样的框架没有引入的情况下)。
当然为了系统的可扩展性、可移植性和系统的松耦合,我们可以采用DAO工厂模式和反射机制来架构我们的系统,由于篇幅有限,这里就不做介绍了。这部分内容我将在以后的时间里进行整理并发布在我的csdn博客和javaeye博客上。
yongtree 2008-3-11 晚
相关推荐
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...
通过上述分析,我们可以看出,合理设计和运用泛型DAO层,不仅可以显著提高代码的复用性和维护性,还能极大地简化复杂的数据库操作,使得开发人员能够更加专注于业务逻辑的实现。因此,对于那些追求高质量、高效率的...
本篇文章将深入探讨一个使用Spring注解和Hibernate实现的泛型DAO设计,以提高代码的复用性和可维护性。 首先,`HibernateBaseDao.java`是基础的Hibernate DAO类,它提供了对Hibernate操作的基本封装。这个类通常会...
在Java编程语言中,"泛型DAO"(Generic DAO)是一种设计模式,它允许开发者创建可重用的数据访问对象(DAOs),以处理多种不同类型的实体对象,而无需为每种对象编写单独的DAO实现。这种方法提高了代码的复用性和可...
【标题】"Hibernate泛型Dao"是针对Java开发中的数据持久化框架Hibernate的一个高级应用,主要目的是为了提高代码的复用性和简洁性。在传统的Hibernate使用中,针对每个实体类,我们都需要创建一个对应的Dao(Data ...
而泛型DAO是一个类型安全的,代码精简的设计模式(相对于传统DAO),尤其在DAO组件数量庞大的时候,代码量的减少更加明显。 泛型DAO的核心是定义一个GenericDao接口,声明基本的CRUD操作: 用hibernate作为持久化...
本篇文章将探讨如何使用Hibernate实现泛型DAO,并结合Spring模板来增强其功能。 泛型DAO是一种设计模式,它通过定义一个通用的DAO接口或抽象类,可以适用于不同的实体类,减少了重复的代码。这种模式的核心在于利用...
`JdbcTemplate`的泛型Dao实现是一种设计模式,目的是提高代码的可重用性和可维护性。通过定义一个泛型接口,我们可以创建一个通用的数据访问对象(DAO),这个DAO可以处理任何类型的实体类,只要它们遵循一定的规则...
6. **泛型Dao**:在Java开发中,泛型Dao(Generic Dao)是一种设计模式,用于减少重复的数据库操作代码。通过定义一个通用的Dao接口,可以实现对不同类型的实体对象进行CRUD操作,提高了代码的复用性和可维护性。...
泛型DAO模式在Java Web开发中的应用 摘要: 泛型DAO模式是Java Web开发中的一种重要模式,它可以提高数据访问代码的类型安全性和可读性。该模式可以与Struts、Spring和JPA框架集成,实现用户管理系统的开发。通过...
【泛型DAO模型设计】是Java开发中一种高效且可复用的数据访问对象(DAO)设计方式,结合了泛型和反射技术。泛型在Java中引入,旨在提高代码的安全性和可读性,减少类型转换的繁琐过程。DAO设计模式主要用于数据库...
本篇文章将深入探讨泛型DAO的实现原理、优势以及如何在实际项目中应用。 首先,我们来理解什么是泛型。泛型是Java 5引入的一个重要特性,允许在类、接口和方法中使用类型参数,以创建可重用的代码并确保类型安全。...
泛型DAO模式通过抽象化设计,增强了程序的复用性和简化了编程语言,同时在程序运行结束后进行类型检查,避免了运行时的问题,并提高了运行速度。 文章进一步讨论了泛型DAO模式的查询功能设计。查询功能是泛型DAO...
本文将深入探讨“Spring Hibernate 泛型DAO”这一主题,以及如何通过泛型DAO实现更加高效、可复用的代码。 首先,让我们理解什么是DAO(Data Access Object)模式。DAO是一种设计模式,它的主要作用是隔离业务逻辑...
总的来说,"ssh通用泛型DAO"是一种设计模式,旨在简化SSH框架下的数据访问层开发,提高代码复用性,减少重复工作,同时通过泛型提供类型安全的保障。理解和熟练运用这一模式,能够有效地提升Java Web应用的开发效率...
4. **泛型DAO**: 在SSH框架中,泛型DAO是一种常见的设计模式,用于封装对数据库的基本操作,如增删查改。通过泛型,我们可以创建一个通用的DAO接口和实现,减少代码重复,提高代码复用。例如,我们可以创建一个`...
而泛型DAO是DAO模式的一个进阶应用,它通过引入泛型来提高代码的复用性和可维护性。 泛型(Generics)是Java 5引入的一个重要特性,它可以让我们在编译时检查类型安全,并且允许我们创建参数化的类型。在泛型DAO中...
而泛型DAO(Data Access Object)则是基于Hibernate进一步抽象出来的一个设计模式,用于提供更通用的数据操作方法。本文档主要探讨了如何在Spring+Hibernate环境中创建和使用泛型DAO。 首先,我们来看一下泛型DAO...