BaseDAO使用


BaseDao接口的過人之處在於:一般是提供從數據庫 增加、刪除、修改記錄、查詢所有記錄、查詢符合某個條件記錄、取得某條記錄等方法的底層數據操作自定義類。
由於我們可能操作多個數據庫表,這樣就需要為每個表提供一個操作他的類 xxDAO, 這些DAO繼承BaseDAO 就可以省略很多重復代碼(從數據庫 增加、刪除、修改記錄、查詢所有記錄、查詢符合某個條件記錄、取得某條記錄等方法的代碼)。

其次對於泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操作的數據類型被指定為一個參數。這種參數類型可以用在類、接口和方法的創建中,分別稱為泛型類、泛型接口、泛型方法。
 Java語言引入泛型的好處是安全簡單。
  在Java SE 1.5之前,沒有泛型的情況的下,通過對類型Object的引用來實現參數的“任意化”,“任意化”帶來的缺點是要做顯式的強制類型轉換,而這種轉換是要求開發者對實際參數類型可以預知的情況下進行的。對於強制類型轉換錯誤的情況,編譯器可能不提示錯誤,在運行的時候才出現異常,這是一個安全隱患。
  泛型的好處是在編譯的時候檢查類型安全,並且所有的強制轉換都是自動和隱式的,提高代碼的重用率。
  泛型在使用中還有一些規則和限制:
  1、泛型的類型參數只能是類類型(包括自定義類),不能是簡單類型。
  2、同一種泛型可以對應多個版本(因為參數類型是不確定的),不同版本的泛型類實例是不兼容的。
  3、泛型的類型參數可以有多個。
4、泛型的參數類型可以使用extends語句,例如<T extends superclass>。習慣上成為“有界類型”。
  5、泛型的參數類型還可以是通配符類型。例如Class<?> classType = Class.forName(java.lang.String);

一般在涉及DAO開發時,常用到的增刪改查方法會封裝到一個基類(BaseDAO),對於各個數據表的基本維護業務都需要用到增刪改查等方法。

 

若對每張表都編寫一套增刪改差方法未必有些麻煩,並且不符合編碼的基本准則。一般,我們可以將這些功能的所公用的部分封裝為一個對象,或者是類,此類是所有DAO的基類,可以稱為:BaseDAO。

由於此類接收到不同的操作對象,故需泛型的支持。

下面,我通過以下實例代碼,為此知識進行展示,供大家參考

此例是基於ssh2的環境中進行搭建:

 

相關類:涉及到BaseDAO接口,接口實現類:BaseDAOImpl、兩個數據表的操作對象及相應的接口:DAOA、DAOB、DAOAImpl、DAOBImpl


BaseDAO:接口代碼,公共方法的接口類

 

[java]  view plain  copy
 
  1. package base;  
  2.   
  3. import java.util.List;  
  4.   
  5. public interface BaseDao<T> {  
  6.   
  7.     /** 
  8.      * 保存實體 
  9.      *  
  10.      * @param entity 
  11.      */  
  12.     void save(T entity);  
  13.   
  14.     /** 
  15.      * 刪除實體 
  16.      *  
  17.      * @param id 
  18.      */  
  19.     void delete(Long id);  
  20.   
  21.     /** 
  22.      * 更新實體 
  23.      *  
  24.      * @param entity 
  25.      */  
  26.     void update(T entity);  
  27.   
  28.     /** 
  29.      * 按id查詢 
  30.      *  
  31.      * @param id 
  32.      * @return 
  33.      */  
  34.     T getById(Long id);  
  35.   
  36.     /** 
  37.      * 按id查詢 
  38.      *  
  39.      * @param ids 
  40.      * @return 
  41.      */  
  42.     List<T> getByIds(Long[] ids);  
  43.   
  44.     /** 
  45.      * 查詢所有 
  46.      *  
  47.      * @return 
  48.      */  
  49.     List<T> findAll();  
  50.   
  51. }  

BaseDAOImpl:公共方法的實現類

 

 

[java]  view plain  copy
 
  1. package base;  
  2.   
  3. import java.lang.reflect.ParameterizedType;  
  4. import java.util.List;  
  5.   
  6. import javax.annotation.Resource;  
  7.   
  8. import org.hibernate.Session;  
  9. import org.hibernate.SessionFactory;  
  10.   
  11. @SuppressWarnings("unchecked")  
  12. public abstract class BaseDaoImpl<T> implements BaseDao<T> {  
  13.   
  14.     @Resource  
  15.     private SessionFactory sessionFactory;  
  16.     private Class<T> clazz;  
  17.   
  18.     public BaseDaoImpl() {  
  19.         // 使用反射技術得到T的真實類型  
  20.         ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 獲取當前new的對象的 泛型的父類 類型  
  21.         this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 獲取第一個類型參數的真實類型  
  22.         System.out.println("clazz ---> " + clazz);  
  23.           
  24.     }  
  25.   
  26.     /** 
  27.      * 獲取當前可用的Session 
  28.      *  
  29.      * @return 
  30.      */  
  31.     protected Session getSession() {  
  32.         return sessionFactory.getCurrentSession();  
  33.     }  
  34.   
  35.     public void save(T entity) {  
  36.         getSession().save(entity);  
  37.     }  
  38.   
  39.     public void update(T entity) {  
  40.         getSession().update(entity);  
  41.     }  
  42.   
  43.     public void delete(Long id) {  
  44.         Object obj = getById(id);  
  45.         if (obj != null) {  
  46.             getSession().delete(obj);  
  47.         }  
  48.     }  
  49.   
  50.     public T getById(Long id) {  
  51.         return (T) getSession().get(clazz, id);  
  52.     }  
  53.   
  54.     public List<T> getByIds(Long[] ids) {  
  55.         return getSession().createQuery(//  
  56.                 "FROM User WHERE id IN (:ids)")//  
  57.                 .setParameterList("ids", ids)//  
  58.                 .list();  
  59.     }  
  60.   
  61.     public List<T> findAll() {  
  62.         return getSession().createQuery(//  
  63.                 "FROM " + clazz.getSimpleName())//  
  64.                 .list();  
  65.     }  
  66.   
  67. }  


DAOA:vo A的DAO接口類,此類需要繼承BaseDAO接口,實現公共類,另外在此可以聲明自己特有的方法

 

 

[java]  view plain  copy
 
  1. package dao;  
  2.   
  3. import pojo.A;  
  4. import base.BaseDao;  
  5.   
  6. public interface DAOA extends BaseDao<A>{  
  7. //...  
  8. }  

DAOAImpl:vo A的DAO實現類,實現DAOA中聲明的方法和BaseDAO的所以基本方法,為實現基本方法,故繼承了BaseDaoImpl類

[java]  view plain  copy
 
  1. package dao.impls;  
  2.   
  3. import org.springframework.stereotype.Repository;  
  4.   
  5. import pojo.A;  
  6. import base.BaseDaoImpl;  
  7. import dao.DAOA;  
  8. @Repository  
  9. public class DAOAImpl extends BaseDaoImpl<A> implements DAOA {     //具體的實現類什么都不用去寫  只需要實現dao(有了聲明)繼承daoImpl(有了實現   這樣的話   無論后面有多少不要的dao及其實現都只需要繼承實現一個共同的BaseDao及其Impl即可     把公共的操作封裝的十分Good)
  10.   
  11. }  


同理,DAOB同上

 

以此,便完成了公共方法的繼承與實現機制。

當中用到了泛型機制,通過繼承父類來實現泛型的數據轉換:

[java]  view plain  copy
 
  1. public class DAOAImpl extends BaseDaoImpl<A>{}  A為vo的模型類,以此在父類中可調用實現!!  

 

通過使用泛型T減少Dao的冗余代碼,當T繼承某個對象時(T extends EntityDao)限制了參數類型必須繼承該對象(EntityDao),並且ClassT必須要有泛型參數(De


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM