? ? ? ?在一次開發(fā)過程中,我發(fā)現(xiàn)后端程的工作其實很快就能完成,而前端的進度幾乎就決定了開發(fā)的進度。所以,我就覺得后端的開發(fā)人員在返回數(shù)據(jù)的時候盡量讓前端拿到數(shù)據(jù)可以直接使用,而不要讓前端再轉一次。而字典數(shù)據(jù)就是典型的例子,比如合同的狀態(tài)在簽訂中、執(zhí)行中、執(zhí)行完成、已廢止,員工的職位是普通員工、部門經(jīng)理、總經(jīng)理等等,這些數(shù)據(jù)在數(shù)據(jù)庫中儲存的是數(shù)字,但是在頁面顯示的時候需要轉成漢字。
? ? ? ? 后端人員想要將這些數(shù)據(jù)轉成數(shù)字其實也很簡單,比如重寫實體類的setter方法,在set相應的屬性的時候就直接進行判斷然后轉成我們想要的數(shù)據(jù)就行了,但如果系統(tǒng)大一點的話就不太好管理了,比如員工的職位想要增加一個,但是有多個視圖用到了員工職位,那么改的setter方法的時候就需要改多個類。而且如果遇到既需要原本的數(shù)據(jù),又需要轉換后的數(shù)據(jù)的情況就很難處理,種種不便我就不再贅述了,這里介紹一個通過自定義注解、反射和Spring AOP實現(xiàn)字典查詢的方法來解決這一問題。
? ? ? ? 首先看看效果:

student實體類中在teacherId、sex和type屬性上加了一個@Dict注解。

在getStudent和StudentById上加了@QueryDict注解。

可以看到,我們并沒用重寫任何一個setter方法,但是在最終的請求結果中我們卻可以看到多了sex_dictText,type_dictText,teacherId_dicText這三個數(shù)據(jù),而且這三個數(shù)據(jù)看起來就像是原本實體類里面的屬性一樣。下面就來講講如何實現(xiàn)這樣的效果。
首先看一下自定義注解:

dicText和dictTable有默認值,使用的時候可以不傳,但傳與不傳會讓dicCode這個屬性的作用不同,這個后面再說。

這個注解沒有屬性,它只是作為一個進行字典查詢的標識。
接下來就是使用Spring AOP和反射來進行實現(xiàn)了:

定義切點這里就用到了第二個注解@QueryDict,當使用了@QueryDict這個注解之后,就會進入這個切面??梢钥吹竭@里是將目標方法的返回值進行了更改。
下面就來看看是如何更改的:

要進行字典查詢的情況只有兩種,一種就是進行分頁查詢的時候,一種就是查詢具體哪條數(shù)據(jù)的時候。用過instanceof來判斷是否是IPage類型就可以判斷出是否是分頁查詢了(因為這里是通過mybatis-plus實現(xiàn)查詢的),如果是分頁查詢,那么就有進行迭代,然后再調(diào)用eachField來進行下一步判斷和更改操作。
不過這里需要先插入一段我的Result類:

只需要看它的屬性就夠了。然后就是eachField方法

這個方法其實就是重新定義了一個json,然后將原先的result返回數(shù)據(jù)直接添加進去,然后再獲取返回數(shù)據(jù)的每個屬性,如果這個屬性添加了@Dict注解,就使用translateDicValue來進行字典翻譯(可以通過查詢數(shù)據(jù)庫來實現(xiàn),也可以進行通過查詢枚舉來實現(xiàn)。),然后將翻譯后的數(shù)據(jù)添加進前面定義的json就可以了。上面代碼中,oConverUtils.getAllFileds是獲取返回數(shù)據(jù)的所有屬性,里面的具體實現(xiàn)是通過getDeclaredFields方法實現(xiàn)的。field.getName()+CommonConstant.DICT_TEXT_SUFFIX是為了給翻譯后的數(shù)據(jù)定義一個鍵名,就是前面測試結果看到的xxx_dictText。

這里調(diào)用了dictService.QueryDict方法:

可以看到,dictTable和dictText為空字符串和不為空字符串的時候調(diào)用的sql是不一樣的,不為空字符串的時候就代表著要去其他基本表查。
比如teacherId這個屬性添加了@Dict(dictTable ="teacher",dicText ="teacher.teacher_name",dicCode ="id")就表示要去teacher表查teacher_name這個字段,查詢條件是teacherId屬性的值等于teacher表中的id。
如果dictText為空字符串的話就要去專門的字典表中查。
最后來看一下sql語句

這樣通過自定義注解、反射和Spring AOP實現(xiàn)字典查詢的方法就差不多交代清楚了。