在持久层框架中,如果我们要像简单的JDBC连接数据库那样写一个通用的Dao方法的话,那么把JDBC简单的业务逻辑搬到hibernate持久层框架中,当然是不可能的,这里主要的问题就在于hibernate持久层框架中,因为它不是像JDBC那样简单的增删改查的编写,而是要针对实体类映射配置文件来对照数据库表字段进行操作,而且操作是面向对象的查询,不是简单的sql语句的查询,这样我们的通用DAO模式就不能是简单的JDBC思路了。
试想,项目底层的通用DAO接口方法,是适用于所有实体类对象应用的,而且数据库读取的所有实体类集合也是一个通用的类模型。这样,和简单的JDBC模式不同的基础上,hibernate通用的DAO模型,就需要我们利用反射序列化的技术机制来完成。因此无论是插入的类对象和读取的类模型信息,通过反射序列化来获取。具体的操作流程如下:
首先,在我们的通用DAO接口中,体现出所有通用功能的方法名外,我们需要定义的另外一个技术,就是泛型类编程模式,我们需要给类加上类型,也就是给类加上泛型模式编程。另外,在泛型中,需要定义两个属性,1是给类加一个继承序列化的变量,和给主键ID继承的一个序列化。因此反射DAO接口如下:
publicinterface IGenericDao<T extends Serializable,ID extends Serializable>
另外,所有的功能方法名,随之也会有所更改,例如我们添加一条信息时候,之前的参数是需要具体的实体类对象,而现在则是泛型的属性为实体类的对象,如下:
public T create(T entity);返回值也是一样。
因此在通用DAO接口如图:
具体的类实现中,除了实现该通用的DAO接口外,还需要自身的泛型编程和继承HibernateDaoSupport父类,因此实现类的方法名为:
publicclass 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实例来获取具体查询的结果集合。
因此实现类的代码大致如下:
publicclass 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() {
returnpersistentClass;
}
publicvoid setPersistentClass(Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
@Override
public T create(T entity) {
return (T) this.getHibernateTemplate().save(entity);
}
@Override
publicvoid delete(ID id) {
//删除通用方法 参数为要删除的实体类对象
System.out.println("IDD "+id);
this.getHibernateTemplate().delete(this.findById(id));
}
@Override
publicvoid update(T entity) {
this.getHibernateTemplate().update(entity);
}
@Override
public T findById(ID id) {
returnthis.getHibernateTemplate().get(persistentClass, id);
}
@Override
public List<T> findAll() {
returnthis.getHibernateTemplate().loadAll(persistentClass);
}
@Override
public List<T> findByObject(String hql, Object[] param) {
returnthis.getHibernateTemplate().find(hql, param);
}
@Override
public PageBean findByPageBean(final String hql,final Object[] param,final int currentpage,finalint pageSize) {
returnthis.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
publicvoid bulkUpdate(String bulk, Object[] param) {
this.getHibernateTemplate().bulkUpdate(bulk,param);
}
@Override
public Integer countByObject(final String hql,final Object[] param) {
returnthis.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
相关推荐
本篇文章将深入探讨Hibernate的通用Dao设计,帮助开发者理解如何利用Hibernate提高代码复用性和可维护性。 在传统的Java应用程序中,DAO(Data Access Object)层是用于封装数据库访问逻辑的地方,它隔离了业务逻辑...
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全栈开发),有任何使用问题欢迎随时与我联系,我会及时为您解惑,...
总的来说,这个"SpringHibernate万能DAO组件"是一个为了简化Spring和Hibernate集成而设计的工具,通过反射和动态SQL构建,提高了开发效率,降低了SSH框架组合项目的复杂性。使用该组件,开发者可以更快速地实现数据...
自定义Dao并通过反射实现,虽然比使用ORM框架(如Hibernate、MyBatis)更繁琐,但可以更好地控制SQL语句,避免了不必要的映射配置。这种方法适用于小型项目或对性能有较高要求的场景,同时也为学习Java反射机制提供...
DAO设计模式是将数据访问逻辑与业务逻辑分离,提高代码的可复用性和可测试性。 首先,我们需要理解DAO的基本概念。DAO是应用程序中负责与数据库交互的组件,它封装了SQL查询和其他数据库操作,使得业务层可以专注于...
DAO模式是一种软件设计模式,它的主要目标是为应用程序提供一个抽象层,以便与数据库交互。通过使用DAO,我们可以将业务逻辑与数据存储细节分离,使得代码更加模块化,更容易测试和维护。 在Java中,DAO通常包含一...
本主题主要探讨的是如何使用泛型和反射技术来实现Hibernate对DAO的封装,从而创建一个通用的DAO模板,减少开发者重复编写CRUD(Create、Read、Update、Delete)操作的工作。 首先,我们需要理解DAO(Data Access ...
泛型通用DAO是这种模式的一种优化,它利用了Java 5.0引入的泛型和反射机制,大大简化了DAO层的编码工作,提高了代码的可复用性和可维护性。 泛型是Java中的一种类型系统扩展,它允许在编译时声明参数化的类型,从而...
DAO模式是将业务逻辑与数据库操作分离的一种设计模式,它使得应用代码可以独立于具体的数据库实现。然而,如果不加以控制,DAO层的代码可能会变得冗余,导致不必要的复杂性和维护问题。 首先,我们需要理解DAO的...
泛型DAO模式是基于Java泛型技术的一种设计模式,它在数据访问层提供了一种更为通用且灵活的方式来操作数据库。 传统的DAO模式通常需要为每一种数据实体类创建一个对应的DAO接口和实现类,这样会导致大量重复的代码...
总结,这个实例让我们深入了解了Java中直接进行数据库操作的机制,包括反射API的使用、SQL语句的构造以及DAO模式的应用。虽然这种方式需要编写更多代码,但可以提供更高的灵活性和对数据库操作的控制。而Hibernate等...
泛型DAO模式也常被用于开发工具库,比如一些自动化的代码生成工具,它们可以根据数据库表结构自动生成对应的泛型DAO和实体类,减轻开发人员的工作负担。此外,还有一些IDE插件也能帮助生成这些代码。 至于压缩包中...
在SSH CRM项目中,Hibernate作为持久层框架,用于管理和操作数据字典,是数据库与Java对象之间的一个桥梁。本节将深入探讨SSH CRM项目中Hibernate如何实现数据字典的高效、便捷操作。SSH架构是由Spring、Struts和...
在编程领域,控制反转(Inversion of Control,简称IoC)是一种设计模式,它将对象的创建和管理责任从应用程序转移到框架或容器中。在Java编程中,IoC通过依赖注入(Dependency Injection,DI)来实现,使得组件之间...
2. 数据访问对象(DAO)模式支持:通过Hibernate,我们可以创建DAO层,将数据操作封装起来,使代码更易于维护和测试。 3. 支持多种数据库:Hibernate4兼容多种主流的关系型数据库,如MySQL、Oracle、PostgreSQL等,...
传统的DAO实现,需要为每个实体类(例如User)创建一个独立的DAO类(例如UserDao),并在其中编写具体的SQL语句或使用ORM框架(如Hibernate、MyBatis)进行映射。 在这个"封转dao层"的方法中,开发者只需要提供实体...
在Java开发中,BaseDao和BaseDaoImpl是常见的设计模式,它们主要用于数据库操作,尤其是在使用ORM框架如Hibernate时。这两个类通常作为数据访问对象(DAO)的基类,旨在简化和标准化对数据库的CRUD(创建、读取、...
于是,使用Facade模式和反射技术模拟Hibernate框架技术演示怎样书封装数据库的操作。 环境:Windows XP Professional, JDK 1.6, Eclipse 3.3 Europa, SQL Server 2000 使用步骤: 1. 下载解压之后,使用Eclipse导入...
2. Hibernate的使用理由:封装JDBC、简化DAO层、基于反射、性能优秀、支持多种关系。 3. Hibernate的延迟加载:实体对象和集合的延迟加载策略,以及在何时真正加载数据以提高性能。 4. Struts1的流程:MVC模式下的...
编写Hibernate的DAO层代码,实现对数据库的基本操作。 #### 三、整合实践中的技巧 - **从ActionForm到JavaBean的转换**:使用Apache Commons的BeanUtils类可以轻松地将ActionForm中的数据转换为JavaBean对象,简化...