最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

簡介

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

案例介紹

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

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

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

案例實現(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)代碼可由逆向工程去生成,我們就簡單的編寫了從控制層請求到服務(wù)層的業(yè)務(wù)處理再到dao層的數(shù)據(jù)處理,在這里我就一一將代碼展示出來了各位還需要自己多動手。下面就直接上代碼結(jié)構(gòu)圖

測試接口:

接下來我們在UserController類中寫一個測試接口,根據(jù)userCode查詢用戶信息如下:

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

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

切面定義

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

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

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

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

定義注解切面類:主要實現(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());
                // 獲取目標方法進行設(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);
}

如上代碼主要分三個步驟:

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

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

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

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);
    }
}

運行結(jié)果:

總結(jié)

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

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

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

相關(guān)文章

最新評論

沂源县| 岱山县| 梅州市| 安义县| 白城市| 平舆县| 五常市| 东平县| 安义县| 吉水县| 区。| 蛟河市| 吴堡县| 洪泽县| 石城县| 汕尾市| 克拉玛依市| 西乡县| 满洲里市| 崇阳县| 平利县| 桑日县| 苗栗市| 黔西县| 兴仁县| 寿光市| 遂川县| 安新县| 堆龙德庆县| 南岸区| 新密市| 泰兴市| 怀仁县| 枣阳市| 呼玛县| 九龙坡区| 镇远县| 宁都县| 岗巴县| 莒南县| 永德县|