Hibernate【DAO重构与高级分页】

 

Hibernate重构DAO思路:

  第一步:实现通用DAO接口与实现类

    核心技术:

      (1)new 子类()的时候,子类会调用父类的构造函数,此时,父类便可以得知子类的信息

      (2)Hibernate的元数据,是描述持久化类数据的数据

  第二步:针对不同的表操作时,分别继承DAO实现类(为的是传递泛型),并不用做任何覆写

  第三步:操作什么表,调用什么Dao

 

重构DAO实例:

  第一步:通用接口与实现

  接口:

public interface CommonDao<T> {
    public List<T> getAllEntity();
    public Long getCount();
}

 

  实现类:

public class CommonDaoImpl<T> implements CommonDao<T> {
    private Class class1;
    private ClassMetadata classMetadata;
    public CommonDaoImpl() {
        ParameterizedType parameterizedType=(ParameterizedType)this.getClass().getGenericSuperclass();
        class1=(Class)parameterizedType.getActualTypeArguments()[0];
        classMetadata=HibernateUtils.sessionFactory.getClassMetadata(class1);
        
    }
    @Override
    public List<T> getAllEntity() {
        SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
        Session session=sessionFactory.openSession();
        List<T> list=session.createQuery("from "+class1.getName()).list();
        session.close();
        return list;
    }

 

  第二步:针对不同的表操作,去继承通用实现类

public class ClassesDao extends CommonDaoImpl<Classes> {}

  第三步:使用

        ClassesDao classesDao=new ClassesDao();
        System.out.println(classesDao.getAllEntity());

 


 

Hibernate预编译

  要实现分页,必须要提一下预编译,因为我需要条件的拼接,在Hibernate中预编译有两种方式。

  方式一:

     Query query=session.createQuery("from domain.Student where name=?");
        query.setParameter(0,"王二狗");

 

  方式二:

        Query query=session.createQuery("from domain.Student where name=:name");
        query.setParameter("name","王二狗");

 

 


 

Hibernate高级分页

 

  使用Hibernate高级分页,无非就是把查询条件如何写成通用的形式。难点在于怎么处理分页请求,并写出通用解决方案。

  

  用到的核心技术:抽象类的使用

 

 

(一)  设计抽象数据类型(ADT)-分页类

  我们的分页都信息都在该类的实例里面

public class PageResult<T> {
    private String url;    //需要设置的值
    private List<T> datas;    //从数据库获取的值
    /**
     * currentPage和pageSize是我们需要传入的数据,其他的数据可以通过计算获得
     */
    private int currentPage; //传递过来的值
    private int pageSize; //传递过来的值
    
    private int pageStartIndex; //构造函数中设置
    private int totalDatas; //传过来的
    private int totalPages;    //构造函数
    
    private int firstPage;
    private int lastPage;
    private int nextPage;
    private int prevPage;
    
    public PageResult(BaseQuery baseQuery,int totalDatas){
        this.currentPage=baseQuery.getCurrentPage();
        this.totalDatas=totalDatas;
        this.pageSize=baseQuery.getPageSize();
        totalPages=totalDatas%pageSize==0?totalDatas/pageSize:totalDatas/pageSize+1;
        pageStartIndex=(currentPage-1)*pageSize;
        
        /**
         * 使当前页始终在页码的中间,
         */
        if(totalPages>3){//这里的3是说,每页有几个索引
            firstPage=currentPage-1;
            lastPage=currentPage+1;
            if(firstPage<1){
                firstPage=1;
                lastPage=3;
            }
            if(lastPage>totalPages){
                firstPage=totalPages-2;
                lastPage=totalPages;
            }
        }else{
            firstPage=1;
            lastPage=totalPages;
        }
    }
PageResult

  分析:

    当前页与每页显示多少个,这两个属性是分页查询的一个指标。是我们动态传入的,所以这两个属性是不论怎么样的都要有的,而多条件查询的条件们是不确定的,我们需要让用户去动态的增加查询条件。所以我们把这些所需的分页属性封装在一起。

(二) 查询通用接口

public abstract class BaseQuery {
    public Integer currentPage;
    public Integer pageSize;
    public Map<String, Object> keyValues;
    public abstract Map<String, Object> someCondition();
        getter and setter..
}
View Code

(三) 通用接口实现类

    @Override
    public PageResult<T> getPageData(BaseQuery baseQuery) {
        SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
        Session session=sessionFactory.openSession();
        //计算总页数
        Long nums=(Long)session.createQuery("select count("+classMetadata.getIdentifierPropertyName()+") from "+class1.getName()).uniqueResult();
        //PageResult需要两个参数,内部完成了一系列计算
        PageResult<T> pageResult=new PageResult<T>(baseQuery, nums.intValue());
        //拼接查询条件
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("from "+class1.getName());
        stringBuffer.append(" where 1=1 ");
        for(Map.Entry<String, Object> entry:baseQuery.someCondition().entrySet()){
            stringBuffer.append("and "+entry.getKey()+"=:"+entry.getKey()+" ");
        }
        System.out.println("拼接的sql语句为:"+stringBuffer);
        
        Query query=session.createQuery(stringBuffer.toString());
        for(Map.Entry<String, Object> entry:baseQuery.someCondition().entrySet()){
            query.setParameter(entry.getKey(), entry.getValue());
        }
        query.setMaxResults(pageResult.getPageSize());
        query.setFirstResult(pageResult.getPageStartIndex());
        List<T> lists=query.list();
        pageResult.setDatas(lists);
        return pageResult;
    }
View Code

(四) 通用DAO

    @Override
    public PageResult<T> getPageData(BaseQuery baseQuery) {
        SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
        Session session=sessionFactory.openSession();
        //计算总页数
        Long nums=(Long)session.createQuery("select count("+classMetadata.getIdentifierPropertyName()+") from "+class1.getName()).uniqueResult();
        //PageResult需要两个参数,内部完成了一系列计算
        PageResult<T> pageResult=new PageResult<T>(baseQuery, nums.intValue());
        //拼接查询条件
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("from "+class1.getName());
        stringBuffer.append(" where 1=1 ");
        for(Map.Entry<String, Object> entry:baseQuery.getKeyValues().entrySet()){
            stringBuffer.append("and "+entry.getKey()+"=:"+entry.getKey()+" ");
        }
        System.out.println("拼接的sql语句为:"+stringBuffer);
        
        Query query=session.createQuery(stringBuffer.toString());
        for(Map.Entry<String, Object> entry:baseQuery.getKeyValues().entrySet()){
            query.setParameter(entry.getKey(), entry.getValue());
        }
        query.setMaxResults(pageResult.getPageSize());
        query.setFirstResult(pageResult.getPageStartIndex());
        List<T> lists=query.list();
        pageResult.setDatas(lists);
        return pageResult;
    }
View Code

(五)   使用

StudentDao studentDao=new StudentDao();
        
        StudentQuery studentQuery=new StudentQuery();
        studentQuery.setName("小花");
        
        studentQuery.setCurrentPage(2);
        studentQuery.setPageSize(2);
    
        PageResult<Student> pageResult=studentDao.getPageData(studentQuery);
        List<Student> students=pageResult.getDatas();
        for(Student s:students){
            System.out.println(s.getId());
        }
View Code

 

posted @ 2016-01-18 01:39  a617475430  阅读(443)  评论(0编辑  收藏  举报