随笔-42  评论-578  文章-1  trackbacks-0
         此EntityDao接口与EntityDaoImpl实现类,可取代了我们平时写的UserDao,NewsDao,CompanyDao等等,可直接供Service层调用.其中实现类的代码如下:
/**
 * Copyright 2009-1012 the original author or authors.
 * My Blog site: 
http://www.blogjava.net/rongxh7
 
*/


package rong.common.dao;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Repository;
import rong.common.utils.Pager;
import rong.util.MyHibernateDaoSupport;

/**
 * Dao层接口的实现类
 * 许多人习惯根据不多的业务逻辑定义不同的DAO层接口,如UserDao,NewsDao,CompanyDao等等,
 * 这样往往使得编码量十分庞大,而且带来了维护的困难,因此,抽取此DAO层接口,收录大部分
 * DAO层必须的方法,以供Service层调用。
 * 
@author rongxinhua
 * 
@version 1.0
 * 
@param <T> 范型,指实体类
 * 
@param <PK> 范型,指实体类主键的数据类型,如Integer,Long
 * 
@see rong.common.dao.EntityDao
 
*/


@Repository(value
="entityDao")
public class EntityDaoImpl<T,PK extends Serializable> extends MyHibernateDaoSupport implements EntityDao<T, PK>{

    
/**
     * 保存实体
     * 包括添加和修改
     * 
@param t 实体对象
     
*/

    
public void saveOrUpdate(T t){
        getHibernateTemplate().saveOrUpdate(t);
    }

    
    
/**
     * 更新实体
     * 可用于添加、修改、删除操作
     * 
@param hql 更新的HQL语句
     * 
@param params 参数,可有项目或多项目,代替Hql中的"?"号
     
*/

    
public void update(final String hql,final Object params){
        getHibernateTemplate().execute(
new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Query query 
= session.createQuery(hql);
                
for(int i=0; i<params.length; i++){
                    query.setParameter(i, params[i]);
                }

                query.executeUpdate();
                
return null;
            }

        }
);
    }

    
    
/**
     * 删除实体
     * 
@param t 实体对象
     
*/

    
public void delete(T t){
        getHibernateTemplate().delete(t);
    }

    
    
/**
     * 删除实体
     * 
@param entityClass 实体类名
     * 
@param id 实体的ID
     
*/

    
public void delete(Class<T> entityClass,PK id){
        getHibernateTemplate().delete(get(entityClass,id));
    }

    
    
/**
     * 单查实体
     * 
@param entityClass 实体类名
     * 
@param id 实体的ID
     * 
@return 实体对象
     
*/

    @SuppressWarnings(
"unchecked")
    
public T get(Class<T> entityClass,PK id){
        
return (T)getHibernateTemplate().get(entityClass, id);
    }

    
    
/**
     * 查询全部记录列表
     * 
@param entityClass 实体类名
     * 
@param propertyName 排序的参照属性
     * 
@param isAsc 排序方式
     * 
@param criterions 查询条件,可为0项或任意多项目
     * 
@return 记录List集
     
*/

    
public List<T> findAll(final Class<T> entityClass,final String propertyName,final boolean isAsc,final Criterion criterions){
        
int firstResult = 0;
        
int maxResults = 0;        //设置为0,则表示查询全部记录
        return findByCriteria(entityClass, propertyName, isAsc, firstResult, maxResults, criterions);
    }

    
    
/**
     * 查询列表
     * 
@param entityClass 实体类名
     * 
@param propertyName 排序的参照属性
     * 
@param isAsc 排序方式,true表示升序,false表示降序,当propertyName赋值为null时,此参数无效
     * 
@param firstResult 开始记录序号
     * 
@param maxResults 最大记录数
     * 
@param criterions 查询条件,可有0项或任意多项目
     * 
@return 记录List集
     
*/

    @SuppressWarnings(
"unchecked")
    
public List<T> findByCriteria(final Class<T> entityClass,final String propertyName,final boolean isAsc,final int firstResult,final int maxResults,final Criterion criterions){
        List
<T> list = (List<T>)getHibernateTemplate().execute(new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Criteria criteria 
= session.createCriteria(entityClass);
                
//按属性条件查询
                for(Criterion criterion : criterions){
                    criteria.add(criterion);
                }

                
//按某个属性排序
                if(null != propertyName){
                    
if(isAsc){
                        criteria.addOrder(Order.asc(propertyName));
                    }
else{
                        criteria.addOrder(Order.desc(propertyName));
                    }

                }

                
//用于分页查询
                if(maxResults != 0){
                    criteria.setFirstResult(firstResult);
                    criteria.setMaxResults(maxResults);
                }

                List
<T> list = criteria.list();
                
return list;
            }

        }
);
        
return list;
    }

    
    
/**
     * 查询总记录数
     * 
@param entityClass 实体类名
     * 
@param criterions 查询条件,可有0项或任意多项
     * 
@return 总记录数
     
*/

    
public int findCountsByCriteria(final Class<T> entityClass,final Criterion criterions){
            
int totalCounts = (Integer)getHibernateTemplate().execute(new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Criteria criteria 
= session.createCriteria(entityClass);
                
//按属性条件查询
                for(Criterion criterion : criterions){
                    criteria.add(criterion);
                }

                
int totalCounts = criteria.list().size();
                
return totalCounts;
            }

        }
);
        
return totalCounts;
    }

    
    
    
/**
     * 分页查询
     * 
@param entityClass 实体类名
     * 
@param propertyName 排序参照属性
     * 
@param isAsc 排序方式,true表示升序,false表示降序,当propertyName赋值为null时,此参数无效
     * 
@param firstResult 开始记录序号
     * 
@param maxResults 最大记录数
     * 
@param criterions 查询条件,可为0项或任意多项目
     * 
@return 封装List和totalCounts的Pager对象
     
*/

    @SuppressWarnings(
"unchecked")
    
public Pager<T> findForPager(final Class<T> entityClass,final String propertyName,final boolean isAsc,final int firstResult,final int maxResults,final Criterion criterions){
        
int totalCounts = findCountsByCriteria(entityClass, criterions);
        List
<T> entityList = findByCriteria(entityClass, propertyName, isAsc, firstResult, maxResults, criterions);
        Pager pager 
= new Pager();
        pager.setTotalCounts(totalCounts);
        pager.setEntityList(entityList);
        
return pager;
    }

    
    
/**
     * 根据属性值查询列表
     * 
@param entityClass 实体类名
     * 
@param propertyName 属性名
     * 
@param value 属性值
     * 
@return List列表
     
*/

    
public List<T> findByProperty(Class<T> entityClass,String propertyName,Object value){
        Criterion criterion 
= Restrictions.eq(propertyName, value);
        List
<T> list = findAll(entityClass, nulltrue, criterion);
        
return list;
    }

    
    
/**
     * 根据属性值查询单个对象
     * 
@param entityClass 实体类名
     * 
@param propertyName 属性名
     * 
@param value 属性值
     * 
@return 实体对象
     
*/

    @SuppressWarnings(
"unchecked")
    
public T findUniqueByProperty(final Class<T> entityClass,final String propertyName,final Object value){
        T t 
= (T)getHibernateTemplate().execute(new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Criteria criteria 
= session.createCriteria(entityClass).add(Restrictions.eq(propertyName, value));
                T t 
= (T)criteria.uniqueResult();
                
return t;
            }

        }
);
        
return t;
    }

    
    
/**
     * 根据属性值查询实体是否存在
     * 
@param entityClass 实体类名
     * 
@param propertyName 参照的属性名
     * 
@param value 属性值
     * 
@return 存在则返回true,不存在则返回false
     
*/

    
public boolean isPropertyExist(final Class<T> entityClass,final String propertyName,final Object value){
        
boolean isExist = (Boolean)getHibernateTemplate().execute(new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Criteria criteria 
= session.createCriteria(entityClass).add(Restrictions.eq(propertyName, value));
                
boolean isEmpty = criteria.list().isEmpty();
                
return ! isEmpty;
            }

        }
);
        
return isExist;
    }

    
    
/**
     * 
     * 
@param hql 查询语句
     * 用法如:可用于登录验证时,根据用户名、密码等信息查询用户
     * 
@param params 参数数组,代替HQL中的"?"号,可有0项目或多项
     * 
@return 唯一实体,返回null则表示不存在配置的实体
     * 
@exception 如果查询的结果集不唯一,则抛异常
     
*/

    @SuppressWarnings(
"unchecked")
    
public T findUniqueByHql(final String hql, final Object params ){
        
        T t 
= (T)getHibernateTemplate().execute(new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Query query 
= session.createQuery(hql);
                
for(int i=0; i<params.length; i++){
                    query.setParameter(i, params[i]);
                }

                T t 
= (T)query.uniqueResult();
                
return t;
            }

        }
);
        
return t;
    }

    
    
/**
     * 按HQL条件查询列表
     * 
@param hql 查询语句,支持连接查询和多条件查询
     * 
@param params 参数数组,代替hql中的"?"号
     * 
@return 结果集List
     
*/

    @SuppressWarnings(
"unchecked")
    
public List<T> findByHql(String hql,Object params){
        List list 
= getHibernateTemplate().find(hql, params);
        
return list;
    }

    
    
/**
     * 按HQL分页查询
     * 
@param firstResult 开始记录号
     * 
@param maxResults 最大记录数
     * 
@param hql 查询语句,支持连接查询和多条件查询
     * 
@param params 参数数组,代替餐hql中的"?"号
     * 
@return 封装List和total的Pager对象
     
*/

    @SuppressWarnings(
"unchecked")
    
public Pager<T> findForPagerByHql(final int firstResult, final int maxResults, final String hql, final Object params){
        Pager
<T> pager = (Pager<T>)getHibernateTemplate().execute(new HibernateCallback(){

            
public Object doInHibernate(Session session)
                    
throws HibernateException, SQLException {
                Query query 
= session.createQuery(hql);
                
for(int position = 0; position < params.length; position ++){
                    query.setParameter(position, params[position]);
                }

                
int totalCounts = query.list().size();    //总记录数
                
//用于分页查询
                if(maxResults > 0){
                    query.setFirstResult(firstResult);
                    query.setMaxResults(maxResults);
                }

                List
<T> list = query.list();
                Pager
<T> pager = new Pager<T>();
                pager.setEntityList(list);
                pager.setTotalCounts(totalCounts);
                
return pager;
            }

        }
);
        
return pager;
    }

    

}


      相关说明:MyHibernateDaoSupport类是我自定义的类,该类继承HibernateDaoSupport,相关代码,请参考我的基于Annotation的Struts2.0+Hibernate3.3+Spring2.5整合开发 (2) ,EntityDao接口与实现类EntityDao的方法声明一样,在此暂且不贴出来.而代码中用到的Pager类,是一个封装list<Entity>和totalCounts的POJO类,代码比较简单,在此也不贴出来.
      开发本代码之前,参考过以下资料:
1)Springside的源码
2)一位北京网友发给我的项目中的代码
        (*^-^*) 本文原创,转载请注明出处, http://www.blogjava.net/rongxh7谢谢! (*^-^*)

本文原创,转载请注明出处,谢谢!http://www.blogjava.net/rongxh7(心梦帆影JavaEE技术博客)
    

posted on 2009-05-19 09:56 心梦帆影 阅读(10410) 评论(20)  编辑  收藏 所属分类: HibernateSpring

评论:
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-05-19 10:55 | xx
封装的不错,不知道会不会太细化了!  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-05-19 12:36 | 幽梦新影
不错,值得一看~~  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-05-19 16:36 | john locke
不是新轮子吧。
这种范型的dao类挺有用的  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-05-20 17:20 | 无量字幕
不错  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-05-20 20:55 | haidao
博主你要就把所有相关的代码都贴出来给新手学习嘛,哪有那样缺一部分代码,支支吾吾的,看着就冒火。这种东西javaeye上到处都是,何必搞得那样神神秘秘  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-05-21 00:31 | 心梦帆影
@haidao
1、从来没有想过要搞你所谓的"神神秘秘,支支吾吾",只是省点篇幅而已;
2、这些代码,在Blogjava,Javaeye等网站上,当然有很多类似的,多了并不一定不好,有自己的特点就行,关键的是自己能灵活运用。
3、只是看了一篇写代码的文章而已,你居然这么容易就冒火的?你可要仔细思考一下,你是不是真的适合搞这行。做Java程序员,学的东西多着呢,要看的文档也多着呢,要写的代码更多着呢,你到时候可得整天冒火冒烟了。
不过,还是感谢你的留言,贴代码表示歉意。
package rong.common.utils;
import java.util.List;
/**
* 封装分页记录的POJO类
* @author rongxinhua
*
* @param <T> 范型,表示操纵的实体
*/
public class Pager<T> {

private List<T> entityList; //对象列表
private int totalCounts; //总记录数

public List<T> getEntityList() {
return entityList;
}
public void setEntityList(List<T> entityList) {
this.entityList = entityList;
}
public int getTotalCounts() {
return totalCounts;
}
public void setTotalCounts(int totalCounts) {
this.totalCounts = totalCounts;
}
}  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-02 10:26 | leilei


有幸拜读,受益颇多,多谢多谢。

另有几处疑问,麻烦帮忙指导一下啊。

上述代码中,有几处用到final Criterion criterions的地方,例如

public List<T> findAll(final Class<T> entityClass,final String propertyName,final boolean isAsc,final Criterion criterions){

我是copy上面的代码的,看到criterions前面有几个省略号,不知道此处是否应该是final Criterion[] criterions ?这样的地方有好几处。

另有一处地方:final Object params
例如:public void update(final String hql,final Object params){
其中的final Object params是否也应该为:final Object[] params ?
  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-03 16:08 | javabeginer
大侠,您好,我现在正在学习java,可否在您空闲的时候将这个项目的源代码发给我,学习下,谢谢!dbemail@126.com  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-04 00:26 | javabeginer
您好,在使用eclipse实践您的代码时,比如用UserDao继承EntityDao,UserDaoImpl继承EntityDaoImpl实现UserDao时,有两个方法需要重写,他们分别是1、public void delete(Class entityClass, Object id) {} 2、public Object get(Class class1, Object id) {return null;},请问源代码如何改进,使方法不再需要重写。谢谢!!  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现)[未登录] 2009-06-12 16:31 | yuyu
如果把final Criterion[] criterions写成这样 那下面的方法又有问题出现,
public List<T> findByProperty(Class<T> entityClass,String propertyName,Object value){
Criterion criterion = Restrictions.eq(propertyName, value);
List<T> list = findAll(entityClass, null, true, criterion);
return list;
}

这样的话不能保持一致。 如果改啊?   回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-13 08:25 | metadmin
看看我们这个怎么样。 直接通过设计器打开数据库表,然后通过鼠标定制出SQL,而且包括了系统的权限需求。
FLASH演示:http://www.metadmin.com/download/showEmployees.html" target="_new" rel="nofollow">http://www.metadmin.com/download/showEmployees.html 演示了按照机构层级查询员工的例子。

---------------------------------
解开权限与业务耦合,提高开发效率
细粒度权限管理软件 试用版下载
http://www.metadmin.com

  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-25 14:28 | 黄燕青
封装的还不错,我也想封装。实现在DAO层里只有查询的方法,那些插入、更新和删除只在业务层调用工具类,但是还没搞定。我看了你的这句话“此EntityDao接口与EntityDaoImpl实现类,可取代了我们平时写的UserDao,NewsDao,CompanyDao等等,可直接供Service层调用”,你上面实现的不可以这样做吧,我认为你的这个实现类可以当作DAO层的基类,比如public void update(final String hql,final Object params){},拼接HQL是在DAO层中进行的,我们一般都不会在业务层中拼接,不知道我说的对不对?  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-25 14:32 | 黄燕青
还有,我建议博主这个Object ...params(相当于Object[] params),改成Map<String, Object>,我感觉这样可读性高,因为参数是有参数名和值的  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-25 18:00 | 心梦帆影
@黄燕青
可以直接供Service调用,不用再写UserDao,NewsDao,CompanyDao等了.但正如你所说的,可能会在Service层写HQL了,这样,就增大了DAO层和Service层的偶合性了,这是不好的地方.  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-25 18:04 | 心梦帆影
@黄燕青
写成可变参数的形式,直接method(param1,param2,param3)插入值就行,如果,Map<String, Object>的话,可读性强,但要通过构建Map实例,才能插入,即Map map = new HashMap();map.put("xxx","xxx"),再把它插入到method参数中method(map),两者各有优点,也各有缺点,根据需要和个人所好使用.  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-06-26 09:10 | 黄燕青
@心梦帆影
呵呵,说的有道理,java学的东西真多,哎,感觉自己学的很少。
  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-07-29 11:53 | chumq
final Criterion criterions 如何给它传值呢?不是很清楚。谢谢回答  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2009-10-29 17:18 | 379548695
是啊老大你这个final Criterion criterions
再业务层是怎么创建的啊?  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现)[未登录] 2010-07-25 18:51 | 过客
不错 很好的示例 谢了  回复  更多评论
  
# re: 奋斗两天,终于开发了自己的DAO层公共类(Spring+Hibernate实现) 2013-07-08 19:22 | www
findForPagerByHql方法中用 int totalCounts = query.list().size();获取总记录数,query.list()相当于是先查出所有的对象,如果数据量大,已经内存溢出了  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: