www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > > 架構(gòu)師社區(qū)
[導(dǎo)讀]本質(zhì)上 ORM 框架并沒有性能的區(qū)分度,因?yàn)樽罱K都是轉(zhuǎn)換成 sql 交給數(shù)據(jù)庫引擎去執(zhí)行,ORM 層面那層性能損耗幾乎可以忽略不計(jì)。

前言

JPA 和 Mybatis 的爭論由來已久,還記得在 2 年前我就在 spring4all 社區(qū)就兩者孰優(yōu)孰劣的話題發(fā)表了觀點(diǎn),我當(dāng)時(shí)是力挺 JPA 的,這當(dāng)然跟自己對 JPA 熟悉程度有關(guān),但也有深層次的原因,便是 JPA 的設(shè)計(jì)理念契合了領(lǐng)域驅(qū)動設(shè)計(jì)的思想,可以很好地指導(dǎo)我們設(shè)計(jì)數(shù)據(jù)庫交互接口。這兩年工作中,逐漸接觸了一些使用 Mybatis 的項(xiàng)目,也對其有了一定新的認(rèn)知。都說認(rèn)知是一個(gè)螺旋上升的過程,隨著經(jīng)驗(yàn)的累積,人們會輕易推翻過去,到了兩年后的今天,我也有了新的觀點(diǎn)。本文不是為了告訴你 JPA 和 Mybatis 到底誰更好,而是嘗試求同存異,甚至是在項(xiàng)目中同時(shí)使用 JPA 和 Mybatis。什么?要同時(shí)使用兩個(gè) ORM 框架,有這個(gè)必要嗎?別急著吐槽我,希望看完本文后,你也可以考慮在某些場合下同時(shí)使用這兩個(gè)框架。

ps. 本文討論的 JPA 特指 spring-data-jpa。

建模

@Entity @Table(name = "t_order") public class Order { @Id private String oid; @Embedded private CustomerVo customer; @OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "order") private ListorderItems;
}

JPA 最大的特點(diǎn)是 sqlless,如上述的實(shí)體定義,便將數(shù)據(jù)庫的表和 Java 中的類型關(guān)聯(lián)起來了,JPA 可以做到根據(jù) @Entity 注解,自動創(chuàng)建表結(jié)構(gòu);基于這個(gè)實(shí)體實(shí)現(xiàn)的 Repository 接口,又使得 JPA 用戶可以很方便地實(shí)現(xiàn)數(shù)據(jù)的 CRUD。所以,使用 JPA 的項(xiàng)目,人們很少會提到”數(shù)據(jù)庫設(shè)計(jì)“,人們更關(guān)心的是領(lǐng)域建模,而不是數(shù)據(jù)建模。

<generatorConfiguration> <context id="my" targetRuntime="MyBatis3"> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="" userId="" password=""/> <javaModelGenerator targetPackage="" targetProject="" /> <sqlMapGenerator targetPackage="" targetProject="" /> <javaClientGenerator targetPackage="moe.cnkirito.demo.mapper" /> <table tableName="t_order" domainObjectName="Order" /> context> generatorConfiguration>

Mybatis 用戶更多使用的是逆向工程,例如 mybatis-generator 插件根據(jù)如上的 xml 配置,便可以直接將表結(jié)構(gòu)轉(zhuǎn)譯成 mapper 文件和實(shí)體文件。

code first 和 table first 從結(jié)果來看是沒有區(qū)別的,差異的是過程,所以設(shè)計(jì)良好的系統(tǒng),并不會僅僅因?yàn)檫@個(gè)差異而高下立判,但從指導(dǎo)性來看,無疑設(shè)計(jì)系統(tǒng)時(shí),更應(yīng)該考慮的是實(shí)體和實(shí)體,實(shí)體和值對象的關(guān)聯(lián),領(lǐng)域邊界的劃分,而不是首先著眼于數(shù)據(jù)庫表結(jié)構(gòu)的設(shè)計(jì)。

建模角度來看,JPA 的領(lǐng)域建模思想更勝一籌。

數(shù)據(jù)更新

聊數(shù)據(jù)庫自然離不開 CRUD,先來看增刪改這些數(shù)據(jù)更新操作,來看看兩個(gè)框架一般的習(xí)慣是什么。

JPA 推崇的數(shù)據(jù)更新只有一種范式,分成三步:

  1. 先 findOne 映射成實(shí)體
  2. 內(nèi)存內(nèi)修改實(shí)體
  3. 實(shí)體整體 save

你可能會反駁我說,@Query 也存在 nativeQuery 和 JPQL 的用法,但這并不是主流用法。JPA 特別強(qiáng)調(diào)”整體 save“的思想,這與領(lǐng)域驅(qū)動設(shè)計(jì)所強(qiáng)調(diào)的有狀態(tài)密不可分,即其認(rèn)為,修改不應(yīng)該是針對于某一個(gè)字段:”update table set a=b where colomonA=xx“ ,而應(yīng)該反映成實(shí)體的變化,save 則代表了實(shí)體狀態(tài)最終的持久化。

先 find 后 save 顯然也適用于 Mybatis,而 Mybatis 的靈活性,使得其數(shù)據(jù)更新方式更加地百花齊放。路人甲可以認(rèn)為 JPA 墨守成規(guī)不懂變通,認(rèn)為 Mybatis 不羈放縱愛自由;路人乙也可以認(rèn)為 JPA 格式規(guī)范易維護(hù),Mybatis 不成方圓。這點(diǎn)不多加評判,留后人說。

從個(gè)人習(xí)慣來說,我還是偏愛先 find 后整體 save 這種習(xí)慣的,不是說這是 JPA 的專利,Mybatis 不具備;而是 JPA 的強(qiáng)制性,讓我有了這個(gè)習(xí)慣。

數(shù)據(jù)更新角度來看,JPA 強(qiáng)制使用 find+save,mybatis 也可以做到這一點(diǎn),勝者:無。

數(shù)據(jù)查詢

JPA 提供的查詢方式主要分為兩種

  1. 簡單查詢:findBy + 屬性名
  2. 復(fù)雜查詢:JpaSpecificationExecutor

簡單查詢在一些簡單的業(yè)務(wù)場景下提供了非常大的便捷性,findBy + 屬性名可以自動轉(zhuǎn)譯成 sql,試問如果可以少寫代碼,有誰不愿意呢?

復(fù)雜查詢則是 JPA 為了解決復(fù)雜的查詢場景,提供的解決方案,硬是把數(shù)據(jù)庫的一些聚合函數(shù),連接操作,轉(zhuǎn)換成了 Java 的方法,雖然做到了 sqlless,但寫出來的代碼又臭又長,也不見得有多么的易讀易維護(hù)。這算是我最不喜歡 JPA 的一個(gè)地方了,但要解決復(fù)雜查詢,又別無他法。

而 Mybatis 可以執(zhí)行任意的查詢 sql,靈活性是 JPA 比不了的。數(shù)據(jù)庫小白搜索的最多的兩個(gè)問題:

  1. 數(shù)據(jù)庫分頁怎么做
  2. 條件查詢怎么做

Mybatis 都可以輕松的解決。

千萬不要否認(rèn)復(fù)雜查詢:如聚合查詢、Join 查詢的場景。令一個(gè) JPA 用戶抓狂的最簡單方式,就是給他一個(gè)復(fù)雜查詢的 case。

select a,b,c,sum(a) where a=xx and d=xx group by a,b,c;

來吧,展示。可能 JPA 的確可以完成上述 sql 的轉(zhuǎn)義,但要知道不是所有開發(fā)都是 JPA 專家,沒人關(guān)心你用 JPA 解決了多么復(fù)雜的查詢語句,更多的人關(guān)心是,能不能下班前把這個(gè)復(fù)雜查詢搞定,早點(diǎn)回家。

在回到復(fù)雜數(shù)據(jù)查詢需求本身的來分析下。我們假設(shè)需求是合理的,畢竟項(xiàng)目的復(fù)雜性難以估計(jì),可能有 1000 個(gè)數(shù)據(jù)查詢需求 JPA 都可以很方便的實(shí)現(xiàn),但就是有那么 10 幾個(gè)復(fù)雜查詢 JPA hold 不住。這個(gè)時(shí)候你只能乖乖地去寫 sql 了,如果這個(gè)時(shí)候又出現(xiàn)一個(gè)條件查詢的場景,出現(xiàn)了 if else 意味著連 @Query 都用不了,完全退化成了 JdbcTemplate 的時(shí)代。

那為什么不使用 Mybatis 呢?Mybatis 使用者從來沒有糾結(jié)過復(fù)雜查詢,它簡直就是為之而生的。

如今很多 Mybatis 的插件,也可以幫助使用者快速的生成基礎(chǔ)方法,雖然仍然需要寫 sql,但是這對于開發(fā)者來說,并不是一件難事。

不要質(zhì)疑高并發(fā)下,JOIN 操作和聚合函數(shù)存在的可能性,數(shù)據(jù)查詢場景下,Mybatis 完勝。

性能

本質(zhì)上 ORM 框架并沒有性能的區(qū)分度,因?yàn)樽罱K都是轉(zhuǎn)換成 sql 交給數(shù)據(jù)庫引擎去執(zhí)行,ORM 層面那層性能損耗幾乎可以忽略不計(jì)。

但從實(shí)際出發(fā),Mybatis 提供給了開發(fā)者更高的 sql 自由度,所以在一些需要 sql 調(diào)優(yōu)的場景下會更加靈活。

可維護(hù)性

前面我們提到 JPA 相比 Mybatis 喪失了 sql 的自由度,凡事必有 trade off,從另一個(gè)層面上來看,其提供了高層次的抽象,嘗試用統(tǒng)一的模型去解決數(shù)據(jù)層面的問題。sqlless 同時(shí)也屏蔽了數(shù)據(jù)庫的實(shí)現(xiàn),屏蔽了數(shù)據(jù)庫高低版本的兼容性問題,這對可能存在的數(shù)據(jù)庫遷移以及數(shù)據(jù)庫升級提供了很大的便捷性。

同時(shí)使用兩者

其他細(xì)節(jié)我就不做分析了,相信還有很多點(diǎn)可以拿過來做對比,但我相信主要的點(diǎn)上文都應(yīng)該有所提及了。進(jìn)行以上維度的對比并不是我寫這篇文章的初衷,更多地是想從實(shí)際開發(fā)角度出發(fā),為大家使用這兩個(gè)框架提供一些參考建議。

在大多數(shù)場景下,我習(xí)慣使用 JPA,例如設(shè)計(jì)領(lǐng)域?qū)ο髸r(shí),得益于 JPA 的正向模型,我會優(yōu)先考慮實(shí)體和值對象的關(guān)聯(lián)性以及領(lǐng)域上下文的邊界,而不用過多關(guān)注如何去設(shè)計(jì)表結(jié)構(gòu);在增刪改和簡單查詢場景下,JPA 提供的 API 已經(jīng)是刻在我 DNA 里面的范式了,使用起來非常的舒服。

在復(fù)雜查詢場景下,例如

  1. 包含不存在領(lǐng)域關(guān)聯(lián)的 join 查詢
  2. 包含多個(gè)聚合函數(shù)的復(fù)雜查詢
  3. 其他 JPA 較難實(shí)現(xiàn)的查詢

我會選擇使用 Mybatis,有點(diǎn)將 Mybatis 當(dāng)做數(shù)據(jù)庫視圖生成器的意味。堅(jiān)定不移的 JPA 擁躉者可能會質(zhì)疑這些場景的存在的真實(shí)性,會質(zhì)疑是不是設(shè)計(jì)的漏洞,但按照經(jīng)驗(yàn)來看,哪怕是短期方案,這些場景也是客觀存在的,所以聽我一言,嘗試擁抱一下 Mybatis 吧。

隨著各類存儲中間件的流行,例如 mongodb、ES,取代了數(shù)據(jù)庫的一部分地位,重新思考下,本質(zhì)上都是在用專業(yè)的工具解決特定場景的問題,最終目的都是為了解放生產(chǎn)力。數(shù)據(jù)庫作為最古老,最基礎(chǔ)的存儲組件,的確承載了很多它本不應(yīng)該承受的東西,那又何必讓一個(gè)工具或者一個(gè)框架成為限制我們想象力的溝壑呢?

兩個(gè)框架其實(shí)都不重,在 springboot 的加持下,引入幾行配置就可以實(shí)現(xiàn)兩者共存了。

我自己在最近的項(xiàng)目中便同時(shí)使用了兩者,遵循的便是本文前面聊到的這些規(guī)范,我也推薦給你,不妨試試。


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計(jì)工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉