zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Openstack的项目管理方案
    Openstack的web管理端相关
    Openstack安全规则说明
    Openstack命令行删除虚拟机硬件模板flavor
    [转]java中的Static class
    [转]Activitys, Threads, & Memory Leaks
    [转]How to Leak a Context: Handlers & Inner Classes
    [原]Android打包之Eclipse打多渠道包
    [转]ubuntu下整合eclipse和javah生成jni头文件开发android的native程序
    Nao 类人机器人 相关资料
  • 原文地址:https://www.cnblogs.com/xingdongpai/p/5137512.html
Copyright © 2011-2022 走看看