在持久层框架中,若是咱们要像简单的JDBC链接数据库那样写一个通用的Dao方法的话,那么把JDBC简单的业务逻辑搬到hibernate持久层框架中,固然是不可能的,这里主要的问题就在于hibernate持久层框架中,由于它不是像JDBC那样简单的增删改查的编写,而是要针对实体类映射配置文件来对照数据库表字段进行操做,并且操做是面向对象的查询,不是简单的sql语句的查询,这样咱们的通用DAO模式就不能是简单的JDBC思路了。 java
试想,项目底层的通用DAO接口方法,是适用于全部实体类对象应用的,并且数据库读取的全部实体类集合也是一个通用的类模型。这样,和简单的JDBC模式不一样的基础上,hibernate通用的DAO模型,就须要咱们利用反射序列化的技术机制来完成。所以不管是插入的类对象和读取的类模型信息,经过反射序列化来获取。具体的操做流程以下: sql
首先,在咱们的通用DAO接口中,体现出全部通用功能的方法名外,咱们须要定义的另一个技术,就是泛型类编程模式,咱们须要给类加上类型,也就是给类加上泛型模式编程。另外,在泛型中,须要定义两个属性,1是给类加一个继承序列化的变量,和给主键ID继承的一个序列化。所以反射DAO接口以下: 数据库
public interface
IGenericDao<T extends Serializable,ID extends Serializable> 编程
另外,全部的功能方法名,随之也会有所更改,例如咱们添加一条信息时候,以前的参数是须要具体的实体类对象,而如今则是泛型的属性为实体类的对象,以下: session
public T create(T entity);返回值也是同样。 框架
所以在通用DAO接口如图: ide
具体的类实现中,除了实现该通用的DAO接口外,还须要自身的泛型编程和继承HibernateDaoSupport父类,所以实现类的方法名为: this
public class
GenericHibernateDao<T extends
Serializable,ID extends Serializable> extends HibernateDaoSupport implements
IGenericDao<T, ID>。 spa
所以例如在插入数据时候实现类代码则是: hibernate
@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