抽取通用的增删改的操作
- 定义接口
public interface BaseDao<T> {
public void save(T t);
public void update(T t);
public void delete(T t);
}
- 定义实现类
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
@Override
public void save(T t) {
this.getHibernateTemplate().save(t);
}
@Override
public void update(T t) {
this.getHibernateTemplate().update(t);
}
@Override
public void delete(T t) {
this.getHibernateTemplate().delete(t);
}
}
抽取一个查询一个的方法
- 在接口中定义了一个查询的方法
public T findById(Serializable id);
- 在实现类中实现查询的方法
*****如果能把具体的类型的class解决,查询所有,分页查询都可以解决!!!
解决方案一:在实现类的构造方法中传入一个Class
- 编写实现类
*****在父类中提供了有参数的构造方法,在子类中继承了父类,提供构造方法,在子类的构造中,调用父类的有参数的构造
- 在客户的DAO的实现类中
- 在联系人的DAO的实现类中
- 有了以上这些内容,将查询的所有的方法,都抽取
- 接口
public interface BaseDao<T> {
public void save(T t);
public void update(T t);
public void delete(T t);
public T findById(Serializable id);
public List<T> findAll();
public Integer findCount(DetachedCriteria detachedCriteria);
public List<T> findByPage(DetachedCriteria detachedCriteria, Integer currPage, Integer pageSize);
}
- 实现类
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class clazz;
public BaseDaoImpl() {
this.clazz = Clazz;
}
@Override
public void save(T t) {
this.getHibernateTemplate().save(t);
}
@Override
public void update(T t) {
this.getHibernateTemplate().update(t);
}
@Override
public void delete(T t) {
this.getHibernateTemplate().delete(t);
}
@Override
public T findById(Serializable id) {
return (T) this.getHibernateTemplate().get(clazz, id);
}
@Override
public List<T> findAll() {
return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());
}
@Override
public Integer findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount());
List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
if(list.size()>0) {
return list.get(0).intValue();
}
return null;
}
@Override
public List<T> findByPage(DetachedCriteria detachedCriteria, Integer currPage, Integer pageSize) {
detachedCriteria.setProjection(null);
return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, currPage, pageSize);
}
}
*****如果这样抽取完成以后,那么在编写DAO的时候如果里面都是一些CRUD操作,在DAO中只需要提供构造方法即可。
- 客户的DAO
- 联系人的DAO
如果泛型通用的DAO编写的更好,连构造方法都不想要了!!!需要怎么做???
- 泛型反射
解决方法二:通过泛型的反射抽取通用的DAO
- 如果现在将DAO中的构造方法去掉,将父类的通用的DAO中提供无参数的构造即可,但是需要在无参数的构造中需要获得具体类型的Class才可以---------涉及到泛型的反射了
- 泛型
- 泛型:通用的类型
- <>:typeof
- List<E>:E称为类型参数变量
- ArrlistList<Integer>:Integer称为是实际类型参数
- ArrayList<Integer>:ArrayList<Integer>称为参数化类型
- 需要在父类的构造方法中获得子类继承父类上的参数化类型中实际类型参数
- 泛型反射的步骤:
第一步:获得代表子类对象的class
第二部:查看API
Type[] getGenericInterfaces(); :获得带有泛型的接口,可以实现多个接口
Type[] getGenericSuperclass(); :获得带有泛型的父类,继承一个类
第三步:获得带有泛型的父类
第四步:将带有泛型的父类的类型转成具体参数化的类型
第五步:通过参数化类型的方法获得实际类型参数
package com.ithou.crm.dao.impl;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import com.ithou.crm.dao.BaseDao;
import com.ithou.crm.domain.Linkman;
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class clazz;
public BaseDaoImpl() {
//1、获得代表子类对象的Class
Class clazz = this.getClass();//正在被调用的那个Class,CustomerDaoImpl或者LinkmanDaoImpl
//2、获得带有泛型的父类
Type type = clazz.getGenericSuperclass();//参数化类型,BaseDaoImpl<Linkman>或者BaseDaoImpl<Customer>
//3、将带有泛型的父类的类型转化成参数化类型
ParameterizedType pType = (ParameterizedType)type;
//4、通过参数化类型的方法获得实际类型参数,得到一个实际类型参数的数组?Map<String,Integer>
Type[] types = pType.getActualTypeArguments();
//只获得第一个实际类型参数即可。
this.clazz = (Class) types[0];//得到Customer、User、Linkman
}
@Override
public void save(T t) {
this.getHibernateTemplate().save(t);
}
@Override
public void update(T t) {
this.getHibernateTemplate().update(t);
}
@Override
public void delete(T t) {
this.getHibernateTemplate().delete(t);
}
@Override
public T findById(Serializable id) {
return (T) this.getHibernateTemplate().get(clazz, id);
}
@Override
public List<T> findAll() {
return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());
}
@Override
public Integer findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount());
List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
if(list.size()>0) {
return list.get(0).intValue();
}
return null;
}
@Override
public List<T> findByPage(DetachedCriteria detachedCriteria, Integer currPage, Integer pageSize) {
detachedCriteria.setProjection(null);
return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, currPage, pageSize);
}
}