詳解Javaee Dao層的抽取
有時候我們在實現(xiàn)不同功能的時候回看到很多的Dao層的增加、修改、刪除、查找都很相似,修改我們將他們提取BaseDao
一、提取前
1. 提取前的LinkDao層:
public interface LinkManDao { Integer findCount(DetachedCriteria detachedCriteria); List<LinkMan> 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<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria); if(list != null && list.size() > 0) { return list.get(0).intValue(); } return null; } @Override public List<LinkMan> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) { detachedCriteria.setProjection(null); return (List<LinkMan>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize); } @Override public void save(LinkMan linkMan) { hibernateTemplate.save(linkMan); } //Dao層根據(jù)id查找聯(lián)系人 @Override public LinkMan findById(Long lkm_id) { return hibernateTemplate.get(LinkMan.class, lkm_id); } //Dao層更新聯(lián)系人信息 @Override public void update(LinkMan linkMan) { hibernateTemplate.update(linkMan); } //Dao層刪除聯(lián)系人 @Override public void delete(LinkMan linkMan) { hibernateTemplate.delete(linkMan); } }
3. 提取前的CustomerDao
public interface CustomerDao{ void save(Customer customer); Integer findCount(DetachedCriteria detachedCriteria); List<Customer> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize); Customer findById(Long cust_id); void delete(Customer customer); void update(Customer customer); List<Customer> findAll(); }
4.提取前的CustomerDaoImpl
@Repository public class CustomerDaoImpl implements CustomerDao { //注入hibernateTemplate模板 @Autowired private HibernateTemplate hibernateTemplate; /** * Dao層保存客戶信息實現(xiàn)方法 * <p>Title: CustomerDaoImpl</p> * <p>Description: </p> * @param customer * @see com.sshcrm.dao.CustomerDao#saveCustomer(com.sshcrm.pojo.Customer) */ @Override public void saveCustomer(Customer customer) { hibernateTemplate.save(customer); } //根據(jù)條件查詢結(jié)果集的總記錄數(shù) @Override public Integer findCount(DetachedCriteria detachedCriteria) { //select count(*) from Customer detachedCriteria.setProjection(Projections.rowCount()); List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria); if(list != null && list.size() > 0) { return list.get(0).intValue(); } return null; } //根據(jù)查詢條件查詢總頁數(shù) @Override public List<Customer> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) { //由于在統(tǒng)計總記錄數(shù)的時候已經(jīng)修改了發(fā)送的SQL語句,在此需要需要清空 detachedCriteria.setProjection(null); return (List<Customer>) 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<Customer> findAll() { return (List<Customer>) hibernateTemplate.find("from Customer"); } }
5.可以看到CustomerDaoImpl和LinkManDaoImpl方法很相似,所以需要提取
二、利用在子類中傳遞真正的Class類型來提取BaseDao,編寫泛型
1. BaseDao層
public interface BaseDao<T> { void save(T t); void update(T t); 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 startIndex, Integer pageSize); }
2. BaseDaoImpl層
public class BaseDaoImpl<T> implements BaseDao<T> { private Class clazz; //提供構(gòu)造方法,在構(gòu)造方法中讓繼承的子類向方法中傳入具體類型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); } //根據(jù)id查詢信息 @Override public T findById(Serializable id) { return (T) hibernateTemplate.get(this.clazz, id); } //查詢所有信息 @Override public List<T> findAll() { return (List<T>) hibernateTemplate.find("from "+ this.clazz.getSimpleName()); } //查詢Count(*)行記錄數(shù) @Override public Integer findCount(DetachedCriteria detachedCriteria) { detachedCriteria.setProjection(Projections.rowCount()); List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria); if(list != null && list.size() > 0) { return list.get(0).intValue(); } return null; } //分頁查詢信息 @Override public List<T> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) { detachedCriteria.setProjection(null); return (List<T>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize); } }
3. 提取后的LinkManDao
public interface LinkManDao extends BaseDao<LinkMan>{ }
4. 提取后的LinkManDaoImpl
@Repository public class LinkManDaoImpl extends BaseDaoImpl<LinkMan> implements LinkManDao { //提供構(gòu)造參數(shù),在構(gòu)造方法中傳入具體類型的Class public LinkManDaoImpl() { super(LinkMan.class); } @Autowired private HibernateTemplate hibernateTemplate; }
5.提取后的CustomerDao
public interface CustomerDao extends BaseDao<Customer> { }
6. 提取后的CustomerDaoImpl
@Repository public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao { //提供構(gòu)造參數(shù),在構(gòu)造方法中傳入具體的Class public CustomerDaoImpl() { super(Customer.class); // TODO Auto-generated constructor stub } //注入hibernateTemplate模板 @Autowired private HibernateTemplate hibernateTemplate; }
7. 如果這樣抽取完成以后,那么在編寫DAO的時候如果里面都是一些CRUD的操作,在DAO中只需要提供構(gòu)造方法即可。
三、如果將通用的DAO編寫的更好,連構(gòu)造方法都不想要了?。?!需要怎么做??? 泛型反射
1 解決方案二:通過泛型的反射抽取通用的DAO
l 如果現(xiàn)在將DAO中的構(gòu)造方法去掉,將父類的通用的DAO中提供無參數(shù)的構(gòu)造即可,但是需要在無參數(shù)的構(gòu)造中需要獲得具體類型的Class才可以-----涉及到泛型的反射了。
l 回顧一下泛型:
泛型 :通用的類型。
<> :念為 typeof
List<E> :E稱為類型參數(shù)變量
ArrayList<Integer> :Integer稱為是實際類型參數(shù)
ArrayList<Integer> :ArrayList<Integer>稱為參數(shù)化類型
需要做的時候在父類的構(gòu)造方法中獲得子類繼承父類上的參數(shù)化類型中的實際類型參數(shù)
泛型反射的步驟:
第一步:獲得代表子類對象的Class
第二步:查看API
Type[] getGenericInterfaces(); :獲得帶有泛型的接口,可以實現(xiàn)多個接口。
Type getGenericSuperclass(); :獲得帶有泛型的父類,繼承一個類。
第三步:獲得帶有泛型的父類
第四步:將帶有泛型的父類的類型轉(zhuǎn)成具體參數(shù)化的類型
第五步:通過參數(shù)化類型的方法獲得實際類型參數(shù)
2. 代碼實現(xiàn)
2.1 修改BaseDaoImpl里面的無參構(gòu)造方法:
public class BaseDaoImpl<T> implements BaseDao<T> { private Class clazz; //提供構(gòu)造方法,在構(gòu)造方法中讓繼承的子類向方法中傳入具體類型Class /** * 不想子類上有構(gòu)造方法,必須在父類中提供無參的構(gòu)造,在無參構(gòu)造中獲取具體的類型Class * 具體類型中的Class是參數(shù)類型中的實際類型 參數(shù) */ public BaseDaoImpl() { //反射:第一步獲得Class Class clazz = this.getClass();//正在被調(diào)用的那個類的Class,CustomerDaoImpl或LinkManDaoImpl //具體查看JDK的API Type type = clazz.getGenericSuperclass();//參數(shù)化類型BaseDaoImpl<Customer>,BaseDaoImpl<LinkMan> //得到的type就是一個參數(shù)化類型,將type強轉(zhuǎn)為參數(shù)化類型 ParameterizedType pType = (ParameterizedType) type; //通過參數(shù)化類型獲得實際類型參數(shù),得到一個實際類型參數(shù)的數(shù)組 Type[] types = pType.getActualTypeArguments(); //只獲得第一參數(shù)類型即可 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); } //根據(jù)id查詢信息 @Override public T findById(Serializable id) { return (T) hibernateTemplate.get(this.clazz, id); } //查詢所有信息 @Override public List<T> findAll() { return (List<T>) hibernateTemplate.find("from "+ this.clazz.getSimpleName()); } //查詢Count(*)行記錄數(shù) @Override public Integer findCount(DetachedCriteria detachedCriteria) { detachedCriteria.setProjection(Projections.rowCount()); List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria); if(list != null && list.size() > 0) { return list.get(0).intValue(); } return null; } //分頁查詢信息 @Override public List<T> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) { detachedCriteria.setProjection(null); return (List<T>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize); } }
2.2 現(xiàn)在LinkDao和CustomerDao不用改變,修改LinkDaoImpl和CustomerDaoImpl
@Repository public class LinkManDaoImpl extends BaseDaoImpl<LinkMan> implements LinkManDao { //提供構(gòu)造參數(shù),在構(gòu)造方法中傳入具體的Class /* public LinkManDaoImpl() { super(LinkMan.class); }*/ @Autowired private HibernateTemplate hibernateTemplate; }
@Repository public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao { //提供構(gòu)造參數(shù),在構(gòu)造方法中傳入具體的Class /*public CustomerDaoImpl() { super(Customer.class); // TODO Auto-generated constructor stub }*/ //注入hibernateTemplate模板 @Autowired private HibernateTemplate hibernateTemplate; }
2.3 后面如果Dao層有特殊方法是可以在比如CustomerDaoImpl中去實現(xiàn),相似的就不需要了,以此來到達抽取Dao層
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- JavaEE線程安全實現(xiàn)線程池方法
- JavaEE的進程,線程和創(chuàng)建線程的5種方式詳解
- 詳解JavaEE中Apollo安裝使用小結(jié)
- 2020新版idea創(chuàng)建項目沒有javaEE 沒有Web選項的完美解決方法
- JavaEE SpringMyBatis是什么? 它和Hibernate的區(qū)別及如何配置MyBatis
- JavaEE Spring MyBatis如何一步一步實現(xiàn)數(shù)據(jù)庫查詢功能
- JavaEE實現(xiàn)基于SMTP協(xié)議的郵件發(fā)送功能
- 詳解JavaEE 使用 Redis 數(shù)據(jù)庫進行內(nèi)容緩存和高訪問負載
- JNDI在JavaEE中的角色_動力節(jié)點Java學院整理
- JavaEE線程安全定時器模式任務
相關(guān)文章
MyBatis-Plus中公共字段的統(tǒng)一處理的實現(xiàn)
在開發(fā)中經(jīng)常遇到多個實體類有共同的屬性字段,這些字段屬于公共字段,本文主要介紹了MyBatis-Plus中公共字段的統(tǒng)一處理的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-08-08springboot使用Logback把日志輸出到控制臺或輸出到文件
這篇文章給大家介紹springboot項目使用日志工具Logback把日志不僅輸出到控制臺,也可以輸出到文件的操作方法,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-10-10解決springboot項目不配置數(shù)據(jù)源啟動報錯問題
這篇文章主要介紹了解決springboot項目不配置數(shù)據(jù)源啟動報錯問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12使用mongoTemplate實現(xiàn)多條件加分組查詢方式
這篇文章主要介紹了使用mongoTemplate實現(xiàn)多條件加分組查詢方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06JDK與JRE的下載和安裝以及配置JDK環(huán)境變量圖文教程
JRE也就是(Java?RuntimeEnvironment)Java運行環(huán)境,是運行JAVA程序所必須的環(huán)境的集合,包含各種類庫,下面這篇文章主要給大家介紹了關(guān)于JDK與JRE的下載和安裝以及配置JDK環(huán)境變量的相關(guān)資料,需要的朋友可以參考下2023-12-12SpringBoot整合Swagger Api自動生成文檔的實現(xiàn)
本文主要介紹了SpringBoot整合Swagger Api自動生成文檔的實,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-06-06