在进行SSH整合开发的过程中,发现DAO层操作数据库有相同的操作:
1、插入新的数据记录
2、更新数据记录
3、删除数据记录
(上面这三个方法的参数传入的都是对象)
4、根据id查询数据库中的数据记录(参数:Serializable id,返回对象)
5、查询一个数据表中的所有数据记录(无参,返回List)
6、统计数据表中的数据记录个数(参数:DetachedCriteria detachedCriteria,返回Integer)
7、分页查询的数据记录(参数:DetachedCriteria detachedCriteria,Integer begin,Integer pageSize,返回List)
第一阶段:抽取增删改方法
step1:抽取BaseDao接口
接口定义的方法:插入数据记录save()、更新数据记录update()、删除数据记录delete()
packagecom.sty.crm.dao;public interface BaseDao{/*** 插入数据记录
*@paramt*/
public voidsave(T t) ;/*** 更新数据记录
*@paramt*/
public voidupdate(T t) ;/*** 删除数据记录
*@paramt*/
public voiddelete(T t) ;
}
View Code
step2:实现类BaseDaoImpl
packagecom.sty.crm.dao.impl;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.BaseDao;public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao{
@Override/*** 插入数据记录*/
public voidsave(T t) {this.getHibernateTemplate().save(t) ;
}
@Override/*** 更新数据记录*/
public voidupdate(T t) {this.getHibernateTemplate().update(t);
}
@Override/*** 删除数据记录*/
public voiddelete(T t) {this.getHibernateTemplate().delete(t);
}
}
View Code
step3:修改DAO层中的实现类和接口
接口继承BaseDao接口
实现类原来是继承HibernateDaoSupport类,该为继承BaseDaoImpl
CustomerDao.java
packagecom.sty.crm.dao;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importcom.sty.crm.domain.Customer;public interface CustomerDao extends BaseDao{//继承BaseDao接口就不用定义下面的三个方法,因为BaseDao接口中已经定义了//void save(Customer customer);//void delete(Customer customer);//void update(Customer customer);
Integer findCount(DetachedCriteria detachedCriteria);
ListfindByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize);
Customer findById(Long cust_id);
ListfindAll();
}
View Code
CustomerDaoImpl.java
packagecom.sty.crm.dao.impl;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importorg.hibernate.criterion.Projection;importorg.hibernate.criterion.Projections;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.CustomerDao;importcom.sty.crm.domain.Customer;public class CustomerDaoImpl extends BaseDaoImpl implementsCustomerDao {//继承BaseDaoImpl实现类就不用实现下面的三个方法,因为BaseDaoImpl中已经实现了
/*@Override
public void save(Customer customer) {
System.out.println("+++++++++++++");
System.out.println(customer.getBaseDictIndustry().getDict_id());
this.getHibernateTemplate().save(customer) ;
}*/
/*@Override*//*** 根据客户对象删除客户*//*public void delete(Customer customer) {
this.getHibernateTemplate().delete(customer);
}*/
/*@Override
public void update(Customer customer) {
this.getHibernateTemplate().update(customer);
}*/
//-----------------------------------
@Override//DAO中带条件统计个数的方法
publicInteger findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount()) ;
List list = (List) this.getHibernateTemplate().findByCriteria(detachedCriteria) ;if(list.size()>0) {return list.get(0).intValue() ;
}return null;
}
@Override//DAO中分页查询客户的方法
public ListfindByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) {
detachedCriteria.setProjection(null) ;//清空之前统计个数的条件
return (List) this.getHibernateTemplate().findByCriteria(detachedCriteria,begin,pageSize) ;
}
@Override/*** 根据客户的id查询客户记录*/
publicCustomer findById(Long cust_id) {return this.getHibernateTemplate().get(Customer.class, cust_id);
}
@Override/*** 查询所有的客户*/
public ListfindAll() {return (List) this.getHibernateTemplate().find("from Customer");
}
}
View Code
以此类推修改DAO层的接口和实现类
第二阶段:抽取查询方法
主要核心:获取要查询的数据表对应的类的class属性
BaseDao接口
packagecom.sty.crm.dao;importjava.io.Serializable;public interface BaseDao{/*** 插入数据记录
*@paramt*/
public voidsave(T t) ;/*** 更新数据记录
*@paramt*/
public voidupdate(T t) ;/*** 删除数据记录
*@paramt*/
public voiddelete(T t) ;/*** 根据id查询数据库的一条记录*/
publicT findById(Serializable id) ;
}
View Code
解决方案一:在实现类的构造方法中传入一个Class
step1:BaseDaoImpl
提供构造方法:在构造方法中传入具体类型的class,实现按照id查询数据记录
packagecom.sty.crm.dao.impl;importjava.io.Serializable;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.BaseDao;public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao{privateClass clazz ;//提供构造方法:在构造方法中传入具体类型的class
publicBaseDaoImpl(Class clazz) {this.clazz =clazz ;
}
@Override/*** 插入数据记录*/
public voidsave(T t) {this.getHibernateTemplate().save(t) ;
}
@Override/*** 更新数据记录*/
public voidupdate(T t) {this.getHibernateTemplate().update(t);
}
@Override/*** 删除数据记录*/
public voiddelete(T t) {this.getHibernateTemplate().delete(t);
}
@OverridepublicT findById(Serializable id) {return (T) this.getHibernateTemplate().get(clazz, id) ;
}
}
View Code
PS:在父类中提供了有参数的构造方法,在子类中继承了父类,提供构造方法,在子类的构造中,调用父类的有参数的构造。
step2:修改DAO层的接口和实现类
CustomerDao.java接口:在接口中去掉根据id查询数据记录的方法的定义
packagecom.sty.crm.dao;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importcom.sty.crm.domain.Customer;public interface CustomerDao extends BaseDao{//继承BaseDao接口就不用定义下面的方法,因为BaseDao接口中已经定义了//void save(Customer customer);//void delete(Customer customer);//void update(Customer customer);//Customer findById(Long cust_id);
Integer findCount(DetachedCriteria detachedCriteria);
ListfindByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize);
ListfindAll();
}
View Code
CustomerDaoImpl.java实现类:
在实现类中去掉根据id查询数据记录的方法的实现(BaseDaoImpl.java中已经实现了),提供构造方法,调用父类的有参数的构造,传入Class类型对象
packagecom.sty.crm.dao.impl;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importorg.hibernate.criterion.Projection;importorg.hibernate.criterion.Projections;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.CustomerDao;importcom.sty.crm.domain.Customer;public class CustomerDaoImpl extends BaseDaoImpl implementsCustomerDao {publicCustomerDaoImpl() {super(Customer.class);
}//继承BaseDaoImpl实现类就不用实现下面的三个方法,因为BaseDaoImpl中已经实现了
/*@Override
public void save(Customer customer) {
System.out.println("+++++++++++++");
System.out.println(customer.getBaseDictIndustry().getDict_id());
this.getHibernateTemplate().save(customer) ;
}*/
/*@Override*//*** 根据客户对象删除客户*//*public void delete(Customer customer) {
this.getHibernateTemplate().delete(customer);
}*/
/*@Override
public void update(Customer customer) {
this.getHibernateTemplate().update(customer);
}*/
/*@Override*//*** 根据客户的id查询客户记录*//*public Customer findById(Long cust_id) {
return this.getHibernateTemplate().get(Customer.class, cust_id);
}*/
//-----------------------------------
@Override//DAO中带条件统计个数的方法
publicInteger findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount()) ;
List list = (List) this.getHibernateTemplate().findByCriteria(detachedCriteria) ;if(list.size()>0) {return list.get(0).intValue() ;
}return null;
}
@Override//DAO中分页查询客户的方法
public ListfindByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) {
detachedCriteria.setProjection(null) ;//清空之前统计个数的条件
return (List) this.getHibernateTemplate().findByCriteria(detachedCriteria,begin,pageSize) ;
}
@Override/*** 查询所有的客户*/
public ListfindAll() {return (List) this.getHibernateTemplate().find("from Customer");
}
}
View Code
以此类推修改DAO层的接口和实现类
第三阶段:抽取所有的方法
step1:BaseDao接口
packagecom.sty.crm.dao;importjava.io.Serializable;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;public interface BaseDao{/*** 插入数据记录
*@paramt*/
public voidsave(T t) ;/*** 更新数据记录
*@paramt*/
public voidupdate(T t) ;/*** 删除数据记录
*@paramt*/
public voiddelete(T t) ;/*** 根据id查询数据库的一条记录*/
publicT findById(Serializable id) ;/***查询所有记录*/
public ListfindAll() ;/*** 统计数据记录个数的方法*/
publicInteger findCount(DetachedCriteria detachedCriteria) ;/*** 分页查询的方法*/
public ListfindByPage(DetachedCriteria detachedCriteria,Integer begin,Integer pageSize) ;
}
View Code
解决方案二:通过泛型的反射抽取通用的DAO
泛型
泛型 :通用的类型。
<> :念为 typeof
List :E称为类型参数变量
ArrayList :Integer称为是实际类型参数
ArrayList :ArrayList称为参数化类型
方法
Type[] getGenericInterfaces(); :获得带有泛型的接口,可以实现多个接口。
Type getGenericSuperclass(); :获得带有泛型的父类,继承一个类。
step2:BaseDaoImpl
在构造方法中通过反射获取运行类的父类中的类型参数变量,即:例如Customer、LinkMan的实体类,然后获取实体类的Class对象,并赋值给BaseDaoImpl中定义的属性class即可
packagecom.sty.crm.dao.impl;importjava.io.Serializable;importjava.lang.reflect.ParameterizedType;importjava.lang.reflect.Type;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importorg.hibernate.criterion.Projections;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.BaseDao;public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao{privateClass clazz ;//提供构造方法:在构造方法中传入具体类型的class
/*** 在构造方法中利用反射获取原来需要传递的参数clazz,
* 就不需要在子类调用父类的构造方法传入参数了
*@paramclazz*/
publicBaseDaoImpl() {//获取运行类的Class对象
Class clazz = this.getClass() ;//获取到的是实际运行类的Class,比如CustomerDaoImpl或LinkManDaoImpl//通过Class对象获取父类的参数化类型//比如:BaseDaoImpl,BaseDaoImpl//注意Type是Class的父接口
Type type =clazz.getGenericSuperclass() ;//type就是一个参数化类型,将type强转为参数化类型
ParameterizedType pType =(ParameterizedType) type ;//通过参数化类型获取实际类型参数//注意得到的是一个实际类型参数的数组
Type[] types =pType.getActualTypeArguments() ;//程序中传入的实际类型参数只有一个
this.clazz = (Class) types[0] ;
}
@Override/*** 插入数据记录*/
public voidsave(T t) {this.getHibernateTemplate().save(t) ;
}
@Override/*** 更新数据记录*/
public voidupdate(T t) {this.getHibernateTemplate().update(t);
}
@Override/*** 删除数据记录*/
public voiddelete(T t) {this.getHibernateTemplate().delete(t);
}
@Override/*** 根据id查询一条数据记录*/
publicT findById(Serializable id) {return (T) this.getHibernateTemplate().get(clazz, id) ;
}
@Override/*** 统计数据记录个数的方法*/
publicInteger findCount(DetachedCriteria detachedCriteria) {//设置统计个数的条件
detachedCriteria.setProjection(Projections.rowCount()) ;
List list = (List) this.getHibernateTemplate().findByCriteria(detachedCriteria) ;if(list.size()>0) {return list.get(0).intValue() ;
}return null;
}
@Override/*** 分页查询*/
public ListfindByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) {//因为在执行分页查询之前一般都要要查询总的记录数,//此处清空设置统计个数的条件(即使之前没有设置统计个数的条件,也可以清空一下)
detachedCriteria.setProjection(null) ;return (List) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize) ;
}
@Overridepublic ListfindAll() {return (List) this.getHibernateTemplate().find("from "+clazz.getSimpleName()) ;
}
}
View Code
step3:修改DAO层中的实现类和接口
UserDao.java接口
packagecom.sty.crm.dao;importcom.sty.crm.domain.User;public interface UserDao extends BaseDao{//因为继承BaseDao接口//void save(User user);
User login(User user);
}
View Code
UserDaoImpl.java实现类
packagecom.sty.crm.dao.impl;importjava.util.List;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.UserDao;importcom.sty.crm.domain.User;public class UserDaoImpl extends BaseDaoImpl implementsUserDao {//因为继承BaseDaoImpl类
/*@Override
//在DAO中使用Hibernate模板保存记录
public void save(User user) {
this.getHibernateTemplate().save(user) ;
}*/@Override//根据用户名和密码查询用户
publicUser login(User user) {
String sql= "from User where user_code=? and user_password=?";
List list = (List) this.getHibernateTemplate().find(sql,user.getUser_code(),user.getUser_password()) ;//判断是否查询到有记录
if(list.size() > 0) {return list.get(0) ;
}return null;
}
}
View Code
CustomerDao.java接口
packagecom.sty.crm.dao;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importcom.sty.crm.domain.Customer;public interface CustomerDao extends BaseDao{//继承BaseDao接口就不用定义下面的方法,因为BaseDao接口中已经定义了//void save(Customer customer);//void delete(Customer customer);//void update(Customer customer);//Customer findById(Long cust_id);//Integer findCount(DetachedCriteria detachedCriteria);//List findByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize);//List findAll();
}
View Code
CustomerDaoImpl.java实现类
packagecom.sty.crm.dao.impl;importjava.util.List;importorg.hibernate.criterion.DetachedCriteria;importorg.hibernate.criterion.Projection;importorg.hibernate.criterion.Projections;importorg.springframework.orm.hibernate5.support.HibernateDaoSupport;importcom.sty.crm.dao.CustomerDao;importcom.sty.crm.domain.Customer;public class CustomerDaoImpl extends BaseDaoImpl implementsCustomerDao {/*public CustomerDaoImpl() {
super(Customer.class);
}*/
//继承BaseDaoImpl实现类就不用实现下面的三个方法,因为BaseDaoImpl中已经实现了
/*@Override
public void save(Customer customer) {
System.out.println("+++++++++++++");
System.out.println(customer.getBaseDictIndustry().getDict_id());
this.getHibernateTemplate().save(customer) ;
}*/
/*@Override*//*** 根据客户对象删除客户*//*public void delete(Customer customer) {
this.getHibernateTemplate().delete(customer);
}*/
/*@Override
public void update(Customer customer) {
this.getHibernateTemplate().update(customer);
}*/
/*@Override*//*** 根据客户的id查询客户记录*//*public Customer findById(Long cust_id) {
return this.getHibernateTemplate().get(Customer.class, cust_id);
}*/
//-----------------------------------
/*@Override
//DAO中带条件统计个数的方法
public Integer findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount()) ;
List list = (List) this.getHibernateTemplate().findByCriteria(detachedCriteria) ;
if(list.size()>0) {
return list.get(0).intValue() ;
}
return null;
}*/
/*@Override
//DAO中分页查询客户的方法
public List findByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) {
detachedCriteria.setProjection(null) ;//清空之前统计个数的条件
return (List) this.getHibernateTemplate().findByCriteria(detachedCriteria,begin,pageSize) ;
}*/
/*@Override*//*** 查询所有的客户*//*public List findAll() {
return (List) this.getHibernateTemplate().find("from Customer");
}*/}
View Code
以此类推修改DAO层的接口和实现类
zwy