首先,把昨天那倆條sql語句的優化緣由給你們補充一下,第一條效率極低,第二條優化後的,sql語句截圖以下:程序員
通過幾個高手的評論和我的的分析:web
第一條sql語句查詢很慢是由於它首先使用了in關鍵字查詢,致使全表掃描,其次我那條sql語句的寫法上,是經過子查詢根據某一個字段去不斷匹配後面查詢到的集合數據,最後獲得查詢結果,這一系列操做下來效率上去纔怪呢。sql
可是第二條sql語句是經過鏈接查詢,根據創建了索引的字段來等值匹配,最後獲得查詢結果,速度槓槓的。(一次小小的優化經歷,學到了)。數據庫
今天(2017-05-24)在微信公衆號上終於等到阿里巴巴集團開源的Java開發手冊更新了,從地鐵上一路看到公司,真的學到了,人家的開發規約真的是好,講的很細,很注重細節,這就是差距啊,下面給你們簡單總結一下吧(手冊原件若是須要,請留言)。編程
它的名字是《阿里巴巴Java開發手冊v1.2.0》,距2017-02-09發佈的初版已經有6個歷史了,它的整體結構分爲五大部分:編程規約、異常日誌、MySQL數據庫、工程結構和安全規約。今天我主要給你們分享總結了工程結構,由於我五一前剛給公司開發了一套內網數據錄入系統,雖然沒用到什麼大的框架和潮流的技術,可是麻雀雖小五臟俱全啊。包括表結構、工程搭建和業務梳理都是本身一我的在開發,當時在開發的時候也是感受很孤獨,由於項目組的其餘人都有戰友配合做戰,而我就一我的,還有頁面的調試和美化都是我一我的在搞,在此聲明一下,我不是在抱怨,反而很珍惜這種開發機會,真的會沉澱不少東西,謝謝公司。緩存
切入正題吧,今天給你們分享的是工程結構這塊的一些我的總結。安全
一、項目應用分層:服務器
這裏主要給咱們講述了一下,一個項目理想化的項目架構圖,和咱們平時開發的項目結構稍稍不一樣,畢竟人家的架構思惟那是至關的高啊,這仍是最基礎的架構圖呢。微信
上圖默認上層依賴於下層,箭頭關係表示直接依賴。架構
開放接口層:可直接封裝service層接口中的方法暴露成RPC接口/服務,經過web封裝成http接口,最後進行網管控制、流量控制等。
終端顯示層:各個端的模板渲染並執行顯示的層。當前咱們主要接觸的是js渲染、jsp渲染和移動端渲染等。
web層:主要是對訪問控制進行轉發,各種基本參數校驗,或者不復用的業務簡單處理等。
service層:相對具體的業務邏輯服務層。
manager層:通用業務處理層,它有以下特徵:一、對第三方平臺封裝的層,預處理返回結果及轉化異常信息;二、對service層通用能力的下沉,好比緩存方案、中間件通用處理、三、與dao層交互,對多個dao的組合複用。
dao層:數據訪問層,與底層MySQL、Oracle、hbase數據庫進行數據交互。
外部接口或第三方平臺:包括其餘部門的rpc接口,基礎平臺,其餘公司的http接口。
以上都是阿里項目的工程架構,有一點不一樣的是咱們平時通用的是controller層、service服務層和dao數據訪問層,可是他們這裏提出了manager層,將一些業務通用的處理方式和須要多個dao組合複用的結果抽取到該層,我的感受在項目維護上很方便,之前咱們都是按模塊劃分,將各個模塊的業務邏輯都往service層堆上去,這樣其實也沒什麼很差,可是咱們感受試着將業務層通用的業務抽取一下,剛纔還琢磨着把我前倆天寫的項目重構一下,最後仍是等到端午吧,也好好模仿一把阿里,哈哈哈。
二、項目異常分層處理規約:
由於dao數據訪問層產生的異常不少,類型也不少,沒法用細粒度的異常進行處理,因此直接將異常丟給service層,爲啥要將數據訪問層的異常丟到manager/service層,由於一般在manager/service層中會有日誌打印,不論是發生異常仍是異常拋出,都會時刻記錄運行狀況到日誌文件中去,要是剛纔在dao層也將異常打印,又由於dao和service是同臺服務器,這樣就至關於打印了2第二天志,浪費性能和儲存。
service產生的異常必須記錄到磁盤日誌文件中去,儘量帶上參數信息,至關於保護案發現場。
web層大哥們,不能在爽啦,必須處理了,若是產生的異常會致使頁面的正常渲染,則採用攔截器或異常處理的方式,跳轉到異常錯誤友好頁面,加上友好的錯誤提示信息,最後還要在開發接口層將產生的異常處理成錯誤碼和錯誤信息返回。
三、分層領域模型規約:
咱們之前的項目中我見過有3類模型類,第一類是web層與視圖層傳遞參數的query類,第二類是與數據表對應的pojo類,第三類是爲了響應數據定義的擴展vo類。
下面咱們來看看阿里是如何將模型進行規約的,我感受很是囉嗦可是很是好,其實不少電商公司也估計是這麼作的,我以前接觸的一個電商項目大概就是這種設計,好長時間了記不清了:
DO(data object):與數據庫中的數據表一一對應,一般是應用於數據訪問層dao中用於向上傳輸數據源對象。
DTO(data transfer object):數據傳輸對象,該模型類主要是應用於service層和manager層,將service層和manager層業務處理後進行向外傳輸對象。
BO(business object):業務對象,主要是service層輸出的封裝的業務邏輯的對象。
Query:數據查詢對象,各層接受上層傳遞過來的多個參數並將這些參數封裝到query對象中。
VO(view object):視圖層對象,主要是web層向視圖層傳輸的數據對象。
四、二方庫依賴:
定義GAV聽從一下規則:
(1)、GroupID格式:com.{公司/BU}.業務線.[子業務線],最多四級。
(2)、ArtifactID格式:產品線名-模塊名。注意:語意不重複不遺漏,最好到中央倉庫中去查證一下。
(3)、Version格式:版本號根據本身公司的規定。
最後給你們送上幾條建議,也是在手冊中看到的,只不過寫到這兒印象比較深入,還沒忘就給你們寫在這兒吧:
一:數據訂正時,在調用修改和刪除方法以前,最好先查詢要修改或刪除的記錄是否存在,確認無誤後再進行更新。
二:在查詢數據時能避免使用IN關鍵字就避免,是在避免不了,則須要仔細評估IN後邊的數據集合中總數是否超過1000,最好控制在1000之內,我上次的優化經歷起源於它,就是匹配的集合數據遠遠超過1000條,最後致使查詢效率極低。
三:sql.xml文件中配置參數儘可能使用#{},儘可能不要使用${},容易形成sql注入問題。
四:接口過期必須加@Deprecated註釋,而且添加註釋清晰地說明替代舊接口的新接口或服務。
五:通常不要在pojo類中定義屬性的變量時,建議不要加is前綴,可是在數據表中定義屬性對應的字段是儘可能加上is_前綴,緣由是:若是在給屬性的變量名加上is前綴很可能會發生,部分框架解析時會引發序列化錯誤。
六:在定義項目中的包結構時,統一使用小寫並單數形式。
七:service層和mapper接口中定義的方法,建議不要寫修飾符,目的就是代碼結構看着簡單,阿里給出的解釋,因此我就把我之前的都刪掉了,好習慣就應該從如今開始。
八:若是項目中要實現分頁邏輯,若是在判斷總記錄數爲0時,則直接返回,避免執行後面的分頁語句,給你們送張截圖,是我前幾天本身寫的分頁邏輯:
1 @Override 2 public List<Task> findOrdersByUserId(Task task,Page page) { 3 int count = vinTaskMapper.countOrdersByUserId(task); 4 page.setMaxRow(count); 5 if(count == 0){ 6 return new ArrayList<Task>(); 7 } 8 return vinTaskMapper.findOrdersByUserId(task,page); 9 }
九:禁止使用存儲過程,由於難以調試和擴展,更沒有移植性。
好了,就總結到這兒吧,這裏雖然沒什麼乾貨和技術要點,可是個人目的是給你們分享一點編程習慣,具有好的代碼風格是做爲一個優秀程序員的基本素能,最後但願你們寫出來的代碼可以越看越美,越看越想看,哈哈哈。