【Spring】DAO 和 Repository 的區別

DAO 和 Repository 的區別

  • 1.概述
  • 2.DAO 模式
    • 2.1 User
    • 2.2 UserDao
    • 2.3 UserDaoImpl
  • 3.Repository 模式
    • 3.1 UserRepository
    • 3.2 UserRepositoryImpl
  • 4.具有多個 DAO 的 Repository 模式
    • 4.1 Tweet
    • 4.2 TweetDao 和 TweetDaoImpl
    • 4.3 增強 User 域
    • 4.4 UserRepositoryImpl
  • 5.比較兩種模式
  • 6.結論

1.概述

通常,Repository 和 DAO 的實現被認為是可互換的,特別是在 以數據為中心 的應用程序中。這造成了對它們差異的混淆。

在本文中,我們將討論 DAO 和 Repository 模式之間的差異。

在這里插入圖片描述

2.DAO 模式

數據訪問對象Data Access ObjectDAO)模式是數據持久性的抽象,被認為更接近于底層存儲,而底層存儲通常以表為中心。因此,在許多情況下,我們的 DAO 與數據庫表匹配,允許更直接的方式從存儲中 發送/檢索 數據,從而隱藏丑陋的查詢。

讓我們來看看 DAO 模式的簡單實現。

2.1 User

首先,讓我們創建一個基本的 User 域類。

public class User {private Long id;private String userName;private String firstName;private String email;// getters and setters
}

2.2 UserDao

然后,我們將創建 UserDao 接口,該接口為 User 域提供簡單的 CRUD 操作。

public interface UserDao {void create(User user);User read(Long id);void update(User user);void delete(String userName);
}

2.3 UserDaoImpl

最后,我們將創建實現 UserDao 接口的 UserDaoImpl 子類。

public class UserDaoImpl implements UserDao {private final EntityManager entityManager;@Overridepublic void create(User user) {entityManager.persist(user);}@Overridepublic User read(long id) {return entityManager.find(User.class, id);}// ...
}

在這里,為了簡單起見,我們使用 JPA EntityManager 接口與底層存儲交互,并為用戶域提供數據訪問機制。

3.Repository 模式

根據 Eric Evans 的《領域驅動設計》:Repository 是一種封裝存儲、檢索和搜索行為的機制,它模擬對象的集合

同樣,根據《企業應用架構模式》,它使用類似于集合的接口訪問領域對象,在 領域層數據映射層 之間進行調解。換句話說,Repository 也處理數據并隱藏查詢,與 DAO 類似。不過,它位于更高層次,更接近應用程序的業務邏輯。

因此,Repository 可以使用 DAO 從數據庫獲取數據并填充域對象。或者,它可以準備域對象中的數據,并使用 DAO 將其發送到存儲系統以實現持久性。

讓我們看看 User 域的 Repository 模式的簡單實現。

3.1 UserRepository

首先,讓我們創建用戶存儲庫接口。

public interface UserRepository {User get(Long id);void add(User user);void update(User user);void remove(User user);
}

在這里,我們添加了一些常用方法,如 getaddupdateremove,以處理對象集合。

3.2 UserRepositoryImpl

然后,我們將創建 UserRepositoryImpl 類,提供 UserRepository 接口的實現。

public class UserRepositoryImpl implements UserRepository {private UserDaoImpl userDaoImpl;@Overridepublic User get(Long id) {User user = userDaoImpl.read(id);return user;}@Overridepublic void add(User user) {userDaoImpl.create(user);}// ...
}

在這里,我們使用 UserDaoImpl 從數據庫中 發送/檢索 數據。

到目前為止,我們可以說 DAO 和 Repository 的實現看起來非常相似,因為 User 類是一個 Anemic Domain。而且,Repository 只是數據訪問層(DAO)的另一層。

🚀 只包含數據,不包含業務邏輯的類,就叫作 貧血模型(Anemic Domain Model)。貧血模型將數據與操作分離,破壞了面向對象的封裝特性,是一種典型的面向過程的編程風格。

但是,DAO 似乎是 訪問數據 的完美候選者,Repository 是 實現業務用例 的理想方式。

4.具有多個 DAO 的 Repository 模式

為了清楚地理解最后一句話,讓我們加強 User 域來處理業務用例。

想象一下,我們想通過聚合一個用戶的 Twitter 推文、Facebook 帖子等,為他準備一份社交媒體檔案。

4.1 Tweet

首先,我們將創建具有一些保存推文信息的屬性的 Tweet 類:

public class Tweet {private String email;private String tweetText;    private Date dateCreated;// getters and setters
}

4.2 TweetDao 和 TweetDaoImpl

然后,與 UserDao 類似,我們將創建允許獲取推文的 TweetDao 界面:

public interface TweetDao {List<Tweet> fetchTweets(String email);    
}

同樣,我們將創建 TweetDaoImpl 類,該類提供 fetchTweets 方法的實現:

public class TweetDaoImpl implements TweetDao {@Overridepublic List<Tweet> fetchTweets(String email) {List<Tweet> tweets = new ArrayList<Tweet>();//call Twitter API and prepare Tweet objectreturn tweets;}
}

在這里,我們將調用 Twitter API,使用用戶的電子郵件獲取其所有推文。

因此,在這種情況下,DAO 提供了一種使用第三方 API 的數據訪問機制。

4.3 增強 User 域

最后,讓我們創建 User 類的 UserSocialMedia 子類,以保留 Tweet 對象的列表。

public class UserSocialMedia extends User {private List<Tweet> tweets;// getters and setters
}

在這里,我們的 UserSocialMedia 是一個復雜的域,其中包含 User 域的屬性。

4.4 UserRepositoryImpl

現在,我們將升級我們的 UserRepositoryImpl 類,以提供 User 域對象以及推文列表。

public class UserRepositoryImpl implements UserRepository {private UserDaoImpl userDaoImpl;private TweetDaoImpl tweetDaoImpl;@Overridepublic User get(Long id) {UserSocialMedia user = (UserSocialMedia) userDaoImpl.read(id);List<Tweet> tweets = tweetDaoImpl.fetchTweets(user.getEmail());user.setTweets(tweets);return user;}
}

在這里,UserRepositoryImpl 使用 UserDaoImpl 提取用戶數據,并使用 TweetDaoImpl 提取用戶的推文。

然后,它聚合兩組信息,并提供 UserSocialMedia 類的域對象,該對象對于我們的業務用例非常方便。因此,存儲庫依賴于 DAO 來訪問來自各種源的數據。

同樣,我們可以增強我們的用戶域以保留 Facebook 帖子列表。

5.比較兩種模式

現在我們已經看到了 DAO 和 Repository 模式的細微差別,讓我們總結一下它們的區別:

  • DAO 是數據持久性的抽象。但是,Repository 是對象集合的抽象。
  • DAO 是一個較 級別的概念,更接近 存儲系統。但是,Repository 是一個更 層次的概念,更接近 域對象
  • DAO 作為 數據映射/訪問層 工作,隱藏丑陋的查詢。但是,Repository 是 數據訪問層 之間的一層,隱藏了整理數據和準備域對象的復雜性。
  • DAO 不能使用 Repository 實現。但是,Repository 可以使用 DAO 來訪問底層存儲。

而且,如果我們有一個貧血域,Repository 將只是一個 DAO。

此外,Repository 模式鼓勵域驅動的設計,也為非技術團隊成員提供了對數據結構的輕松理解。

  • 職責不同:Repository 負責數據訪問的邏輯管理,封裝與數據庫的交互操作,包括數據的增刪改查等。Repository 的設計目標是提供一個統一的接口,將數據訪問邏輯與業務邏輯分離,使得業務邏輯更加清晰和可維護。DAO 更關注于數據訪問的實現細節,與具體的數據庫交互,實現數據的存儲和檢索等功能。
  • 抽象層次不同:Repository 提供一種更加抽象的數據訪問方式,將數據訪問的邏輯從業務邏輯中分離出來,使得業務邏輯與數據訪問無關,降低代碼耦合度,提高可維護性和可擴展性。Repository 定義一組通用的接口和方法,供業務模塊調用。DAO 更接近于具體的數據訪問實現,直接與數據庫交互,實現數據的存儲和檢索等功能。DAO 的設計目標是提供一組具體的數據訪問方法,以滿足業務模塊的具體需求。

6.結論

在本文中,我們探討了 DAO 和 Repository 模式之間的差異。

首先,我們研究了 DAO 模式的基本實現。然后,我們看到了使用 Repository 模式的類似實現。

最后,我們研究了一個利用多個 DAO 的 Repository,它增強了域解決業務用例的能力。

因此,我們可以得出結論,當應用程序從以數據為中心轉向面向業務時,Repository 模式被證明是一種更好的方法。

🚀 譯自《DAO vs Repository Patterns》

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37175.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37175.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37175.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ISO 19110操作要求類中的/req/operation/formal-definition詳細解釋

/req/operation/formal-definition 要求: 每個要素操作實體必須具有一個形式定義&#xff08;formal definition&#xff09;&#xff0c;該定義應明確描述操作的行為和影響。 具體解釋 定義 要素操作實體&#xff08;feature operation entity&#xff09;&#xff1a;這…

深度學習基準模型Mamba

深度學習基準模型Mamba Mamba(英文直譯&#xff1a;眼鏡蛇)具有選擇性狀態空間的線性時間序列建模&#xff0c;是一種先進的狀態空間模型 (SSM)&#xff0c;專為高效處理復雜的數據密集型序列而設計。 Mamba是一種深度學習基準模型&#xff0c;專為處理長序列數據而設計&…

【鴻蒙學習筆記】位置設置

官方文檔&#xff1a;位置設置 目錄標題 align&#xff1a;子元素的對齊方式direction&#xff1a;官方文檔沒懂&#xff0c;看圖理解吧 align&#xff1a;子元素的對齊方式 Stack() {Text(TopStart)}.width(90%).height(50).backgroundColor(0xFFE4C4).align(Alignment.TopS…

<Python><ffmpeg>基于python使用PyQt5構建GUI實例:音頻格式轉換程序(MP3/aac/wma/flac)(優化版2)

前言 本文是基于python語言使用pyqt5來構建的GUI,功能是使用ffmpeg來對音頻文件進行格式轉換,如mp3、aac、wma、flac等音樂格式。 UI示例: 環境配置 系統:windows 平臺:visual studio code 語言:python 庫:pyqt5、ffmpeg 概述 本文是建立在之前的博文的基礎上的優化版…

在線教育項目(一):如何防止一個賬號多個地方登陸

使用jwt做驗證&#xff0c;使用賬號作為redis中的key,登錄的時候生成token放到redis中&#xff0c;每次申請資源的時候去看token 有沒有變&#xff0c;因為token每次登錄都會去覆蓋&#xff0c;只要第二次登錄token就不一樣了

Day7:.翻轉字符串里的單詞 151 卡碼網:55.右旋轉字符串

題目 151. 反轉字符串中的單詞 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:// 移除多余空格void moveSpace(string& s) {// 定義快慢指針int slow 0;int fast 0;// 刪除前導空格while (s.size() > 0 && fast < s.size() &&…

【算法——雙指針前綴和】

例題&#xff1a; 奇偶排序數組&#xff08;與下標對應&#xff09; 奇數偶數個數相等 922. 按奇偶排序數組 II #include<iostream> #include<vector> #include<algorithm> using namespace std;int main() {vector<int>nums { 4,2,5,7 };//指針x…

==和equals的區別(面試題)

和equals有什么區別 對于基本數據類型&#xff0c;比較的是值是否相等&#xff0c;對于引用類型則是比較的地址是否相等&#xff1b;對于equals來說&#xff0c;基本數據類型沒有equals方法&#xff0c;對于引用類型equals比較的是引用對象是否相同 那針對以上結論&#xff0c…

西點領導力:卓越是怎樣練成的

今天剛看了一個美國西點軍校第50任校長&#xff1a;羅伯克卡斯倫的《為什么跟西點軍校學領導力培養》這個演講。從中受益良多&#xff0c;于是我就去了解了一下這位校長以及西點軍校。 西點軍校 西點軍校&#xff08;United States Military Academy, USMA&#xff09;&#…

Android常用加解密算法總結

Android開發中對于數據的傳輸和保存一定會使用加密技術&#xff0c;加密算法是最普遍的安保手段&#xff0c;多數情況數據加密后在需要使用源數據時需要再進行解密&#xff0c;但凡是都有例外。下面從可逆加密、不可逆、不純粹加密三種方式記錄一下常見的加解密算法。 加密技術…

【使用sudo apt-get出現報錯】——無法獲得鎖 /var/lib/dpkg/lock-open(11:資 源暫時不可用) ,是否有其他進程正占用它?

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、ubuntu中進程正在被占用1. 問題描述2. 原因分析3. 解決 總結 前言 一、ubuntu中進程正在被占用 1. 問題描述 在Ubuntu中&#xff0c;使用終端時輸入帶有…

C++函數不完整聲明報錯

擋在c中聲明如下的函數代碼段時&#xff0c;不會進行隱式的轉換。 double add(); int main(){double s add(1,2);return 0; } double add(double a,double b){return ab; } 在調用add時&#xff0c;main中為它提供了兩個參數&#xff0c;看起來可以被轉換成double類型。然而…

昇思25天學習打卡營第7天之二 | 模型保存與加載

1. 保存與加載 在訓練網絡模型的過程中&#xff0c;實際上我們希望保存中間和最后的結果&#xff0c;用于微調&#xff08;fine-tune&#xff09;和后續的模型推理與部署&#xff0c;本章節我們將介紹如何保存與加載模型。 1.1 導入依賴 # 導入numpy庫&#xff0c;并將其重命…

六月,允許自己做自己,別人做別人

今天結束后&#xff0c;2024 就過去一半了。 年初的規劃完成一半了嗎&#xff1f;如果沒有也沒關系&#xff0c;做你自己繼續前進。 家人來北京旅游&#xff0c;我累趴了 六月初&#xff0c;我搬家了&#xff0c;這次租了一整套房&#xff0c;是一個小倆居、還帶一個小閣樓。…

速盾:視頻cdn和網站cdn的相同點與不同點

CDN&#xff08;Content Delivery Network&#xff09;是一種分布式網絡架構&#xff0c;旨在為用戶提供高效、高質量的內容傳送服務。CDN主要通過將內容分發到全球各地的邊緣節點&#xff0c;并根據用戶的地理位置選擇最近的節點來提供內容&#xff0c;從而加速內容的傳輸并降…

【高考志愿】儀器科學與技術

目錄 一、專業介紹 1.1 專業概述 1.2 專業方向 1.3 主要課程 二、專業技能與素質培養 三、就業前景 四、個人發展規劃建議 五、儀器科學與技術專業排名 六、總結 一、專業介紹 1.1 專業概述 儀器科學與技術專業是一門綜合性極強的學科&#xff0c;它融合了測量、控制…

數學學習與研究雜志社《數學學習與研究》雜志社2024年第6期目錄

課改前沿 基于核心素養的高中數學課堂教學研究——以“直線與圓、圓與圓的位置關系”為例 張亞紅; 2-4 核心素養視角下初中生數學閱讀能力的培養策略探究 賈象虎; 5-7 初中數學大單元教學實踐策略探索 耿忠義; 8-10《數學學習與研究》投稿&#xff1a;cn7kantougao…

使用Python繪制極坐標圖

使用Python繪制極坐標圖 極坐標圖極坐標圖的優點使用場景 效果代碼 極坐標圖 極坐標圖&#xff08;Polar Chart&#xff09;是一種圖表類型&#xff0c;用于顯示在極坐標系中的數據。極坐標圖使用圓形坐標系&#xff0c;角度表示一個變量的值&#xff0c;半徑表示另一個變量的…

線程安全問題(二)——死鎖

死鎖 前言可重入鎖邏輯 兩個線程兩把鎖&#xff08;死鎖&#xff09;死鎖的特點多個線程多把鎖&#xff08;哲學家就餐問題&#xff09;總結 前言 在前面的文章中&#xff0c;介紹了鎖的基本使用方式——鎖 在上一篇文章中&#xff0c;通過synchronized關鍵字進行加鎖操作&am…

XML簡介XML 使用教程XML的基本結構XML的使用場景

學習總結 1、掌握 JAVA入門到進階知識(持續寫作中……&#xff09; 2、學會Oracle數據庫入門到入土用法(創作中……&#xff09; 3、手把手教你開發炫酷的vbs腳本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA編程利器技巧(編寫中……&#xff09; 5、面經吐血整理的 面試技…