在開(kāi)發(fā)者的圈子里,沒(méi)當(dāng)說(shuō)到一種技術(shù)好或者不好,都會(huì)引發(fā)激烈或者不激烈的爭(zhēng)論,直到一個(gè)開(kāi)發(fā)者出來(lái)說(shuō) PHP 是世界上最好的語(yǔ)言,大家伙兒才會(huì)紛紛退去繼續(xù)寫(xiě)代碼。
今天說(shuō) JPA 的問(wèn)題不是想引發(fā)什么討論或者罵戰(zhàn),單純的就是我不喜歡 JPA 。沒(méi)錯(cuò),就是這么 Real。
說(shuō)到 Java 開(kāi)發(fā),涉及到數(shù)據(jù)庫(kù)訪問(wèn)的,主要就兩種框架,一個(gè)是 MyBatis ,另一個(gè)就是 JPA。據(jù)說(shuō)是國(guó)外 JPA 用的比較多,國(guó)內(nèi) MyBatis
用的比較多。國(guó)內(nèi)為什么 MyBatis 用的多呢,傳說(shuō)是因?yàn)檎麄€(gè)阿里系都用它。
JPA 全稱是Java 持久化 API ,它的目的就是幫助我們提高開(kāi)發(fā)效率,它的核心是 Java持久化查詢語(yǔ)言
(JPQL),對(duì)存儲(chǔ)在關(guān)系數(shù)據(jù)庫(kù)中的實(shí)體進(jìn)行查詢。在語(yǔ)法上類似于SQL查詢,但是操作的是實(shí)體對(duì)象而不是直接對(duì)數(shù)據(jù)庫(kù)表進(jìn)行操作。(摘自 wiki)
使用 JPA 開(kāi)發(fā)的流程如下:
1、將數(shù)據(jù)庫(kù)表映射到項(xiàng)目實(shí)體中
2、生成對(duì)應(yīng)的 Repository
3、實(shí)現(xiàn) Service ,Service 中調(diào)用 Repository
JPA 幫你省事兒的地方就在 Repository
里,對(duì)于那些比較簡(jiǎn)單的邏輯,比如單表查詢,直接根據(jù)名字就可以實(shí)現(xiàn)查詢邏輯。對(duì)于大部分查詢來(lái)說(shuō),真的很省事兒。但剛開(kāi)始用的時(shí)候,確實(shí)感覺(jué)有些莫名其妙。
確實(shí)如此,如果你用過(guò) JPA ,有些時(shí)候它確實(shí)對(duì)開(kāi)發(fā)效率有很大提升,JPA 想要做的就是盡量讓你少寫(xiě) sql,甚至不寫(xiě) sql?;谶@種思想,JPA
實(shí)現(xiàn)了它自己的一套語(yǔ)法、注解規(guī)則。
JPA
要用各種注解配合來(lái)實(shí)現(xiàn)數(shù)據(jù)實(shí)體間的一對(duì)多、多對(duì)多等等的關(guān)聯(lián)關(guān)系。正因?yàn)檫@樣,我覺(jué)得實(shí)體變得不單純是實(shí)體,而是摻雜的邏輯在里面,也增加了實(shí)體的復(fù)雜度,對(duì)于比較復(fù)雜的業(yè)務(wù)來(lái)說(shuō),很容易造成實(shí)體間直接或間接的循環(huán)引用。
你如果想用 JPA,除了要掌握各種注解外,對(duì)于稍微復(fù)雜的查詢,還要掌握它的那套寫(xiě)法,比如下面這種代碼:
Specification<CmContent> specification = (root, criteriaQuery,
criteriaBuilder) -> { Predicate p =
criteriaBuilder.equal(root.get("deleted").as(Boolean.class), false); Predicate
news = criteriaBuilder.equal(root.get("cntntType"),
ContentType.CNTNTTP_NEWS.name()); Predicate salon =
criteriaBuilder.equal(root.get("cntntType"), ContentType.CNTNTTP_SALON.name());
Predicate type = criteriaBuilder.or(news, salon); ...
而且你想要實(shí)現(xiàn)一個(gè) join 查詢也是夠費(fèi)勁的,除了要寫(xiě)上面那套代碼外,還要在實(shí)體上做手腳,想到就想哭,有沒(méi)有。難道直接寫(xiě)個(gè) sql
不好嗎,為什么要這么糟蹋自己。
還有一點(diǎn),JPA
有些注解用上了之后會(huì)影響到數(shù)據(jù)庫(kù)層面,比方說(shuō)關(guān)鍵外鍵的注解,如果你用默認(rèn)設(shè)置,這個(gè)外鍵就真的會(huì)應(yīng)用到數(shù)據(jù)庫(kù)表里,在表上建外鍵。還有其他的一些 ORM
框架也是如此,這是我完全不能接受的,憑什么,憑什么在我的數(shù)據(jù)庫(kù)上改東西。
愿我參與的項(xiàng)目中沒(méi)有 JPA。公司有個(gè)項(xiàng)目用到了 JPA ,我也參與了一部分,寫(xiě)的代碼不算多,除了令我頭疼之外,沒(méi)有體會(huì)到 JPA
的半點(diǎn)好處,這其中當(dāng)然很可能是由于我的水平有限,或者說(shuō)我寫(xiě)的 JPA 代碼不夠多,或者我根本沒(méi)有領(lǐng)會(huì)到 JPA
的精髓所在。總之不管怎么樣,對(duì)不起,愿我不會(huì)再碰到 JPA。
當(dāng)然這么說(shuō)肯定是有失偏頗,有些同學(xué)可能會(huì)對(duì)此嗤之以鼻。沒(méi)錯(cuò),有同事就是這樣說(shuō)的:事物存在即合理,JPA 這么多年了,如果不好用怎么會(huì)還有這么多人用,而且國(guó)外
JPA 使用者眾多,難道人家都有問(wèn)題。
如果只是簡(jiǎn)單的項(xiàng)目,業(yè)務(wù)一點(diǎn)也不復(fù)雜,不復(fù)雜到連個(gè) join 都沒(méi)有的項(xiàng)目,可以用 JPA ,其他的情況下,真的不用它最好。用 JPA
的感覺(jué)就像是被綁上了手腳,失去了自由。不自由,毋寧死??v使千般好,少了自由,我就拒絕它。而 MyBatis 恰恰就是給開(kāi)發(fā)者自由的一個(gè)框架。
還是那句話,不自由,毋寧死。這是第一個(gè),恐怕也是最后一個(gè)用 JPA 的項(xiàng)目了。
不要吝惜你的「推薦」呦
歡迎關(guān)注,不定期更新本系列和其他文章
古時(shí)的風(fēng)箏 ,進(jìn)入公眾號(hào)可以加入交流群
熱門工具 換一換
