有時候我們在實現不同功能的時候回看到很多的Dao層的增加、修改、刪除、查找都很相似,修改我們將他們提取BaseDao
一、提取前
1. 提取前的LinkDao層:
public interface LinkManDao {
Integer findCount(DetachedCriteria detachedCriteria);
List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);
void save(LinkMan linkMan);
LinkMan findById(Long lkm_id);
void update(LinkMan linkMan);
void delete(LinkMan linkMan);
}
2. 提取前的LinkDaoImpl:
@Repository
public class LinkManDaoImpl implements LinkManDao {
@Autowired
private HibernateTemplate hibernateTemplate;
@Override
public Integer findCount(DetachedCriteria detachedCriteria) {
//select count(*) from LinkMan
detachedCriteria.setProjection(Projections.rowCount());
List list = (List) hibernateTemplate.findByCriteria(detachedCriteria);
if(list != null && list.size() > 0) {
return list.get(0).intValue();
}
return null;
}
@Override
public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
detachedCriteria.setProjection(null);
return (List) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
}
@Override
public void save(LinkMan linkMan) {
hibernateTemplate.save(linkMan);
}
//Dao層根據id查找聯系人
@Override
public LinkMan findById(Long lkm_id) {
return hibernateTemplate.get(LinkMan.class, lkm_id);
}
//Dao層更新聯系人信息
@Override
public void update(LinkMan linkMan) {
hibernateTemplate.update(linkMan);
}
//Dao層刪除聯系人
@Override
public void delete(LinkMan linkMan) {
hibernateTemplate.delete(linkMan);
}
}
3. 提取前的CustomerDao
public interface CustomerDao{
void save(Customer customer);
Integer findCount(DetachedCriteria detachedCriteria);
List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);
Customer findById(Long cust_id);
void delete(Customer customer);
void update(Customer customer);
List findAll();
}
4.提取前的CustomerDaoImpl
@Repository
public class CustomerDaoImpl implements CustomerDao {
//注入hibernateTemplate模板
@Autowired
private HibernateTemplate hibernateTemplate;
/**
* Dao層保存客戶信息實現方法
*
Title: CustomerDaoImpl
*
Description:
* @param customer
* @see com.sshcrm.dao.CustomerDao#saveCustomer(com.sshcrm.pojo.Customer)
*/
@Override
public void saveCustomer(Customer customer) {
hibernateTemplate.save(customer);
}
//根據條件查詢結果集的總記錄數
@Override
public Integer findCount(DetachedCriteria detachedCriteria) {
//select count(*) from Customer
detachedCriteria.setProjection(Projections.rowCount());
List list = (List) hibernateTemplate.findByCriteria(detachedCriteria);
if(list != null && list.size() > 0) {
return list.get(0).intValue();
}
return null;
}
//根據查詢條件查詢總頁數
@Override
public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
//由于在統計總記錄數的時候已經修改了發送的SQL語句,在此需要需要清空
detachedCriteria.setProjection(null);
return (List) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
}
@Override
public Customer findById(Long cust_id) {
return hibernateTemplate.get(Customer.class, cust_id);
}
@Override
public void delete(Customer customer) {
hibernateTemplate.delete(customer);
}
@Override
public void update(Customer customer) {
hibernateTemplate.update(customer);
}
@Override
public List findAll() {
return (List) hibernateTemplate.find("from Customer");
}
}
5.可以看到CustomerDaoImpl和LinkManDaoImpl方法很相似,所以需要提取
二、利用在子類中傳遞真正的Class類型來提取BaseDao,編寫泛型
1. BaseDao層
public interface BaseDao {
void save(T t);
void update(T t);
void delete(T t);
public T findById(Serializable id);
public List findAll();
public Integer findCount(DetachedCriteria detachedCriteria);
public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);
}
2. BaseDaoImpl層
public class BaseDaoImpl implements BaseDao {
private Class clazz;
//提供構造方法,在構造方法中讓繼承的子類向方法中傳入具體類型Class
public BaseDaoImpl(Class clazz) {
this.clazz = clazz;
}
//注入HibernateTemplate模板
@Autowired
private HibernateTemplate hibernateTemplate;
//保存信息
@Override
public void save(T t) {
hibernateTemplate.save(t);
}
//更新信息
@Override
public void update(T t) {
hibernateTemplate.update(t);
}
//刪除信息
@Override
public void delete(T t) {
hibernateTemplate.delete(t);
}
//根據id查詢信息
@Override
public T findById(Serializable id) {
return (T) hibernateTemplate.get(this.clazz, id);
}
//查詢所有信息
@Override
public List findAll() {
return (List) hibernateTemplate.find("from "+ this.clazz.getSimpleName());
}
//查詢Count(*)行記錄數
@Override
public Integer findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount());
List list = (List) hibernateTemplate.findByCriteria(detachedCriteria);
if(list != null && list.size() > 0) {
return list.get(0).intValue();
}
return null;
}
//分頁查詢信息
@Override
public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
detachedCriteria.setProjection(null);
return (List) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
}
}
3. 提取后的LinkManDao
public interface LinkManDao extends BaseDao{
}
4. 提取后的LinkManDaoImpl
@Repository
public class LinkManDaoImpl extends BaseDaoImpl implements LinkManDao {
//提供構造參數,在構造方法中傳入具體類型的Class
public LinkManDaoImpl() {
super(LinkMan.class);
}
@Autowired
private HibernateTemplate hibernateTemplate;
}
5.提取后的CustomerDao
public interface CustomerDao extends BaseDao {
}
6. 提取后的CustomerDaoImpl
@Repository
public class CustomerDaoImpl extends BaseDaoImpl implements CustomerDao {
//提供構造參數,在構造方法中傳入具體的Class
public CustomerDaoImpl() {
super(Customer.class);
// TODO Auto-generated constructor stub
}
//注入hibernateTemplate模板
@Autowired
private HibernateTemplate hibernateTemplate;
}
7.? 如果這樣抽取完成以后,那么在編寫DAO的時候如果里面都是一些CRUD的操作,在DAO中只需要提供構造方法即可。
三、如果將通用的DAO編寫的更好,連構造方法都不想要了!!!需要怎么做???? 泛型反射
1 解決方案二:通過泛型的反射抽取通用的DAO
l? 如果現在將DAO中的構造方法去掉,將父類的通用的DAO中提供無參數的構造即可,但是需要在無參數的構造中需要獲得具體類型的Class才可以-----涉及到泛型的反射了。
l? 回顧一下泛型:
泛型???????? :通用的類型。
<>???????????? :念為? typeof
List???? :E稱為類型參數變量
ArrayList? :Integer稱為是實際類型參數
ArrayList? :ArrayList稱為參數化類型
需要做的時候在父類的構造方法中獲得子類繼承父類上的參數化類型中的實際類型參數
泛型反射的步驟:
第一步:獲得代表子類對象的Class
第二步:查看API
Type[] getGenericInterfaces();??????? :獲得帶有泛型的接口,可以實現多個接口。
Type getGenericSuperclass();????????? :獲得帶有泛型的父類,繼承一個類。
第三步:獲得帶有泛型的父類
第四步:將帶有泛型的父類的類型轉成具體參數化的類型
第五步:通過參數化類型的方法獲得實際類型參數
2. 代碼實現
2.1 修改BaseDaoImpl里面的無參構造方法:
public class BaseDaoImpl implements BaseDao {
private Class clazz;
//提供構造方法,在構造方法中讓繼承的子類向方法中傳入具體類型Class
/**
* 不想子類上有構造方法,必須在父類中提供無參的構造,在無參構造中獲取具體的類型Class
* 具體類型中的Class是參數類型中的實際類型 參數
*/
public BaseDaoImpl() {
//反射:第一步獲得Class
Class clazz = this.getClass();//正在被調用的那個類的Class,CustomerDaoImpl或LinkManDaoImpl
//具體查看JDK的API
Type type = clazz.getGenericSuperclass();//參數化類型BaseDaoImpl,BaseDaoImpl
//得到的type就是一個參數化類型,將type強轉為參數化類型
ParameterizedType pType = (ParameterizedType) type;
//通過參數化類型獲得實際類型參數,得到一個實際類型參數的數組
Type[] types = pType.getActualTypeArguments();
//只獲得第一參數類型即可
this.clazz = (Class) types[0];//得到Customer,LinkMan
}
//注入HibernateTemplate模板
@Autowired
private HibernateTemplate hibernateTemplate;
//保存信息
@Override
public void save(T t) {
hibernateTemplate.save(t);
}
//更新信息
@Override
public void update(T t) {
hibernateTemplate.update(t);
}
//刪除信息
@Override
public void delete(T t) {
hibernateTemplate.delete(t);
}
//根據id查詢信息
@Override
public T findById(Serializable id) {
return (T) hibernateTemplate.get(this.clazz, id);
}
//查詢所有信息
@Override
public List findAll() {
return (List) hibernateTemplate.find("from "+ this.clazz.getSimpleName());
}
//查詢Count(*)行記錄數
@Override
public Integer findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount());
List list = (List) hibernateTemplate.findByCriteria(detachedCriteria);
if(list != null && list.size() > 0) {
return list.get(0).intValue();
}
return null;
}
//分頁查詢信息
@Override
public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
detachedCriteria.setProjection(null);
return (List) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
}
}
2.2 現在LinkDao和CustomerDao不用改變,修改LinkDaoImpl和CustomerDaoImpl
@Repository
public class LinkManDaoImpl extends BaseDaoImpl implements LinkManDao {
//提供構造參數,在構造方法中傳入具體的Class
/* public LinkManDaoImpl() {
super(LinkMan.class);
}*/
@Autowired
private HibernateTemplate hibernateTemplate;
}
@Repository
public class CustomerDaoImpl extends BaseDaoImpl implements CustomerDao {
//提供構造參數,在構造方法中傳入具體的Class
/*public CustomerDaoImpl() {
super(Customer.class);
// TODO Auto-generated constructor stub
}*/
//注入hibernateTemplate模板
@Autowired
private HibernateTemplate hibernateTemplate;
}
2.3 后面如果Dao層有特殊方法是可以在比如CustomerDaoImpl中去實現,相似的就不需要了,以此來到達抽取Dao層
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。