aop+springboot实现数据字典表

文章目录

    • 概要
    • 整体架构流程
    • 目录结构方式
      • pom文件信息
      • application.yml文件信息
      • aop实现方式(重点方式)
        • 我们这里主要的实现了,就是在前段请求数据的时候,我们利用aop,拦截数据,将code编码进行翻译,翻译的方式就是我们将code值,获取重新在数据库中查询到的值,存储到code,重新返回给前段展示
      • 注解
        • 我们注释在需要翻译的实体类上 `这个字段必须是经过在aop_item表中的字段`我们通过code和datasource数据方式来确定这个val值
      • 工具类
      • 实体类文件信息
      • controller信息
      • 测试
    • 小结

概要

spingboot+aop实现数据字典方式

例如:

我们在想数据库中存储文字的时候,效率不高,这个时候我们会考虑存储,code编码格式数据,然后利用aop返回给前端的时候翻译code编码将值给code编码

整体架构流程

我们会新建三张表

1.第一张表是aop_student学生表存储学生等级,兴趣,爱好,我们这里分别存储是code编码并不是存储真实的数据方式,我们会将真实的数据存储到aop_item
2.第二张表是aop_item这张表存储我们真实的数据信息,我们通过code和属性名称查询对应的值

aop+springboot实现数据字典表_第1张图片

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for aop_dict
-- ----------------------------
DROP TABLE IF EXISTS `aop_dict`;
CREATE TABLE `aop_dict`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `aop_datasource` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '科目',
  `aop_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of aop_dict
-- ----------------------------
INSERT INTO `aop_dict` VALUES (1, 'aop_level', '数学');
INSERT INTO `aop_dict` VALUES (2, 'aop_english', '语文');
INSERT INTO `aop_dict` VALUES (3, 'aop_hobby', '兴趣');

SET FOREIGN_KEY_CHECKS = 1;


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for aop_item
-- ----------------------------
DROP TABLE IF EXISTS `aop_item`;
CREATE TABLE `aop_item`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `aop_datasource` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `aop_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `aop_val` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of aop_item
-- ----------------------------
INSERT INTO `aop_item` VALUES (1, 'aop_english', '1', '优秀');
INSERT INTO `aop_item` VALUES (2, 'aop_level', '1', '优秀');
INSERT INTO `aop_item` VALUES (3, 'aop_level', '2', '良好');
INSERT INTO `aop_item` VALUES (4, 'aop_english', '2', '良好');
INSERT INTO `aop_item` VALUES (5, 'aop_hobby', '1', 'A');
INSERT INTO `aop_item` VALUES (6, 'aop_hobby', '2', 'B');
INSERT INTO `aop_item` VALUES (7, 'aop_hobby', '3', 'C');
INSERT INTO `aop_item` VALUES (8, 'aop_hobby', '4', 'D');
INSERT INTO `aop_item` VALUES (9, 'aop_hobby', '5', 'E');
INSERT INTO `aop_item` VALUES (10, 'aop_hobby', '6', 'G');

SET FOREIGN_KEY_CHECKS = 1;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for aop_student
-- ----------------------------
DROP TABLE IF EXISTS `aop_student`;
CREATE TABLE `aop_student`  (
  `id` int(11) NOT NULL,
  `aop_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `aop_enlish` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '英语',
  `aop_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '等级',
  `aop_hobby` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '爱好',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of aop_student
-- ----------------------------
INSERT INTO `aop_student` VALUES (1, '天天', '1', '1', '1,2,3');
INSERT INTO `aop_student` VALUES (2, '拜拜', '2', '2', '4,5');

SET FOREIGN_KEY_CHECKS = 1;

例如:
在语言模型中,编码器和解码器都是由一个个的 Transformer 组件拼接在一起形成的。

目录结构方式

aop+springboot实现数据字典表_第2张图片

pom文件信息

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.7.7</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.22</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
    </dependencies>

application.yml文件信息

server:
  port: 10001
spring:
  datasource:
    url: jdbc:mysql://192.168.47.128:3306/mycnblog?characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  #redis连接信息
  redis:
    port: 6379
    host: 192.168.47.128
mybatis:
  mapper-locations: classpath:/mapper/*Dao.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

aop实现方式(重点方式)

我们这里主要的实现了,就是在前段请求数据的时候,我们利用aop,拦截数据,将code编码进行翻译,翻译的方式就是我们将code值,获取重新在数据库中查询到的值,存储到code,重新返回给前段展示

package com.cn.aop;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cn.common.Result;
import com.cn.log.DictRedis;
import com.cn.service.AopItemService;
import com.cn.utils.BeanUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.junit.platform.commons.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Aspect
@Component
public class DictAspect {

    private Logger log = LoggerFactory.getLogger(DictAspect.class);


    @Autowired
    private AopItemService aopItemService;

    @Pointcut("execution(* com.cn.controller.*.*(..))")
    public void execute(){

    }

    @Around("execute()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object result = point.proceed();
        stopWatch.stop();
        log.info("获取数据时间:{}",result);
        stopWatch.start();
        translateDict(result);
        stopWatch.stop();
        log.info("翻译字典时间:{}",stopWatch.getLastTaskTimeMillis());
        return result;
    }

    /**
     * 翻译字典
     * @param result
     */
    private void translateDict(Object result) {
        if (result instanceof Result){
        	//封装返回的值
            List<JSONObject> items = new ArrayList<>();
			//将获取对象强制转化成Result对象
            Result dictResult = (Result)result;
			//获取的Result获取getData()转化成list
            List<?> list = (List<?>)dictResult.getData();
			//循环list获取里面注册标注的数据添加值
            for (Object o : list) {
            	//获取值进行json格式的转化
                ObjectMapper mapper = new ObjectMapper();

                String json = "{}";

                try {
                    json=mapper.writeValueAsString(o);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }

                JSONObject parseObject = JSON.parseObject(json);
				
				//遍历获取对象中的属性和名称
                for (Field field : BeanUtil.getAllFields(o)) {
                	//获取注解标注的值
                    if (field.getAnnotation(DictRedis.class)!=null){
                        String dictDataSource = field.getAnnotation(DictRedis.class).dictDataSource();
                        String dictText = field.getAnnotation(DictRedis.class).dictText();
                        //获取当前key值
                        String keys = String.valueOf(parseObject.get(field.getName()));
                        //获取当前字典中的值
                        String textValue = translateTextValue(dictDataSource,keys);
                        if (StringUtils.isNotBlank(dictText)){
                            parseObject.put(dictText,textValue);
                        }else {
                            parseObject.put(field.getName()+"cc",textValue);
                        }
                    }
                }
                items.add(parseObject);
            }
            dictResult.setData(items);
        }
    }

    /**
     * 获取字典中的值
     * @param dictDataSource 名称
     * @param keys 值
     * @return
     */
    private String translateTextValue(String dictDataSource, String keys) {
        if (StringUtils.isBlank(dictDataSource) || StringUtils.isBlank(keys)){
            return null;
        }
        StringBuffer buffer = new StringBuffer();
		
		//分割key将分割的key循环便利进行查询
        String[] key = keys.split(",");
        for (String k : key) {
            String tempValue =null;
            if (k.trim().length()==0){
                continue;
            }
            log.info("字典中的值:{}",k);
            tempValue = aopItemService.selectByDatasourceKey(dictDataSource,k);

            if (StringUtils.isNotBlank(tempValue)){
                if (!"".equals(buffer.toString())){
                    buffer.append(",");
                }
                buffer.append(tempValue);
            }
        }
        return buffer.toString();
    }


}


注解

我们注释在需要翻译的实体类上 这个字段必须是经过在aop_item表中的字段我们通过code和datasource数据方式来确定这个val值
package com.cn.log;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictRedis {

    /**
     * 方法描述:类型dataSource
     * @return
     */
    String dictDataSource();

    /**
     * 返回后台的put到json中的文件key值
     * @return
     */
    String dictText() default "";

}

package com.cn.log;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoDict {
}

工具类

获取所有属性中的名称

package com.cn.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BeanUtil {
    /**
     * 通过反射包括父类的所有属性类型
     * @param object
     * @return
     */
    public static Field[] getAllFields(Object object){
        Class<?> clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz!=null){
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;

    }
}

实体类文件信息

package com.cn.entity;


import com.cn.log.DictRedis;

import java.io.Serializable;

/**
 * (AopStudent)实体类
 *
 * @author makejava
 * @since 2023-05-24 18:35:57
 */
public class AopStudent implements Serializable {
    private static final long serialVersionUID = 127399537035303507L;
    
    private Integer id;
    /**
    * 姓名
    */
    private String aopName;
    /**
    * 英语
    */
    @DictRedis(dictDataSource = "aop_english",dictText = "aop-cc")
    private String aopEnlish;
    /**
    * 等级
    */
    @DictRedis(dictDataSource = "aop_level")
    private String aopLevel;
    /**
    * 爱好
    */
    @DictRedis(dictDataSource = "aop_hobby")
    private String aopHobby;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAopName() {
        return aopName;
    }

    public void setAopName(String aopName) {
        this.aopName = aopName;
    }

    public String getAopEnlish() {
        return aopEnlish;
    }

    public void setAopEnlish(String aopEnlish) {
        this.aopEnlish = aopEnlish;
    }

    public String getAopLevel() {
        return aopLevel;
    }

    public void setAopLevel(String aopLevel) {
        this.aopLevel = aopLevel;
    }

    public String getAopHobby() {
        return aopHobby;
    }

    public void setAopHobby(String aopHobby) {
        this.aopHobby = aopHobby;
    }

}

controller信息

package com.cn.controller;

import com.cn.common.Constant;
import com.cn.common.Result;
import com.cn.entity.AopStudent;
import com.cn.log.DoDict;
import com.cn.service.AopStudentService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * (AopStudent)表控制层
 *
 * @author makejava
 * @since 2023-05-24 18:35:59
 */
@RestController
@RequestMapping("aopStudent")
public class AopStudentController {
    /**
     * 服务对象
     */
    @Resource
    private AopStudentService aopStudentService;

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("selectOne")
    public AopStudent selectOne(Integer id) {
        return this.aopStudentService.queryById(id);
    }

    /**
     * 获取所有学生的信息
     * @return 返回所有学生信息
     */
    @DoDict
    @GetMapping("findAll")
    public Result findAll(){
        List<AopStudent> all =aopStudentService.findAll();
        return new Result(Constant.success,"成功获取信息",all);
    }

}

测试

访问地址信息
http://localhost:10001/aopStudent/findAll
aop+springboot实现数据字典表_第3张图片

小结

这里我们查询效率更高,主要的方式通过分表的方式和aop注解方式进行提升效率方式

你可能感兴趣的:(java,spring,boot,java,数学建模)