spingboot+aop实现数据字典方式
例如:
我们在想数据库中存储文字的时候,效率不高,这个时候我们会考虑存储,code编码格式数据,然后利用aop返回给前端的时候翻译code编码将值给code编码
我们会新建三张表
1.第一张表是aop_student学生表存储学生等级,兴趣,爱好,我们这里分别存储是code编码并不是存储真实的数据方式,我们会将真实的数据存储到aop_item
2.第二张表是aop_item这张表存储我们真实的数据信息,我们通过code和属性名称查询对应的值
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 组件拼接在一起形成的。
<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>
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
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;
}
}
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注解方式进行提升效率方式