欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何利用Java使用AOP實(shí)現(xiàn)數(shù)據(jù)字典轉(zhuǎn)換

 更新時(shí)間:2022年06月29日 10:51:56   作者:??生命猿于運(yùn)動(dòng)????  
這篇文章主要介紹了如何利用Java使用AOP實(shí)現(xiàn)數(shù)據(jù)字典轉(zhuǎn)換,AOP也是我們常說(shuō)的面向切面編程,AOP在我們開發(fā)過(guò)程中應(yīng)用也比較多,在這里我們就基于AOP來(lái)實(shí)現(xiàn)一個(gè)數(shù)據(jù)字典轉(zhuǎn)換的案例

簡(jiǎn)介

AOP也是我們常說(shuō)的面向切面編程,AOP在我們開發(fā)過(guò)程中應(yīng)用也比較多,在這里我們就基于AOP來(lái)實(shí)現(xiàn)一個(gè)數(shù)據(jù)字典轉(zhuǎn)換的案例。

案例介紹

相信各位在寫代碼的時(shí)候肯定有過(guò)這樣的經(jīng)歷,我們?cè)O(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)對(duì)于字典類的數(shù)據(jù)一般都會(huì)采用字典碼進(jìn)行存儲(chǔ),而不是直接使用字典值。首先是因?yàn)檫@是一種開發(fā)規(guī)范,其次使用編碼也會(huì)利于數(shù)據(jù)存儲(chǔ),數(shù)據(jù)整體也會(huì)比較干凈整潔。

數(shù)據(jù)字典編碼的定義一般也會(huì)做一些分類,比如說(shuō)U01開頭代表用戶類型,U02開頭代表用戶性別等等,這樣也有助于我們進(jìn)行數(shù)據(jù)分析。

下面我們就簡(jiǎn)單以一個(gè)用戶表來(lái)做數(shù)據(jù)字典轉(zhuǎn)換。

案例實(shí)現(xiàn)

創(chuàng)建表:

CREATE TABLE `t_user` (
  `id` BIGINT(12) NOT NULL AUTO_INCREMENT,
  `user_code` VARCHAR(20) NOT NULL,
  `user_name` VARCHAR(50) NOT NULL,
  `user_type` CHAR(5) NOT NULL COMMENT '用戶類型 -> U0101:普通用戶,U0102:VIP用戶',
  `gender` CHAR(5) NOT NULL COMMENT '用戶性別 -> U0299:未知,U0201:男,U0202:女',
  PRIMARY KEY (`id`) 
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

代碼結(jié)構(gòu):

相關(guān)代碼可由逆向工程去生成,我們就簡(jiǎn)單的編寫了從控制層請(qǐng)求到服務(wù)層的業(yè)務(wù)處理再到dao層的數(shù)據(jù)處理,在這里我就一一將代碼展示出來(lái)了各位還需要自己多動(dòng)手。下面就直接上代碼結(jié)構(gòu)圖

測(cè)試接口:

接下來(lái)我們?cè)赨serController類中寫一個(gè)測(cè)試接口,根據(jù)userCode查詢用戶信息如下:

@GetMapping("/{userCode}")
public UserVo queryUser(@PathVariable("userCode") String userCode) {
    UserDto userDto = userService.queryUserByCode(userCode);
    return userMapStruct.userDtoToUserVo(userDto);
}

初始化測(cè)試數(shù)據(jù):

切面定義

定義注解類:用于標(biāo)記哪個(gè)地方需要進(jìn)行數(shù)據(jù)字典轉(zhuǎn)換切面。

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictParam {
    /**
     * 映射目標(biāo)屬性,為空默認(rèn)直接映射到field,替換掉原來(lái)的field
     * @return
     */
    String targetField() default "";

    /**
     * 映射來(lái)源屬性
     * @return
     */
    String field();

    /**
     * 數(shù)據(jù)字典類型
     * @return
     */
    String dictType();
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictHelper {
    /**
    * 字典轉(zhuǎn)換參數(shù)配置
    */
    DictParam[] value();
}

定義注解切面類:主要實(shí)現(xiàn)字典轉(zhuǎn)換的核心內(nèi)容。

@Slf4j
@Aspect
public class DictHelperAspect {
    public DictHelperAspect() {
    }
    @Around("@annotation(dictHelper)")
    public Object doAround(ProceedingJoinPoint joinPoint, DictHelper dictHelper) {
        try {
            // 執(zhí)行方法得到結(jié)果
            Object result = joinPoint.proceed();

            DictParam[] values = dictHelper.values();
            if (values == null || values.length == 0) {
                return result;
            }

            // 字典轉(zhuǎn)換開始(使用反射)
            for (DictParam value : values) {
                Class<?> clazz = result.getClass();
                // 反射調(diào)用get方法獲取字段值
                Method sourceMethod = clazz.getMethod("get" + firstToUppercase(value.field()));
                Object fieldValue = sourceMethod.invoke(result);
                // 獲取字典值
                String dictValue = DictConfig.DICT_MAPPER.get(value.dictType()).get(fieldValue.toString());
                // 獲取目標(biāo)方法進(jìn)行設(shè)值
                String targetField = StringUtils.isBlank(value.targetField()) ? value.field() : value.targetField();
                Method targetMethod = clazz.getMethod("set" + firstToUppercase(targetField), dictValue.getClass());
                targetMethod.invoke(result, dictValue);
            }
            return result;
        }
        catch (Throwable throwable) {
            log.error("error:", throwable);
            return null;
        }
    }

    private String firstToUppercase(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
}

Service層添加字典轉(zhuǎn)換的切面掃描注解:

@DictHelper(values = {
        @DictParam(field = "userType", targetField = "userTypeShow", dictType = "USER_TYPE"),
        @DictParam(field = "gender", targetField = "genderShow", dictType = "GENDER")
})
public UserDto queryUserByCode(String userCode) {
    UserEntity userEntity = userMapper.selectUser(userCode);
    return userMapStruct.userEntityToUserDto(userEntity);
}

如上代碼主要分三個(gè)步驟:

  • 根據(jù)@DictParam注解配置的數(shù)據(jù)來(lái)源字段通過(guò)返回調(diào)用數(shù)據(jù)返回對(duì)象獲取數(shù)據(jù)來(lái)源字典編碼。
  • 根據(jù)字典編碼通過(guò)字典編碼表(這里直接使用靜態(tài)DictConfig直接調(diào)用)找到對(duì)應(yīng)字典值。
  • 根據(jù)@DictParam注解配置的目標(biāo)數(shù)據(jù)字典,將匹配到的數(shù)據(jù)字典值通過(guò)反射將數(shù)據(jù)回填到對(duì)象中。

注意:各位開發(fā)者朋友們,看到這里是不是以為很簡(jiǎn)單呢,但是在實(shí)際開發(fā)過(guò)程中我們更注重的是程序的安全、穩(wěn)定、可靠,所以這也不難看出上面的代碼當(dāng)中省去了許多校驗(yàn)

靜態(tài)字典:實(shí)際開發(fā)過(guò)程中,不建議這么配置,因?yàn)檫@樣是完全不靈活的,這里只是為了方便演示而已。實(shí)際業(yè)務(wù)當(dāng)中可以自定義一種數(shù)據(jù)字典加載策略(服務(wù)啟動(dòng)成功后加載或者定期刷新加載),將字典加載到內(nèi)存,或者使用數(shù)據(jù)庫(kù)結(jié)合redis做內(nèi)存也可以,數(shù)據(jù)字典還是要避免頻繁直接的去查數(shù)據(jù)庫(kù)。

public class DictConfig {
    public static final Map<String, Map<String, String>> DICT_MAPPER = new HashMap<>();
    static {
        Map<String, String> USER_TYPE = new HashMap<>();
        USER_TYPE.put("U0101", "普通用戶");
        USER_TYPE.put("U0102", "VIP用戶");
        DICT_MAPPER.put("USER_TYPE", USER_TYPE);

        Map<String, String> GENDER = new HashMap<>();
        GENDER.put("U0201", "男");
        GENDER.put("U0202", "女");
        GENDER.put("U0299", "未知");
        DICT_MAPPER.put("GENDER", GENDER);
    }
}

運(yùn)行結(jié)果:

總結(jié)

利用切面編程還可以做很多事,本文所展示的數(shù)據(jù)字典轉(zhuǎn)換也僅僅只是冰山一角,像用的比較多的分頁(yè)處理我們也一樣可以用這種方式去做。

數(shù)據(jù)字典在我們開發(fā)設(shè)計(jì)當(dāng)中是必不可少的,合理的使用好數(shù)據(jù)字典還是很有必要的。

到此這篇關(guān)于如何利用Java使用AOP實(shí)現(xiàn)數(shù)據(jù)字典轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Java AOP字典轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot指定profiles啟動(dòng)失敗問(wèn)題及解決

    springboot指定profiles啟動(dòng)失敗問(wèn)題及解決

    這篇文章主要介紹了springboot指定profiles啟動(dòng)失敗問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Spring整合Mybatis 掃描注解創(chuàng)建Bean報(bào)錯(cuò)的解決方案

    Spring整合Mybatis 掃描注解創(chuàng)建Bean報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了Spring 整合Mybatis 掃描注解創(chuàng)建Bean報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • spring boot 2整合swagger-ui過(guò)程解析

    spring boot 2整合swagger-ui過(guò)程解析

    這篇文章主要介紹了spring boot 2整合swagger-ui過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring Security攔截器引起Java CORS跨域失敗的問(wèn)題及解決

    Spring Security攔截器引起Java CORS跨域失敗的問(wèn)題及解決

    這篇文章主要介紹了Spring Security攔截器引起Java CORS跨域失敗的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù)

    springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù)

    這篇文章主要介紹了springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 基于Java Springboot + Vue + MyBatis實(shí)現(xiàn)音樂(lè)播放系統(tǒng)

    基于Java Springboot + Vue + MyBatis實(shí)現(xiàn)音樂(lè)播放系統(tǒng)

    這篇文章主要介紹了一個(gè)完整的音樂(lè)播放系統(tǒng)是基于Java Springboot + Vue + MyBatis編寫的,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Java實(shí)現(xiàn)駝峰、下劃線互轉(zhuǎn)的方法

    Java實(shí)現(xiàn)駝峰、下劃線互轉(zhuǎn)的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)駝峰、下劃線互轉(zhuǎn)的示例代碼,主要有使用 Guava 實(shí)現(xiàn)和自定義代碼轉(zhuǎn),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java異常Exception詳細(xì)講解

    Java異常Exception詳細(xì)講解

    異常就是不正常,比如當(dāng)我們身體出現(xiàn)了異常我們會(huì)根據(jù)身體情況選擇喝開水、吃藥、看病、等?異常處理方法。?java異常處理機(jī)制是我們java語(yǔ)言使用異常處理機(jī)制為程序提供了錯(cuò)誤處理的能力,程序出現(xiàn)的錯(cuò)誤,程序可以安全的退出,以保證程序正常的運(yùn)行等
    2022-07-07
  • java自定義日志輸出文件(log4j日志文件輸出多個(gè)自定義日志文件)

    java自定義日志輸出文件(log4j日志文件輸出多個(gè)自定義日志文件)

    打印日志的在程序中是必不可少的,如果需要將不同的日志打印到不同的地方,則需要定義不同的Appender,然后定義每一個(gè)Appender的日志級(jí)別、打印形式和日志的輸出路徑,下面看一個(gè)示例吧
    2014-01-01
  • 使用Maven搭建SpringMVC項(xiàng)目的步驟(圖文教程)

    使用Maven搭建SpringMVC項(xiàng)目的步驟(圖文教程)

    本篇文章主要介紹了使用Maven搭建SpringMVC項(xiàng)目的步驟(圖文教程),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-09-09

最新評(píng)論