jpa 和hibernate 有哪些區(qū)別 你平時主要使用什么Java開發(fā)框架?
你平時主要使用什么Java開發(fā)框架?就拿我們項目來舉例子扒一扒吧。我們的項目是一個純后臺服務(wù)的項目,也就是沒有前端頁面,只正式提供服務(wù);項目是是實現(xiàn)Spring Boot來做的,引導出spring-b
你平時主要使用什么Java開發(fā)框架?
就拿我們項目來舉例子扒一扒吧。
我們的項目是一個純后臺服務(wù)的項目,也就是沒有前端頁面,只正式提供服務(wù);項目是是實現(xiàn)Spring Boot來做的,引導出spring-boot-starter-web,直接對外不暴露接口,報文建議使用的JSON,有極大多數(shù)的接口是從老系統(tǒng)遷出上來的,目的是讓動態(tài)鏈接庫方盡肯定地稍作改,所以我達到了XML的報文;在開始的生產(chǎn)環(huán)境中,也不使用的內(nèi)置的Tomcat;集成顯卡了Swagger,來做接口的文檔在線批量生成。
ORM框架你選擇的是MyBatis,的原因項目中大部分的查詢都你做到了單表查詢,但查詢條件也很固定設(shè)置,所以才真接建議使用注解做的SQL語句解除綁定。
是因為項目不單可以使用了關(guān)系型數(shù)據(jù)庫,而更多的數(shù)據(jù)是加工關(guān)聯(lián)后需要保存到了MongoDB中,因此項目也用到了Spring Data MongoDB,我們的MongoDB是做了副本集的部署,可以使用Spring Data MongoDB,只不需要做最簡單配置,就這個可以成功對多臺MongoDB的訪問,如果沒有其中一臺MongoDB掛了,對服務(wù)都是沒有影響的,所以才我們做MongoDB擴容的時候是也可以在線做的(MongoDB擴內(nèi)存和CPU的時候必須欠費停機)。
和部分系統(tǒng)的交互使用到了RabbitMQ,而Spring Boot只需核心中spring-boot-starter-amqp,當然就可以很方便地成功和RabbitMQ的集成顯卡;生產(chǎn)者和消費者都十分方便。
而且是純接口的服務(wù),是為緩解數(shù)據(jù)庫的壓力,因此我們依據(jù)什么業(yè)務(wù)場景,將一些接口的結(jié)果直接緩存到Redis中(數(shù)據(jù)變化不頻繁,另外業(yè)務(wù)場景的實時性要求不是很高)。在集成顯卡Redis的時候,我們前后試了兩種
Spring Boot項目,再使用@Cacheable注解就可以能夠完成和Redis最簡單的集成主板,但聽說后來因為設(shè)置里緩存的網(wǎng)絡(luò)錯誤時間太差靈話,我們后來把它改成了第二種方案;
在用RedisTemplate,是可以完成對Redis的絕大部分你的操作。
我將減弱分享Java開發(fā)、架構(gòu)設(shè)計、程序員職業(yè)發(fā)展等方面的見解,只希望能換取你的關(guān)注。
如何優(yōu)雅的設(shè)計Java異常?
異常的類別
正如我們所明白了的,java中的無比的超類是(后文省略為Throwable),它有兩個比較不重要的子類,(后文省略為Exception)和(后文省略為Error),其中Error由JVM虛擬機接受管理,如我們所熟知的OutOfMemoryError異樣等,因此我們本文不打聽一下Error極其,那么我們多說幾句一下Exception十分。
Exception十分有個也很重要的是的子類,叫做RuntimeException。我們將RuntimeException或其他繼承自RuntimeException的子類稱做非受檢無比(unsafeException),其他繼承自Exception極其的子類被稱受檢異樣(assignException)。本文重點來了解看看受檢異常和非受檢異常這兩種異常。
如何選擇類型異常
從筆者的開發(fā)經(jīng)驗來看,如果沒有在一個應(yīng)用中,必須的新一個方法(如某個功能的service方法),這個方法要是中間可能會又出現(xiàn)無比,那么你是需要判斷這個十分直接出現(xiàn)之后是否是動態(tài)創(chuàng)建者可以如何處理,但是你有無如果能動態(tài)創(chuàng)建者通過處理,要是調(diào)用者這個可以處理,并且你也希望調(diào)用者接受處理,那你還得一拋受檢異常,警告動態(tài)創(chuàng)建者在不使用你的方法時,考慮到要是甩出異常時假如接受處理。
相象的,假如在寫某個方法時,你以為這是個偶然異常,理論上說,你總覺得運行時可能會出現(xiàn)什么問題,而這些問題也許不是什么勢必突然發(fā)生的,也不要動態(tài)鏈接庫者不顯示的通過異常來確認業(yè)務(wù)流程不能操作的,那就這時就也可以使用一個RuntimeException這樣的非受檢異樣.
完了,估記我上邊說的這段話,你讀了很多遍也仍然都覺得艱澀了。
那就,請跟了我的思路,在漸漸領(lǐng)會幫一下忙。
什么時候才不需要拋極其
簡單的方法我們必須清楚一個問題,什么時候才不需要拋異常?無比的設(shè)計是方便啊給開發(fā)者不使用的,但也不是亂用的,筆者對于什么時候拋極其這個問題也問了很多朋友,能決定詳細答案的確實不多。不過這個問題很很簡單,如果不是你總覺得某些”問題”可以解決不了了,這樣你就這個可以一拋極其了。
諸如,你在寫一個service,其中在不寫某段代碼處,你突然發(fā)現(xiàn)可能會會產(chǎn)生問題,那你就請一拋異常吧,不會相信我,你此時甩出異常將是一個最佳的位置時機。
應(yīng)該要擲下怎樣才能的異常
打聽一下完了什么時候才需要拋出異常后,我們再琢磨一個問題,確實當我們擲下異常時,我們估計選用比較怎樣才能的無比呢?到底是是受檢異樣肯定非受檢異樣呢(RuntimeException)呢?
我來請解釋看看這個問題,先從受檢異樣你說起,比如有那樣的話一個業(yè)務(wù)邏輯,需要從某文件中讀取數(shù)據(jù)某個數(shù)據(jù),這個讀取文件你操作可能會是導致文件被刪掉等其他的問題造成沒能資源從而出現(xiàn)無法讀取錯誤,這樣就要從redis或mysql數(shù)據(jù)庫中再去獲取此數(shù)據(jù),參考不勝感激代碼,getKey(Integer)為入口程序.
可以了,看了以上代碼以后,你或許心中有一些想法,那個受檢無比是可以完全控制義務(wù)邏輯,對,是啊,按照受檢十分確實可以不控制業(yè)務(wù)邏輯,不過千萬記住別那樣使用,我們應(yīng)該要合算的甩出異常,畢竟程序本身才是流程,十分的作用僅是當你進行不開去的時候能找到的一個借口罷了,它并不能充當完全控制程序流程的入口或出口,要是那樣的話建議使用的話,是在將異樣的作用逐漸擴大化,這樣很快就會導致代碼復雜程度的增加,耦合性會能提高,代碼可讀性減低等問題。
那就就當然別在用這樣的無比嗎?當然也不是,在真有這樣的需求的時候,我們可以不這樣使用,僅僅千萬記住,不要把它真的充當操縱流程的工具或手段。這樣的話到底是什么時候才要拋出這樣的無比呢?要判斷,如果沒有全局函數(shù)者調(diào)用出錯后,一定要讓動態(tài)創(chuàng)建者對這錯誤進行處理才這個可以,柯西-黎曼方程這樣的要求時,我們才能考慮到建議使用受檢十分。
接下來的事情,我們來看再看看非受檢異常呢(RuntimeException),是對RuntimeException這種極其,我們當然很多見,.例如/等,那就這種異常我們時候丟出呢?
當我們在寫某個方法的時候,很有可能會一面之緣遇見某個錯誤,我們其實這個問題時正常運行時可能為不可能發(fā)生的,但是理論上講,沒有這個問題的話,程序很快就會正常執(zhí)行的時候,它不強制沒有要求動態(tài)鏈接庫者一定得捕獲這個無比,此時一拋RuntimeException異樣。
舉個例子,當傳來一個路徑的時候,不需要直接返回一個路徑對應(yīng)的File對象:
本案所涉例子說,如果不是調(diào)用者動態(tài)鏈接庫getFiles(String)的時候如果沒有path是空,那么就一拋空指針無比(它是RuntimeException的子類),動態(tài)鏈接庫者不用什么會顯示的進行try…catch…操作通過滿處理.這就那些要求全局函數(shù)者在全局函數(shù)這樣的方法時先參與不驗證,避免再一次發(fā)生RuntimeException.萬分感謝:
應(yīng)該選用天然哪種異樣
通過以上的描述和例子,這個可以學習總結(jié)出一個結(jié)論,RuntimeException異常和受檢異樣之間的區(qū)別那是:是否滿那些要求全局函數(shù)者前提是全面處理此十分,假如滿要求內(nèi)部函數(shù)者可以進行處理,那就就建議使用受檢異樣,不然就你選擇非受檢異樣(RuntimeException)。一般來講,要是沒有普通的要求,我們個人建議不使用RuntimeException十分。
場景可以介紹和技術(shù)選型架構(gòu)描述
正如我們所知,傳統(tǒng)的項目也是以MVC框架為基礎(chǔ)進行旗下的,本文主要注意從在用restful風格接口的設(shè)計來可以體驗下異常處理的優(yōu)雅。
我們把關(guān)注點放到restful的api層(和web中的controller層帶有)和service層,研究幫一下忙在service中如何一拋異樣,然后api層該如何并且去捕獲但是被轉(zhuǎn)化異常。
在用的技術(shù)是:spring-boot,jpa(hibernate),mysql,如果對這些技術(shù)不是太認識,讀者是需要讓其閱讀什么相關(guān)材料。
業(yè)務(wù)場景描述
你選擇一個比較好簡單的業(yè)務(wù)場景,以電商中的收貨地址管理為例,用戶在移動端接受購買商品時,不需要進行收貨地址管理,在項目中,提供一些給移動端進行訪問的api接口,如:去添加收貨地址,刪出收貨地址,更改后收貨地址,默認收貨地址設(shè)置,收貨地址列表可以查詢,單個收貨地址查詢等接口。
最終形成約束條件
可以了,這個是設(shè)置好的一個很基本是的業(yè)務(wù)場景,其實,無論什么樣的api操作,其中都乾坤二卦一些規(guī)則:
去添加收貨地址:入?yún)?
用戶id
收貨地址實體信息
強制力:
用戶id不能不能為空,且此用戶確實是是必然的
收貨地址的沒必要字段不能為空
假如用戶還沒有收貨地址,當此收貨地址創(chuàng)建角色時系統(tǒng)設(shè)置成默認收貨地址—
刪除掉收貨地址:入?yún)?
用戶id
收貨地址id
管理和約束:
用戶id不能為空,且此用戶倒是是存在地的
收貨地址又不能為空,且此收貨地址確實是存在地的
判斷此收貨地址是否是是用戶的收貨地址
判斷此收貨地址是否是為默認收貨地址,假如是默認收貨地址,那你肯定不能并且刪掉
你要改收貨地址:入?yún)?
用戶id
收貨地址id
約束力:
用戶id沒法為空,且此用戶倒是是修真者的存在的
收貨地址又不能為空,且此收貨地址確實是是修真者的存在的
確定此收貨地址如何確定是用戶的收貨地址
默認地址設(shè)置:入?yún)?
用戶id
收貨地址id
約束:
用戶id肯定不能為空,且此用戶倒是是存在地的
收貨地址不能不能為空,且此收貨地址確實是存在的
判斷此收貨地址是否是用戶的收貨地址
收貨地址列表網(wǎng)上查詢:入?yún)?
用戶id
加以約束:
用戶id不能為空,且此用戶雖然是必然的
單個貨到地址查詢:入?yún)?
用戶id
收貨地址id
加以約束:
用戶id沒法為空,且此用戶確實是是修真者的存在的
收貨地址沒法為空,且此收貨地址確實是是存在的
確定此收貨地址是否是用戶的收貨地址
管理和約束判斷和技術(shù)選型
對于根據(jù)上述規(guī)定列出的約束條件和功能列表,我選擇幾個比較比較有名的異常處理場景并且分析:直接添加收貨地址,徹底刪除收貨地址,查看收貨地址列表。
這樣的話應(yīng)該是有哪些必要的知識儲備呢,讓我們?nèi)タ纯词肇浀刂愤@個功能:
去添加收貨地址中必須對用戶id和收貨地址實體信息就行校驗,這樣的話是對非空的判斷,我們怎么參與工具的選擇呢?比較傳統(tǒng)的判斷追加:
上邊的例子,如果不是只可以確定uid為空好在,要是再去確定address這個實體中的某些必要的話屬性是否為空,在字段很多的情況下,這說白是災(zāi)難性的。
那我們應(yīng)該怎莫通過這些入?yún)⒌呐袛嗄?,給大家推薦兩個知識點:
Guava中的Preconditions類實現(xiàn)程序了很多入?yún)⒎椒ǖ呐袛?/p>
jsr303的validation規(guī)范(目前基于都很全的是hibernate利用的hibernate-validator)
如果沒有不使用了這兩種幫我推薦技術(shù),那就入?yún)⒌呐袛鄷兊卯惓:唵吸c大部分。推薦大家多建議使用這些成熟的技術(shù)和jar工具包,他是可以降低很多不必要的工作量。我們只是需要把重心扔到業(yè)務(wù)邏輯上。而肯定不會是因為這些入?yún)⒌呐袛嗟⒄`了更多的時間。
如何能優(yōu)雅的怎么設(shè)計java無比domain詳細介紹
依據(jù)什么項目場景來看,需要兩個domain模型,一個是用戶實體,一個是地址實體.
Addressdomain::
Userdomain萬分感謝:
就ok啦,上邊是一個模型關(guān)系,用戶-收貨地址的關(guān)系是1-n的關(guān)系。上邊的@Data是可以使用了一個叫做lombok的工具,它自動導入了Setter和Getter等方法,用起來很方便,感興趣的東西讀者可以自行打聽一下幫一下忙。
dao可以介紹
數(shù)據(jù)連接上層,我們不使用了spring-data-jpa這個框架,它特別要求我們只必須繼承框架能提供的接口,因此通過約定對方法接受取名,就可以不能夠完成我們想要的數(shù)據(jù)庫操作。
用戶數(shù)據(jù)庫操作不勝感激:
收貨地址操作::
事實上讀者所注意到的,我們的DAO只是需要無法繼承JpaRepository,它就早就幫我們完成了基本的CURD等你操作,如果沒有想所了解更多關(guān)於spring-data的這個項目,請參考一下spring的官方文檔,它比不方案我們對異常的研究。
Service異常設(shè)計
行啦,再一次到了我們的重點了,我們要結(jié)束service一些的部分操作:先添加收貨地址,刪出收貨地址,聲望兌換收貨地址列表.
首先看我的service接口定義:
我們來關(guān)注幫一下忙實現(xiàn):
再添加收貨地址
是需要我來看一下以前整理好的約束條件:
入?yún)?
用戶id
收貨地址實體信息
管理和約束:
用戶id沒法為空,且此用戶確實是是存在的
收貨地址的必要的話字段不能不能為空
要是用戶還沒有收貨地址,當此收貨地址修改時設(shè)置里成默認收貨地址
先看100元以內(nèi)代碼基于:
其中,早就能夠完成了根據(jù)上述規(guī)定所具體描述的三點約束條件,當三點約束條件都行最簡形矩陣時,才也可以進行正常了的業(yè)務(wù)邏輯,否則將甩出異樣(一般在此處我建議你一拋運行時極其-RuntimeException)。
能介紹100元以內(nèi)以上我所都用到的技術(shù):
1、(T t)這個是建議使用Guava中的參與確認的,而且service中要用的驗正較多,所以個人建議將Preconfitions該成靜態(tài)動態(tài)導入的
不過Guava的github中的那說明也建議我們這樣的話建議使用。
2、(validator,address)這個不使用了hibernate實現(xiàn)程序的jsr303規(guī)范來做的,需要傳出一個validator和一個需要驗正的實體,這樣validator是要如何聲望兌換的呢,::
他將某些一個Validator對象,然后把我們在service中通過涌入便可以建議使用了:
那就BeanValidators這個類是該如何實現(xiàn)程序的?當然實現(xiàn)方法很簡單啊,只要你去推測jsr303的標示注解就行啦了。
那你jsr303的注解寫在哪里了呢?當然是寫在address實體類中了: