我無法明確的告訴你JPA和MyBatis在國內(nèi)哪個(gè)會(huì)更流行,我本人更喜歡JPA,但是我本人日常開發(fā)用MyBatis多。
但是我的回答絕對(duì)不是在劃水,而是我多年來自己的一點(diǎn)小小的思考。MyBatis用好了就是神!用不好就特么一坨……并且,這個(gè)框架只有兩個(gè)結(jié)果,要么就是用的好,要么就是用不好……
而JPA,用不好,比MyBatis還一坨……但是用好了,那是超越神的存在,因?yàn)槟阋呀?jīng)完全脫離了事務(wù)腳本。
有沒有更牛逼的?
有,但是現(xiàn)實(shí)中你基本遇不到這樣的大神,因?yàn)檫@樣的大神在成為大神之前,要么早就財(cái)務(wù)自由了,要么就轉(zhuǎn)管理了。
國內(nèi)大多數(shù)項(xiàng)目其實(shí)根本沒有設(shè)計(jì)過程,都是想到哪兒寫到哪兒,別說領(lǐng)域模型的設(shè)計(jì)了,就連OOP都沒有,都是披著OOP的外殼在寫過程。
當(dāng)然這是大環(huán)境所逼迫的,并不是程序員、架構(gòu)師所能左右的,大環(huán)境就很浮躁,就認(rèn)為一個(gè)月能開發(fā)出一個(gè)支付寶,你沒辦法去抗衡它,大家都要吃飯的嘛,我為什么要打擊別人的夢想呢?只要您給錢,我就盡量滿足您。
我(曾經(jīng))非常憤恨這種劣幣驅(qū)逐良幣的環(huán)境,本來大家都是安心做設(shè)計(jì),然后水到渠成的進(jìn)行開發(fā),客戶也是和和氣氣的跟開發(fā)進(jìn)行商討,結(jié)果有些人念歪了敏捷的經(jīng),更有甚者,讀了一本《人人都是產(chǎn)品經(jīng)理》就真的認(rèn)為自己是個(gè)非常牛逼的產(chǎn)品經(jīng)理了。
都特么一群....
千萬不要自信的認(rèn)為,前三十年的懶惰,通過一兩本書就能解決自己知識(shí)的匱乏。
結(jié)果就是導(dǎo)致現(xiàn)在大家都不喜歡靜下心來搞設(shè)計(jì),而是喜歡不管三七十二一先沖山頭再說,稍微有點(diǎn)前瞻性的考慮都認(rèn)為你是過度設(shè)計(jì)。
- 你跟他說制定作戰(zhàn)計(jì)劃。
- 毛的的作戰(zhàn)計(jì)劃,全都給我上,見招拆招,逢人便打就對(duì)了。
仔細(xì)一想,好像也沒說錯(cuò)什么……
但是如果重心放在設(shè)計(jì)上,那么自然JPA在OOP上比MyBatis優(yōu)秀太多太多了。
封裝、繼承、多態(tài)抽象、接口、實(shí)現(xiàn)
一說到OOP,大家都信手拈來,甚至什么貧血模型、充血模型、脹血模型都跟你說的頭頭是道,但是一涉及到實(shí)際開發(fā)全都拋到腦后去了。
仔細(xì)想想,有多久沒有寫類似下面這種代碼了?(隨便寫著玩的,Lombok僅為減少代碼行數(shù))
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name="uaa_account")
@Entity
public class Account {
/* 狀態(tài) */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
/* 構(gòu)造 */
private AccountRepository accountRepository;
public Account(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
/* 行為 */
public void login(LoginCommand command) {}
public void register(RegisterCommand command){}
/* 事件驅(qū)動(dòng) */
@PostPersist
public void emmitEvent() {}
}
再說一個(gè)讓很多開發(fā)感到恐懼的事情:
public abstract class AbstractDomAIn {
@Getter
protected final String attr;
public AbstractDomain(String attr) {
this.attr = attr;
}
}
試問一下,你有多久沒有寫抽象類和受保護(hù)的狀態(tài)了?final 這個(gè)關(guān)鍵字,如果沒有Sonar,大家是不是快把它給忘記了?
只讀屬性究竟意味著什么還記得嗎?
Collections.unmodifiableList() 不可變集合到底用來干嘛的?我估計(jì)90%的開發(fā)都沒用過這個(gè)玩意兒吧?

約書亞·布洛克(英語:Joshua J. Bloch,1961年8月28日-),美國著名程序員。他為JAVA平臺(tái)設(shè)計(jì)并實(shí)作了許多的功能,曾擔(dān)任google的首席Java架構(gòu)師(Chief Java Architect)。
2001年出版Effective Java,獲得2001年Jolt獎(jiǎng)。詹姆斯·高斯林曾表示相當(dāng)贊賞此書。
大神的代碼隨處可見,你離大神就是那么的近。
- SOLID五大原則,你是否已經(jīng)忘記的一干二凈了?
- 你的代碼是否只有分層,而沒有模式?
- 23種設(shè)計(jì)模式,隨口能說五六個(gè),但是這五六個(gè)都用來解決什么問題的,有沒有仔細(xì)思考過?
我從2018年開始負(fù)責(zé)面試,到今年已經(jīng)接近三年了,期間從HR提交過來自己走眼的簡歷至少兩千份,現(xiàn)場面試差不多有四百人,能把設(shè)計(jì)模式和面向?qū)ο笳f清楚的,寥寥無幾。
現(xiàn)在大家的重心都是怎么快速的沖鋒,前面三個(gè)山頭,也不給你一個(gè)具體的目標(biāo),反正你給我沖,沖到哪里咱不管,起碼你沖了。
于是我們可以看到99%的代碼結(jié)構(gòu)就是:
- Controller - 幾乎沒代碼
- Service - 重災(zāi)區(qū)
- Utils - 重災(zāi)區(qū)
- Entity - 跟VO有啥區(qū)別?
- Repository 或 MApper 或 Dao - 幾乎沒代碼
- Mapper.xml - 證明我是SQL小王子的時(shí)候到了
- Test - What? 這干嘛的?
Service太重了,隨便翻開一個(gè)Service,里面的代碼一大堆。
不信隨手翻一下現(xiàn)有的項(xiàng)目,超過一千行的Service是不是到處都是?
我形容這種開發(fā)為豬突式開發(fā)。
那么這個(gè)時(shí)候,MyBatis牛逼的地方就顯現(xiàn)出來了。
幸好還有個(gè)Spring框架如果沒有Spring框架,什么OOP,扯犢子呢?抓緊往上懟懟懟懟代碼,懟完拉倒。
框架是為了簡化開發(fā)任務(wù),讓你有更多的時(shí)間去做程序設(shè)計(jì)和邏輯架構(gòu)。所以,哪個(gè)會(huì)更流行取決于大環(huán)境,而不是開發(fā)人員。我本人是更喜歡先設(shè)計(jì),后開發(fā)的。
但是我同樣是一個(gè)有同情心的人,我不忍心破壞別人想當(dāng)一個(gè)架構(gòu)師的夢想,雖然他可能一行代碼都沒寫過,我依然支持他,當(dāng)然前提是該背的鍋你得背,該我的錢一個(gè)子兒都不能少。
說些題外話
我個(gè)人有三種開發(fā)方式,第一種是前端驅(qū)動(dòng),第二種是后端驅(qū)動(dòng)(好像說的是廢話……),第三種是數(shù)據(jù)驅(qū)動(dòng)。
前端驅(qū)動(dòng)顧名思義,就是做一個(gè)項(xiàng)目,前端先上,前端根據(jù)設(shè)計(jì)稿和產(chǎn)品文檔實(shí)現(xiàn)了UI之后,后端再根據(jù)前端UI去設(shè)計(jì)后臺(tái)架構(gòu)。這么做的好處在于無論是客戶還是開發(fā),都能面向一個(gè)具體的頁面進(jìn)行需求討論和架構(gòu)設(shè)計(jì),最終實(shí)現(xiàn)結(jié)果不會(huì)跑偏。
前端的開發(fā)速度是比后端快的,因此在發(fā)生需求變動(dòng)的時(shí)候,響應(yīng)速度也非常快,實(shí)在有一些比較難處理的UI,例如需要Canvas繪圖的地方,通過口頭(或文檔)補(bǔ)充即可。但是這種方式只適合一些面向客戶的小項(xiàng)目,而不是面向產(chǎn)品的項(xiàng)目,就是說客戶要什么就給他什么,他要一匹馬,你就別給他設(shè)計(jì)一輛車,到時(shí)候吃力不討好。
這種類型的項(xiàng)目,MyBatis最合適。
如果一個(gè)項(xiàng)目非常大,例如從頭開始設(shè)計(jì)一個(gè)B2B的交易平臺(tái)(包括后臺(tái)ERP)產(chǎn)品,就不能采用這種方式。
因?yàn)椴捎眠@種方式的壞處在于他不能站在高處俯瞰全貌,都是一點(diǎn)一點(diǎn)的往上堆砌,就是大家常說的摸著石頭過河,最終會(huì)導(dǎo)致抽象不足,代碼冗余,重構(gòu)成本高,維護(hù)成本高,數(shù)據(jù)孤島嚴(yán)重,子系統(tǒng)甚至是子模塊業(yè)務(wù)互斥,向著惡性循環(huán)發(fā)展,最終項(xiàng)目變得越來越龐雜,無數(shù)的內(nèi)耗產(chǎn)生。
大的項(xiàng)目,一定要從數(shù)據(jù)建模開始設(shè)計(jì),一定是后端驅(qū)動(dòng),要認(rèn)真仔細(xì)的思考每一個(gè)細(xì)節(jié),先做抽象設(shè)計(jì),然后具象到模塊,再由模塊具象到每一個(gè)實(shí)體、接口。
當(dāng)這一切都設(shè)計(jì)好了之后,開始模擬數(shù)據(jù)流轉(zhuǎn),注意,此時(shí)還沒有開始寫一行代碼。
數(shù)據(jù)流轉(zhuǎn)通暢之后,剩下的編碼只是水到渠成的事情,編碼過程根本不重要。而這么做,JPA是最合適的。
但是,大部分土老帽認(rèn)為程序設(shè)計(jì)是一件很low bee的事情,別笑,真事兒,因?yàn)樗麄冋J(rèn)為不需要你來設(shè)計(jì),他們自己就能設(shè)計(jì)好,你所要做的就是把他們“設(shè)計(jì)”好的東西用代碼實(shí)現(xiàn)就好了。
他們最喜歡聽的一句話就是:
嗯!老板說得對(duì),小的馬上就去寫代碼!
而不是:
老板,我覺得這個(gè)地方需要重新設(shè)計(jì)一下。
最后一種,是數(shù)據(jù)驅(qū)動(dòng),這種開發(fā)方式也很常見,最明顯的就是報(bào)表以及大部分掛羊頭賣狗肉的大數(shù)據(jù)處理,因?yàn)榫瓦@些數(shù)據(jù),你很難去做后端驅(qū)動(dòng),你設(shè)計(jì)的再好,數(shù)據(jù)就是缺失的你沒辦法。
所以數(shù)據(jù)驅(qū)動(dòng),MyBatis也是比較合適的,JPA可能不太合適。
來源:
zhihu.com/question/317183937/answer/1474629982