成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Java中的DAO模式

TIGERB / 785人閱讀

摘要:此的功能是從應(yīng)用程序中隱藏在底層存儲(chǔ)機(jī)制中執(zhí)行操作所涉及的所有復(fù)雜性。這正是模式試圖解決的問題。將模式與一起使用開發(fā)人員普遍認(rèn)為的發(fā)布將模式的功能降級(jí)為零,因?yàn)樵撃J街皇菍?shí)體經(jīng)理提供的另一層抽象和復(fù)雜性。在這種情況下,模式有其自己的位置。

案例概述

數(shù)據(jù)訪問對(duì)象(DAO)模式是一種結(jié)構(gòu)模式,它允許我們使用抽象API將應(yīng)用程序/業(yè)務(wù)層與持久層(通常是關(guān)系數(shù)據(jù)庫(kù),但它可以是任何其他持久性機(jī)制)隔離開來。
此API的功能是從應(yīng)用程序中隱藏在底層存儲(chǔ)機(jī)制中執(zhí)行CRUD操作所涉及的所有復(fù)雜性。這允許兩個(gè)層分別進(jìn)化而不知道彼此之間的任何事情。
在本文中,我們將深入研究模式的實(shí)現(xiàn),并且我們將學(xué)習(xí)如何使用它來抽象調(diào)用JPA實(shí)體管理器。

簡(jiǎn)單實(shí)施

要了解DAO模式的工作原理,讓我們創(chuàng)建一個(gè)基本示例。
假設(shè)我們想要開發(fā)一個(gè)管理用戶的應(yīng)用程序。為了使應(yīng)用程序的域模型完全不受數(shù)據(jù)庫(kù)的影響,我們將創(chuàng)建一個(gè)簡(jiǎn)單的DAO類,它將保持這些組件彼此完美地分離。

由于我們的應(yīng)用程序?qū)⑴c用戶一起工作,我們需要定義一個(gè)類來實(shí)現(xiàn)其模型:

public class User {
?????
????private String name;
????private String email;
?????
????// constructors / standard setters / getters
}

User類只是用戶數(shù)據(jù)的普通容器,因此它不實(shí)現(xiàn)任何其他值得強(qiáng)調(diào)的行為。

當(dāng)然,我們?cè)谶@里需要做的最相關(guān)的設(shè)計(jì)選擇是如何使使用這個(gè)類的應(yīng)用程序與任何可以在某個(gè)時(shí)候?qū)崿F(xiàn)的持久性機(jī)制隔離開來。

這正是DAO模式試圖解決的問題。

DAO API

讓我們定義一個(gè)基本的DAO層,這樣我們就可以看到它如何使域模型與持久層完全分離。

這是DAO API:

public interface Dao {
?????
????Optional get(long id);
?????
????List getAll();
?????
????void save(T t);
?????
????void update(T t, String[] params);
?????
????void delete(T t);
}

從鳥瞰的角度來看,很明顯Dao接口定義了一個(gè)抽象API,它對(duì)類型為T的對(duì)象執(zhí)行CRUD操作。

由于接口提供的抽象級(jí)別很高,因此很容易創(chuàng)建與用戶對(duì)象一起工作的具體的、細(xì)粒度的實(shí)現(xiàn)。

UserDao類

讓我們定義Dao接口的特定于用戶的實(shí)現(xiàn):

public class UserDao implements Dao {
?????
????private List users = new ArrayList<>();
?????
????public UserDao() {
????????users.add(new User("John", "john@domain.com"));
????????users.add(new User("Susan", "susan@domain.com"));
????}
?????
????@Override
????public Optional get(long id) {
????????return Optional.ofNullable(users.get((int) id));
????}
?????
????@Override
????public List getAll() {
????????return users;
????}
?????
????@Override
????public void save(User user) {
????????users.add(user);
????}
?????
????@Override
????public void update(User user, String[] params) {
????????user.setName(Objects.requireNonNull(
??????????params[0], "Name cannot be null"));
????????user.setEmail(Objects.requireNonNull(
??????????params[1], "Email cannot be null"));
?????????
????????users.add(user);
????}
?????
????@Override
????public void delete(User user) {
????????users.remove(user);
????}
}

所述的UserDAO類實(shí)現(xiàn)所有用于獲取,更新和刪除所需要的功能的用戶的對(duì)象。

為簡(jiǎn)單起見,User List的作用類似于內(nèi)存數(shù)據(jù)庫(kù),在構(gòu)造函數(shù)中填充了幾個(gè)User對(duì)象。

當(dāng)然,重構(gòu)其他方法很容易,因此它們可以用于關(guān)系數(shù)據(jù)庫(kù)。

雖然User和UserDao類在同一個(gè)應(yīng)用程序中獨(dú)立共存,但我們?nèi)匀恍枰纯春笳呷绾斡糜诒3殖志脤訉?duì)應(yīng)用程序邏輯的隱藏:

public class UserApplication {
?
????private static Dao userDao;
?
????public static void main(String[] args) {
????????userDao = new UserDao();
?????????
????????User user1 = getUser(0);
????????System.out.println(user1);
????????userDao.update(user1, new String[]{"Jake", "jake@domain.com"});
?????????
????????User user2 = getUser(1);
????????userDao.delete(user2);
????????userDao.save(new User("Julie", "julie@domain.com"));
?????????
????????userDao.getAll().forEach(user -> System.out.println(user.getName()));
????}
?
????private static User getUser(long id) {
????????Optional user = userDao.get(id);
?????????
????????return user.orElseGet(
??????????() -> new User("non-existing user", "no-email"));
????}
}

這個(gè)例子是人為的,但簡(jiǎn)而言之,它顯示了DAO模式背后的動(dòng)機(jī)。在這種情況下,main方法只使用UserDao實(shí)例對(duì)幾個(gè)User對(duì)象執(zhí)行CRUD操作。

此過程最相關(guān)的方面是UserDao如何從應(yīng)用程序中隱藏有關(guān)如何持久,更新和刪除對(duì)象的所有低級(jí)詳細(xì)信息。

將模式與JPA一起使用

開發(fā)人員普遍認(rèn)為JPA的發(fā)布將DAO模式的功能降級(jí)為零,因?yàn)樵撃J街皇荍PA實(shí)體經(jīng)理提供的另一層抽象和復(fù)雜性。

毫無(wú)疑問,在某些情況下這是事實(shí)。即便如此,有時(shí)我們只想向我們的應(yīng)用程序公開實(shí)體管理器API的一些特定于域的方法。在這種情況下,DAO模式有其自己的位置。

JpaUserDao類

話雖如此,讓我們創(chuàng)建一個(gè)Dao接口的新實(shí)現(xiàn),這樣我們就可以看到它如何封裝JPA實(shí)體管理器提供的開箱即用功能:

public class JpaUserDao implements Dao {
?????
????private EntityManager entityManager;
?????
????// standard constructors
?????
????@Override
????public Optional get(long id) {
????????return Optional.ofNullable(entityManager.find(User.class, id));
????}
?????
????@Override
????public List getAll() {
????????Query query = entityManager.createQuery("SELECT e FROM User e");
????????return query.getResultList();
????}
?????
????@Override
????public void save(User user) {
????????executeInsideTransaction(entityManager -> entityManager.persist(user));
????}
?????
????@Override
????public void update(User user, String[] params) {
????????user.setName(Objects.requireNonNull(params[0], "Name cannot be null"));
????????user.setEmail(Objects.requireNonNull(params[1], "Email cannot be null"));
????????executeInsideTransaction(entityManager -> entityManager.merge(user));
????}
?????
????@Override
????public void delete(User user) {
????????executeInsideTransaction(entityManager -> entityManager.remove(user));
????}
?????
????private void executeInsideTransaction(Consumer action) {
????????EntityTransaction tx = entityManager.getTransaction();
????????try {
????????????tx.begin();
????????????action.accept(entityManager);
????????????tx.commit(); 
????????}
????????catch (RuntimeException e) {
????????????tx.rollback();
????????????throw e;
????????}
????}
}

該JpaUserDao類是能夠與由JPA實(shí)現(xiàn)所支持的任何關(guān)系數(shù)據(jù)庫(kù)的工作。

此外,如果我們仔細(xì)研究這個(gè)類,我們將會(huì)意識(shí)到使用Composition和Dependency Injection如何允許我們只調(diào)用應(yīng)用程序所需的實(shí)體管理器方法。

簡(jiǎn)而言之,我們有一個(gè)特定于域的定制API,而不是整個(gè)實(shí)體管理器的API。

重構(gòu)User類

在這種情況下,我們將使用Hibernate作為JPA默認(rèn)實(shí)現(xiàn),因此我們將相應(yīng)地重構(gòu)User類:

@Entity
@Table(name = "users")
public class User {
?????
????@Id
????@GeneratedValue(strategy = GenerationType.AUTO)
????private long id;
?????
????private String name;
????private String email;
?????
????// standard constructors / setters / getters
}
以編程方式引導(dǎo)JPA實(shí)體管理器

假設(shè)我們已經(jīng)在本地或遠(yuǎn)程運(yùn)行MySQL的工作實(shí)例,并且數(shù)據(jù)庫(kù)表“users”填充了一些用戶記錄,我們需要獲得一個(gè)JPA實(shí)體管理器,因此我們可以使用JpaUserDao類來執(zhí)行CRUD操作數(shù)據(jù)庫(kù)。

在大多數(shù)情況下,我們通過典型的“persistence.xml”文件來實(shí)現(xiàn)這一點(diǎn),這是標(biāo)準(zhǔn)方法。

在這種情況下,我們將采用“xml-less”方法,通過Hibernate方便的EntityManagerFactoryBuilderImpl類獲取具有普通Java的實(shí)體管理器。

有關(guān)如何使用Java引導(dǎo)JPA實(shí)現(xiàn)的詳細(xì)說明,請(qǐng)查看用Java編程引導(dǎo)JPA。

UserApplication類

最后,讓我們重構(gòu)一下初始的UserApplication類,這樣它就可以使用JpaUserDao實(shí)例并在User實(shí)體上執(zhí)行CRUD操作:

public class UserApplication {
?
????private static Dao jpaUserDao;
?
????// standard constructors
?????
????public static void main(String[] args) {
????????User user1 = getUser(1);
????????System.out.println(user1);
????????updateUser(user1, new String[]{"Jake", "jake@domain.com"});
????????saveUser(new User("Monica", "monica@domain.com"));
????????deleteUser(getUser(2));
????????getAllUsers().forEach(user -> System.out.println(user.getName()));
????}
?????
????public static User getUser(long id) {
????????Optional user = jpaUserDao.get(id);
?????????
????????return user.orElseGet(
??????????() -> new User("non-existing user", "no-email"));
????}
?????
????public static List getAllUsers() {
????????return jpaUserDao.getAll();
????}
?????
????public static void updateUser(User user, String[] params) {
????????jpaUserDao.update(user, params);
????}
?????
????public static void saveUser(User user) {
????????jpaUserDao.save(user);
????}
?????
????public static void deleteUser(User user) {
????????jpaUserDao.delete(user);
????}
}

即使示例確實(shí)非常有限,它仍然有助于演示如何將DAO模式的功能與實(shí)體管理器提供的功能集成。

在大多數(shù)應(yīng)用程序中,有一個(gè)DI框架,它負(fù)責(zé)將JpaUserDao實(shí)例注入U(xiǎn)serApplication類。為簡(jiǎn)單起見,我們省略了此過程的詳細(xì)信息。

最相關(guān)的點(diǎn)這里要強(qiáng)調(diào)的是如何在JpaUserDao類有助于保持UserApplication類完全無(wú)關(guān)關(guān)于持久層如何執(zhí)行CRUD操作。

此外,由于Dao接口和實(shí)體管理器提供的抽象級(jí)別,我們可以將MySQL交換到任何其他RDBMS(甚至是平面數(shù)據(jù)庫(kù)),而且,我們的應(yīng)用程序仍將按預(yù)期繼續(xù)工作。

案例結(jié)論

在本文中,我們深入研究了DAO模式的關(guān)鍵概念,如何在Java中實(shí)現(xiàn)它,以及如何在JPA的實(shí)體管理器之上使用它。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/73167.html

相關(guān)文章

  • Java 23種設(shè)計(jì)模式----適配器模式

    摘要:適配器模式的結(jié)構(gòu)通過繼承實(shí)現(xiàn)通過委讓實(shí)現(xiàn)代碼實(shí)現(xiàn)目標(biāo)類使用數(shù)據(jù)線適配類使用轉(zhuǎn)適配線主函數(shù)與在適配器模式中的應(yīng)用當(dāng)前,不少公司使用整合進(jìn)行系統(tǒng)開發(fā)。 Java 23種設(shè)計(jì)模式----適配器模式 1、面向?qū)ο驩O = 面向?qū)ο蠓治鯫OA + 面向?qū)ο笤O(shè)計(jì)OOD + 面向?qū)ο缶幊蘋OP 2、編程是一門技術(shù)、同時(shí)也是一門藝術(shù) 3、應(yīng)該面向接口編程,而不是面向?qū)崿F(xiàn)編程 什么是設(shè)計(jì)模式 設(shè)計(jì)模式是...

    VincentFF 評(píng)論0 收藏0
  • Spring AOP從零單排-織入時(shí)期源碼分析

    摘要:何為簡(jiǎn)單點(diǎn)來定義就是切面,是一種編程范式。定義一個(gè)切面的載體定義一個(gè)切點(diǎn)定義一個(gè)為,并指定對(duì)應(yīng)的切點(diǎn)一個(gè)注冊(cè)配置類,啟動(dòng)容器,初始化時(shí)期獲取對(duì)象,獲取對(duì)象時(shí)期,并進(jìn)行打印好了,這樣我們整體的代理就已經(jīng)完成。 問題:Spring AOP代理中的運(yùn)行時(shí)期,是在初始化時(shí)期織入還是獲取對(duì)象時(shí)期織入? 織入就是代理的過程,指目標(biāo)對(duì)象進(jìn)行封裝轉(zhuǎn)換成代理,實(shí)現(xiàn)了代理,就可以運(yùn)用各種代理的場(chǎng)景模式。 ...

    honmaple 評(píng)論0 收藏0
  • dao 設(shè)計(jì)模式

    摘要:介紹功能是數(shù)據(jù)操作客戶發(fā)送數(shù)據(jù)到顯示層顯示層發(fā)送數(shù)據(jù)到業(yè)務(wù)層業(yè)務(wù)發(fā)送數(shù)據(jù)到數(shù)據(jù)層數(shù)據(jù)層進(jìn)行持久化即保存進(jìn)入一些簡(jiǎn)稱業(yè)務(wù)對(duì)象的簡(jiǎn)稱一個(gè)數(shù)據(jù)訪問對(duì)象增刪查改數(shù)據(jù)庫(kù)一條記錄映射成對(duì)象擁有方法為什么使用把的操作進(jìn)行分離即數(shù)據(jù)庫(kù)的操作和業(yè)務(wù)進(jìn)行分離是 介紹 DAO功能是數(shù)據(jù)操作.客戶發(fā)送數(shù)據(jù)到顯示層,顯示層發(fā)送數(shù)據(jù)到業(yè)務(wù)層,業(yè)務(wù)發(fā)送數(shù)據(jù)到數(shù)據(jù)層,數(shù)據(jù)層進(jìn)行持久化.即.保存進(jìn)入databases ...

    rickchen 評(píng)論0 收藏0
  • web開發(fā)模式

    摘要:顯示層控制層數(shù)據(jù)層統(tǒng)一交給或者處理處理流程客戶端發(fā)送到執(zhí)行讀取返回返回給在返回給在給客戶端問題代碼雜亂即方式客戶端發(fā)送到然后執(zhí)行用于讀取控制器獲取到讀取的數(shù)據(jù)以后再次返回給生成文件給客戶端分為顯示層控制層模型層屬于提供的分布式組件服務(wù)分 Model1 顯示層,控制層,數(shù)據(jù)層,統(tǒng)一交給jsp或者javabean處理. 處理流程 客戶端發(fā)送request 到 jsp jsp 執(zhí)行java...

    ztyzz 評(píng)論0 收藏0
  • DAO開發(fā)小試

    摘要:在代理類完成以后,最后還需要編寫工廠類,以降低代碼間的耦合度。工廠類工廠類的功能就是直接返回接口的實(shí)例化對(duì)象這樣客戶端就可以直接通過工廠類取得接口的實(shí)例化對(duì)象。 數(shù)據(jù) DAO的開發(fā)完全圍繞著數(shù)據(jù)進(jìn)行,先在數(shù)據(jù)庫(kù)中準(zhǔn)備幾個(gè)要用到的表: sqlcreate table emp ( empno int(4) PRIMARY KEY, ename varchar(10...

    Lorry_Lu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

TIGERB

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<