Hibernate反射DAO模式

在持久层框架中,如果我们要像简单的JDBC连接数据库那样写一个通用的Dao方法的话,那么把JDBC简单的业务逻辑搬到hibernate持久层框架中,当然是不可能的,这里主要的问题就在于hibernate持久层框架中,因为它不是像JDBC那样简单的增删改查的编写,而是要针对实体类映射配置文件来对照数据库表字段进行操作,而且操作是面向对象的查询,不是简单的sql语句的查询,这样我们的通用DAO模式就不能是简单的JDBC思路了。

试想,项目底层的通用DAO接口方法,是适用于所有实体类对象应用的,而且数据库读取的所有实体类集合也是一个通用的类模型。这样,和简单的JDBC模式不同的基础上,hibernate通用的DAO模型,就需要我们利用反射序列化的技术机制来完成。因此无论是插入的类对象和读取的类模型信息,通过反射序列化来获取。具体的操作流程如下:

首先,在我们的通用DAO接口中,体现出所有通用功能的方法名外,我们需要定义的另外一个技术,就是泛型类编程模式,我们需要给类加上类型,也就是给类加上泛型模式编程。另外,在泛型中,需要定义两个属性,1是给类加一个继承序列化的变量,和给主键ID继承的一个序列化。因此反射DAO接口如下:

public interface IGenericDao<T extends Serializable,ID extends Serializable>

另外,所有的功能方法名,随之也会有所更改,例如我们添加一条信息时候,之前的参数是需要具体的实体类对象,而现在则是泛型的属性为实体类的对象,如下:

public T create(T entity);返回值也是一样。

因此在通用DAO接口如图:

                       

具体的类实现中,除了实现该通用的DAO接口外,还需要自身的泛型编程和继承HibernateDaoSupport父类,因此实现类的方法名为:

public class GenericHibernateDao<T extends Serializable,ID extends Serializable> extends HibernateDaoSupport  implements IGenericDao<T, ID>。

因此例如在插入数据时候实现类代码则是:

@Override

    public T create(T entity) {

       return (T) this.getHibernateTemplate().save(entity);

    }

这里反射序列化的类对象T,作为通用Dao接口的实现类实体类通用类型,但是在实现类的查询中,也就是读取中,我们也需要获取一个反射序列化的通过实体类对象模型,这就是需要反射的Class实例对象了,因此在通用DAO接口的实现类中,我们需要创建一个Class实例对象,这个对象中我们需要的泛型类型是反射序列化的实体类对象模型T,因此这个对象为

Class<T> persistentClass;  

但是我们还需要这个Class实例对象来获取反射序列化的具体对象模型,这就需要我们通过java底层对象类型来获取了,具体为

this.persistentClass=

(Class<T>)(ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

这里面1. getClass().getGenericSuperclass():获取java最底层类对象  

2. (ParameterizedType)getClass().getGenericSuperclass()):转换为可序列化类型

3. .getActualTypeArguments()[0]  反射出第一个参数对象信息,也就是获取类泛型中T extends Serializable

4. (Class<T>):强转为当前类对象

通过这些复杂的过程,我们可以获取反射序列化的具体Class实例类型,这样就可以通过该Class实例来获取具体查询的结果集合。

因此实现类的代码大致如下:

public class GenericHibernateDao<T extends Serializable,ID extends Serializable>

                     extends HibernateDaoSupport  implements IGenericDao<T, ID> {

   Class<T> persistentClass;     

   public GenericHibernateDao() {

      //                强转为当前类对象,转换为可序列化类型,                        获取java最底层类对象                     反射出第一个参数对象信息                                               

      this.persistentClass=(Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

   }

   public Class<T> getPersistentClass() {

      return persistentClass;

   }

   public void setPersistentClass(Class<T> persistentClass) {

      this.persistentClass = persistentClass;

   }

   @Override

   public T create(T entity) {

      return (T) this.getHibernateTemplate().save(entity);

   }

   @Override

   public void delete(ID id) {

      //删除通用方法                             参数为要删除的实体类对象

      System.out.println("IDD "+id);

      this.getHibernateTemplate().delete(this.findById(id));

   }

   @Override

   public void update(T entity) {

       this.getHibernateTemplate().update(entity);

   }

   @Override

   public T findById(ID id) {

      return this.getHibernateTemplate().get(persistentClass, id);

   }

   @Override

   public List<T> findAll() {

      return this.getHibernateTemplate().loadAll(persistentClass);

   }

   @Override

   public List<T> findByObject(String hql, Object[] param) {

      return this.getHibernateTemplate().find(hql, param);

   }

   @Override

   public PageBean findByPageBean(final String hql,final  Object[] param,final  int currentpage,final int pageSize) {

      return this.getHibernateTemplate().execute(new HibernateCallback<PageBean>() {

         @Override

         public PageBean doInHibernate(Session session)throws HibernateException, SQLException {

            //创建pagebean对象

            PageBean pb=new PageBean();

            //通过Query对象来获取所需要页的数据

            Query qu=session.createQuery(hql);

            //赋值参数

            if(param.length>0){

                for (int i = 0; i < param.length; i++) {

                   qu.setParameter(i, param[i]);

                }

            }

            //为Query对象,赋值从第几行到第几行参数,也就是最大最小页数值

            qu.setFirstResult((currentpage-1)*pageSize);

            qu.setMaxResults(pageSize);

            //给PageBean对象,赋值list参数

            pb.setData(qu.list());

            //获取总行数                                 

            qu=session.createQuery("select count(*) "+hql.substring(hql.toLowerCase().indexOf("from")));

            //赋值获取总行数参数

            if(param.length>0){

               for (int j = 0; j < param.length; j++) {

                   qu.setParameter(j, param[j]);

               }              

            }

            //Pagebean赋值总行数参数

            pb.setTotalRows(Integer.parseInt(qu.uniqueResult().toString()));

            //Pagebean赋值当前页参数

            pb.setCurrentPage(currentpage);

            //Pagebean赋值每页大小参数

            pb.setPageSize(pageSize);

            //返回pagebean对象

            return pb;

         }

      });

   }

   @Override

   public void bulkUpdate(String bulk, Object[] param) {

      this.getHibernateTemplate().bulkUpdate(bulk,param);

   }

   @Override

   public Integer countByObject(final String hql,final Object[] param) {

      return this.getHibernateTemplate().execute(new HibernateCallback<Integer>() {

            //获取hibernateSessionFactory接口方法  

         @Override

         public Integer doInHibernate(Session session)throws HibernateException, SQLException {

            //通过HIbernateQuery方法来获取count值

            Query qu=session.createQuery(hql);

            for (int i = 0; i < param.length; i++) {

                qu.setParameter(i, param[i]);

            }

            return Integer.parseInt(qu.uniqueResult().toString());          

         }

      });

   }

}

  以上是反射DAO模式的实现类及接口的核心代码,通过具体的实体类对象来获取具体的类对象集合,就可以实现具体的通过DAO反射序列化的接口及实现类的效果。

  作者:中软卓越天津ETC

转载于:https://www.cnblogs.com/zretc/p/3199870.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值