在傳統分層架構中,DAO 層往往存在大量重複的 CRUD 代碼。引入泛型可以將通用邏輯抽象到基類,具體實體類僅需指定類型參數即可復用。本文對比兩種主流泛型 DAO 寫法並給出建議。
public class User {
private int id;
private String name;
// getter/setter 省略
}
在每個方法聲明前單獨聲明類型參數,適用於極少數方法需要不同類型參數的場景。
public class EntityDao1 {
// 方法級泛型:返回值前聲明 或
public void add(T t) { /* 保存邏輯 */ }
public T get(ID id) { /* 查詢邏輯 */ return null; }
}
特點:
<T>,語法略顯累贅。在類聲明時定義類型參數,所有方法共享,構建類型安全的 DAO 基類。
public class EntityDao2 {
public void add(T t) { /* 保存邏輯 */ }
public T get(ID id) { /* 查詢邏輯 */ return null; }
}
優勢:
T 和 ID,編譯期檢查所有方法簽名。public class UserDao extends EntityDao2 即可獲得完整類型安全的 CRUD 能力。public abstract class BaseDao {
private Class entityClass;
public BaseDao() {
// 通過反射獲取實際類型參數
this.entityClass = (Class) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
public void save(T entity) { /* 通用保存 */ }
public T findById(ID id) { /* 通用查詢 */ }
public void delete(T entity) { /* 通用刪除 */ }
// 更多通用方法...
}
| 維度 | 方法級泛型 | 類級泛型 |
|---|---|---|
| 適用場景 | 工具類、靜態方法、極少數多態方法 | DAO、Service、Repository 等業務基類 |
| 類型安全 | 弱(調用時指定) | 強(實例化時固定) |
| 代碼復用 | 低 | 高(配合繼承) |
| 推薦指數 | ⭐⭐ | ⭐⭐⭐⭐⭐ |
結論:DAO 層基類務必採用類級泛型,構建類型安全、可復用的數據訪問體系。方法級泛型保留給真正需要「每次調用類型不同」的工具方法。