自定义数据字典翻译注解

  • 参考出处
    • 代码背景
    • @Dict注解
    • 注解对应实现类
    • 工具类
      • 分页工具类
    • service层查询接口
    • service实现类和Mybatis的SQL语句
    • 实体类
    • 缓存的ehcache.xml存放在项目的位置
    • ehcache.xml
    • ehcache.xsd项目位置
    • ehcache.xsd内容
    • 每次新增或修改数据字典时候清空当前缓存
    • 数据表
    • 表格图片:
    • 表格数据样例
    • 使用样例

参考出处

(非常感谢)https://blog.csdn.net/weixin_42687829/article/details/103289383

代码背景

小公司新项目加上本人也就两个开发,很多地方用到了字典,于是在网上参考一篇数据字典翻译类,自己记录一下,方便之后项目用到使用。

@Dict注解


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @Author: Yin XX* @Description:* @Date: Create in 11:33 2020/4/30*/@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dict {/*** 方法描述:数据dataSource* @return 返回类型: String*/String dictDataSource();/*** 方法描述:这是返回后Put到josn中的文本key值* @return 返回类型: String*/String dictText() default "";
}

注解对应实现类


import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.renren.common.annotation.Dict;
import io.renren.common.utils.ObjConvertUtils;
import io.renren.common.utils.PageUtils;
import io.renren.modules.dictionaries.service.DictionariesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** @Author: Yin XX* @Description:* @Date: Create in 11:26 2020/4/30*/
@Aspect
@Component
@Slf4j
public class DictAspect {//表对应字段加上_dictText即可显示出文本private static String DICT_TEXT_SUFFIX = "_dictText";@Autowiredprivate DictionariesService dataItemService;//定义切点Pointcut拦截所有对服务器的请求@Pointcut("execution(* io.renren.modules.*.service.*.*(..))")public void excudeService() {}/*** 这是触发DictionariesService的时候会执行的,在环绕通知中目标对象方法被调用后的结果进行再处理* @param pjp* @return* @throws Throwable*/@Around("excudeService()")public Object doAround(ProceedingJoinPoint pjp) throws Throwable {//这是定义开始事件long time1 = System.currentTimeMillis();//这是方法并获取返回结果Object result = pjp.proceed();//这是获取到结束时间long time2 = System.currentTimeMillis();log.info("获取JSON数据耗时:" + (time2 - time1) + "ms");//解析开始时间long start = System.currentTimeMillis();//开始解析(翻译字段内部的值凡是打了@Dict这玩意的都会被翻译)this.parseDictText(result);//解析结束时间long end = System.currentTimeMillis();log.info("解析注入JSON数据耗时:" + (end - start) + "ms");return result;}private void parseDictText(Object result) {if (result instanceof PageUtils) {List<JSONObject> items = new ArrayList<>();PageUtils pageUtils = (PageUtils) result;//循环查找出来的数据for (Object record : pageUtils.getList()) {ObjectMapper mapper = new ObjectMapper();String json = "{}";try {//解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormatjson = mapper.writeValueAsString(record);} catch (JsonProcessingException e) {log.error("Json解析失败:" + e);}JSONObject item = JSONObject.parseObject(json);//解决继承实体字段无法翻译问题for (Field field : ObjConvertUtils.getAllFields(record)) {//解决继承实体字段无法翻译问题if (field.getAnnotation(Dict.class) != null) {//如果该属性上面有@Dict注解,则进行翻译String datasource = field.getAnnotation(Dict.class).dictDataSource();//拿到注解的dictDataSource属性的值String text = field.getAnnotation(Dict.class).dictText();//拿到注解的dictText属性的值//获取当前带翻译的值String key = String.valueOf(item.get(field.getName()));//翻译字典值对应的text值String textValue = translateDictValue(datasource, key);//DICT_TEXT_SUFFIX的值为,是默认值://public static final String DICT_TEXT_SUFFIX = "_dictText";log.debug("字典Val: " + textValue);log.debug("翻译字典字段:" + field.getName() + DICT_TEXT_SUFFIX + ": " + textValue);//如果给了文本名if (!StringUtils.isBlank(text)) {item.put(text, textValue);} else {//走默认策略item.put(field.getName() + DICT_TEXT_SUFFIX, textValue);}}//date类型默认转换string格式化日期if (field.getType().getName().equals("java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));}}items.add(item);}pageUtils.setList(items);}}/*** 翻译字典文本* @param datasource* @param key* @return*/private String translateDictValue(String datasource, String key) {//如果key为空直接返回就好了if (ObjConvertUtils.isEmpty(key)) {return null;}StringBuffer textValue = new StringBuffer();//分割key值String[] keys = key.split(",");//循环keys中的所有值for (String k : keys) {String tmpValue = null;log.debug("字典key:" + k);if (k.trim().length() == 0) {continue;//跳过循环}tmpValue = dataItemService.selectByFieldNameAndFieldValue(datasource, k.trim());if (tmpValue != null) {if (!"".equals(textValue.toString())) {textValue.append(",");}textValue.append(tmpValue);}}//返回翻译的值return textValue.toString();}
}

工具类


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @Author: Yin xx* @Description:* @Date: Create in 11:38 2020/4/30*/
public class ObjConvertUtils {/*** 获取类的所有属性,包括父类* @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;}public static boolean isEmpty(Object object) {if (object == null) {return (true);}if ("".equals(object)) {return (true);}if ("null".equals(object)) {return (true);}return (false);}
}

分页工具类

/*** Copyright (c) 2016-2019 人人开源 All rights reserved.** https://www.renren.io** 版权所有,侵权必究!*/package io.renren.common.utils;import com.baomidou.mybatisplus.core.metadata.IPage;import java.io.Serializable;
import java.util.List;/*** 分页工具类** @author Mark sunlightcs@gmail.com*/
public class PageUtils implements Serializable {private static final long serialVersionUID = 1L;/*** 总记录数*/private int totalCount;/*** 每页记录数*/private int pageSize;/*** 总页数*/private int totalPage;/*** 当前页数*/private int currPage;/*** 列表数据*/private List<?> list;/*** 分页* @param list        列表数据* @param totalCount  总记录数* @param pageSize    每页记录数* @param currPage    当前页数*/public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {this.list = list;this.totalCount = totalCount;this.pageSize = pageSize;this.currPage = currPage;this.totalPage = (int)Math.ceil((double)totalCount/pageSize);}/*** 分页*/public PageUtils(IPage<?> page) {this.list = page.getRecords();this.totalCount = (int)page.getTotal();this.pageSize = (int)page.getSize();this.currPage = (int)page.getCurrent();this.totalPage = (int)page.getPages();}public int getTotalCount() {return totalCount;}public void setTotalCount(int totalCount) {this.totalCount = totalCount;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getTotalPage() {return totalPage;}public void setTotalPage(int totalPage) {this.totalPage = totalPage;}public int getCurrPage() {return currPage;}public void setCurrPage(int currPage) {this.currPage = currPage;}public List<?> getList() {return list;}public void setList(List<?> list) {this.list = list;}}

service层查询接口


import com.baomidou.mybatisplus.extension.service.IService;
import io.renren.common.utils.PageUtils;
import io.renren.modules.dictionaries.entity.DictionariesEntity;
import org.springframework.cache.annotation.Cacheable;import java.util.Map;/*** @Author: Yin xx* @Description:* @Date: Create in 16:06 2020/4/29*/
public interface DictionariesService extends IService<DictionariesEntity> {/*** 列表查询* @param params* @return*/PageUtils queryPage(Map<String, Object> params);/*** 将查询出来的字段存放在缓存中* @param fieldName* @param fieldValue* @return*/@Cacheable(value = "dictEhcache") //把数据缓存到本地String selectByFieldNameAndFieldValue(String fieldName,String fieldValue);}

service实现类和Mybatis的SQL语句

    @Overridepublic String selectByFieldNameAndFieldValue(String fieldName, String fieldValue) {DictionariesEntity entity = this.baseMapper.selectByFieldNameAndFieldValue(fieldName, fieldValue);if(entity ==null){return "无翻译词汇";}return entity.getFieldDetail();}==============================分割线,以下是SQL=================================================<!--通过表格字段名和字段值查询该字典信息--><select id="selectByFieldNameAndFieldValue" parameterType="java.lang.String"resultType="io.renren.modules.dictionaries.entity.DictionariesEntity">SELECT * FROM pz_dictionaries<where><if test="fieldName != null and fieldName !=''">field_name = #{fieldName}</if><if test="fieldValue != null and fieldValue !=''">and field_value = #{fieldValue}</if></where></select>

实体类


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;/*** @Author: Yin xx* @Description: 数据字典表* @Date: Create in 16:11 2020/4/29*/
@Data
@TableName("pz_dictionaries")
public class DictionariesEntity implements Serializable {/*** 字段唯一标识*/@TableId(value = "id",type = IdType.UUID)private String id;/*** 字段名*/@TableField("field_name")private String fieldName;/*** 字段值*/@TableField("field_value")private String fieldValue;/*** 字段说明*/@TableField("field_detail")private String fieldDetail;/*** 具体描述*/@TableField("field_describe")private String fieldDescribe;
}

缓存的ehcache.xml存放在项目的位置

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="./config/ehcache.xsd"updateCheck="false"><!--这个是磁盘存储路径,当内存缓存满了的时候,就会往这里面放,java.io.tmdir是操作系统缓存的临时目录,不同操作系统缓存目录不一样。--><diskStore path="D:/ehcacheData"/><!--maxElementsInMemory      内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素overflowToDisk,内存不足时,是否启用磁盘缓存--><!--eternal:缓存中对象是否永久有效--><!--timeToIdleSeconds:缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除--><!--timeToLiveSeconds:缓存数据的总的存活时间(单位:秒),仅当eternal=false时使用,从创建开始计时,失效结束。--><!--maxElementsOnDisk:磁盘缓存中最多可以存放的元素数量,0表示无穷大--><defaultCacheeternal="false"maxElementsInMemory="10000"overflowToDisk="false"diskPersistent="false"timeToIdleSeconds="600"timeToLiveSeconds="600"maxElementsOnDisk="10000000"memoryStoreEvictionPolicy="LRU" /><!-- 这里的 dictEhcache 缓存空间是为了缓存字典数据做准备 --><cachename="dictEhcache"eternal="false"maxElementsInMemory="1000"overflowToDisk="false"diskPersistent="false"timeToIdleSeconds="600"timeToLiveSeconds="600"memoryStoreEvictionPolicy="LRU" />
</ehcache>

ehcache.xsd项目位置

ehcache.xsd内容

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.7"><xs:element name="ehcache"><xs:complexType><xs:sequence><xs:element maxOccurs="1" minOccurs="0" ref="diskStore"/><xs:element maxOccurs="1" minOccurs="0" ref="sizeOfPolicy"/><xs:element maxOccurs="1" minOccurs="0" ref="transactionManagerLookup"/><xs:element maxOccurs="1" minOccurs="0" ref="cacheManagerEventListenerFactory"/><xs:element maxOccurs="1" minOccurs="0" ref="managementRESTService"/><xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerProviderFactory"/><xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerListenerFactory"/><xs:element maxOccurs="1" minOccurs="0" ref="terracottaConfig"/><xs:element maxOccurs="1" minOccurs="0" ref="defaultCache"/><xs:element maxOccurs="unbounded" minOccurs="0" ref="cache"/></xs:sequence><xs:attribute name="name" use="optional"/><xs:attribute default="true" name="updateCheck" type="xs:boolean" use="optional"/><xs:attribute default="autodetect" name="monitoring" type="monitoringType" use="optional"/><xs:attribute default="true" name="dynamicConfig" type="xs:boolean" use="optional"/><xs:attribute default="15" name="defaultTransactionTimeoutInSeconds" type="xs:integer" use="optional"/><xs:attribute default="0" name="maxBytesLocalHeap" type="memoryUnitOrPercentage" use="optional"/><xs:attribute default="0" name="maxBytesLocalOffHeap" type="memoryUnit" use="optional"/><xs:attribute default="0" name="maxBytesLocalDisk" type="memoryUnit" use="optional"/></xs:complexType></xs:element><xs:element name="managementRESTService"><xs:complexType><xs:attribute name="enabled" type="xs:boolean" use="optional"/><xs:attribute name="bind" use="optional"/><xs:attribute name="securityServiceLocation" use="optional"/><xs:attribute name="securityServiceTimeout" use="optional" type="xs:integer"/><xs:attribute name="sslEnabled" use="optional" type="xs:boolean"/><xs:attribute name="needClientAuth" use="optional" type="xs:boolean"/><xs:attribute name="sampleHistorySize" use="optional" type="xs:integer"/><xs:attribute name="sampleIntervalSeconds" use="optional" type="xs:integer"/><xs:attribute name="sampleSearchIntervalSeconds" use="optional" type="xs:integer"/></xs:complexType></xs:element><xs:element name="diskStore"><xs:complexType><xs:attribute name="path" use="optional"/></xs:complexType></xs:element><xs:element name="transactionManagerLookup"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheManagerEventListenerFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheManagerPeerProviderFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheManagerPeerListenerFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="terracottaConfig"><xs:complexType><xs:sequence><xs:element maxOccurs="1" minOccurs="0" name="tc-config"><xs:complexType><xs:sequence><xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip"/></xs:sequence></xs:complexType></xs:element></xs:sequence><xs:attribute default="localhost:9510" name="url" use="optional"/><xs:attribute name="rejoin" type="xs:boolean" use="optional" default="false"/><xs:attribute name="wanEnabledTSA" type="xs:boolean" use="optional" default="false"/></xs:complexType></xs:element><!--add clone support for addition of cacheExceptionHandler. Important!--><xs:element name="defaultCache"><xs:complexType><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/><xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/><xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/><xs:element minOccurs="0" maxOccurs="1" ref="pinning"/><xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/><xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/><xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/><xs:element minOccurs="0" maxOccurs="1" ref="elementValueComparator"/><xs:element minOccurs="0" maxOccurs="1" ref="sizeOfPolicy"/><xs:element minOccurs="0" maxOccurs="1" ref="persistence"/></xs:sequence><xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/><xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/><xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/><xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/><xs:attribute name="eternal" type="xs:boolean" use="optional" default="false"/><xs:attribute name="maxElementsInMemory" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxEntriesLocalHeap" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/><xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/><xs:attribute name="overflowToDisk" type="xs:boolean" use="optional"/><xs:attribute name="timeToIdleSeconds" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="timeToLiveSeconds" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxElementsOnDisk" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxEntriesLocalDisk" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off"/><xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/><xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/><xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/><xs:attribute name="cacheLoaderTimeoutMillis" type="xs:integer" use="optional" default="0"/><xs:attribute name="overflowToOffHeap" type="xs:boolean" use="optional" default="false"/><xs:attribute name="maxMemoryOffHeap" type="xs:string" use="optional"/></xs:complexType></xs:element><xs:element name="cache"><xs:complexType><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/><xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/><xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/><xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/><xs:element minOccurs="0" maxOccurs="1" ref="pinning"/><xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/><xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/><xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/><xs:element minOccurs="0" maxOccurs="1" ref="searchable"/><xs:element minOccurs="0" maxOccurs="1" ref="elementValueComparator"/><xs:element minOccurs="0" maxOccurs="1" ref="sizeOfPolicy"/><xs:element minOccurs="0" maxOccurs="1" ref="persistence"/></xs:sequence><xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/><xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/><xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/><xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/><xs:attribute name="eternal" type="xs:boolean" use="optional" default="false"/><xs:attribute name="maxElementsInMemory" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxEntriesLocalHeap" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/><xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/><xs:attribute name="name" type="xs:string" use="required"/><xs:attribute name="overflowToDisk" type="xs:boolean" use="optional"/><xs:attribute name="timeToIdleSeconds" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="timeToLiveSeconds" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxElementsOnDisk" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxEntriesLocalDisk" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="maxEntriesInCache" type="xs:nonNegativeInteger" use="optional"/><xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off"/><xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/><xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/><xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/><xs:attribute name="logging" type="xs:boolean" use="optional" default="false"/><xs:attribute name="cacheLoaderTimeoutMillis" type="xs:integer" use="optional" default="0"/><xs:attribute name="overflowToOffHeap" type="xs:boolean" use="optional" default="false"/><xs:attribute name="maxMemoryOffHeap" type="xs:string" use="optional"/><xs:attribute default="0" name="maxBytesLocalHeap" type="memoryUnitOrPercentage" use="optional"/><xs:attribute default="0" name="maxBytesLocalOffHeap" type="memoryUnitOrPercentage" use="optional"/><xs:attribute default="0" name="maxBytesLocalDisk" type="memoryUnitOrPercentage" use="optional"/></xs:complexType></xs:element><xs:element name="cacheEventListenerFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/><xs:attribute name="listenFor" use="optional" type="notificationScope" default="all"/></xs:complexType></xs:element><xs:element name="bootstrapCacheLoaderFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheExtensionFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheExceptionHandlerFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheLoaderFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="cacheDecoratorFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="searchAttribute"><xs:complexType><xs:attribute name="name" use="required" type="xs:string"/><xs:attribute name="expression" type="xs:string"/><xs:attribute name="class" type="xs:string"/><xs:attribute name="type" type="xs:string" use="optional"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="searchable"><xs:complexType><xs:sequence><xs:element minOccurs="0" maxOccurs="unbounded" ref="searchAttribute"/></xs:sequence><xs:attribute name="keys" use="optional" type="xs:boolean" default="true"/><xs:attribute name="values" use="optional" type="xs:boolean" default="true"/><xs:attribute name="allowDynamicIndexing" use="optional" type="xs:boolean" default="false"/></xs:complexType></xs:element><xs:element name="pinning"><xs:complexType><xs:attribute name="store" use="required" type="pinningStoreType"/></xs:complexType></xs:element><xs:element name="terracotta"><xs:complexType><xs:sequence><xs:element minOccurs="0" maxOccurs="1" ref="nonstop"/></xs:sequence><xs:attribute name="clustered" use="optional" type="xs:boolean" default="true"/><xs:attribute name="coherentReads" use="optional" type="xs:boolean" default="true"/><xs:attribute name="localKeyCache" use="optional" type="xs:boolean" default="false"/><xs:attribute name="localKeyCacheSize" use="optional" type="xs:positiveInteger" default="300000"/><xs:attribute name="orphanEviction" use="optional" type="xs:boolean" default="true"/><xs:attribute name="orphanEvictionPeriod" use="optional" type="xs:positiveInteger" default="4"/><xs:attribute name="copyOnRead" use="optional" type="xs:boolean" default="false"/><xs:attribute name="coherent" use="optional" type="xs:boolean" default="false"/><xs:attribute name="consistency" use="optional" type="consistencyType" default="eventual"/><xs:attribute name="synchronousWrites" use="optional" type="xs:boolean" default="false"/><xs:attribute name="concurrency" use="optional" type="xs:nonNegativeInteger" default="0"/><xs:attribute name="localCacheEnabled" use="optional" type="xs:boolean" default="true"/><xs:attribute name="compressionEnabled" use="optional" type="xs:boolean" default="false"/></xs:complexType></xs:element><xs:simpleType name="consistencyType"><xs:restriction base="xs:string"><xs:enumeration value="strong"/><xs:enumeration value="eventual"/></xs:restriction></xs:simpleType><xs:element name="nonstop"><xs:complexType><xs:sequence><xs:element minOccurs="0" maxOccurs="1" ref="timeoutBehavior"/></xs:sequence><xs:attribute name="enabled" use="optional" type="xs:boolean" default="true"/><xs:attribute name="immediateTimeout" use="optional" type="xs:boolean" default="false"/><xs:attribute name="timeoutMillis" use="optional" type="xs:positiveInteger" default="30000"/><xs:attribute name="searchTimeoutMillis" use="optional" type="xs:positiveInteger" default="30000"/></xs:complexType></xs:element><xs:element name="timeoutBehavior"><xs:complexType><xs:attribute name="type" use="optional" type="timeoutBehaviorType" default="exception"/><xs:attribute name="properties" use="optional" default=""/><xs:attribute name="propertySeparator" use="optional" default=","/></xs:complexType></xs:element><xs:simpleType name="timeoutBehaviorType"><xs:restriction base="xs:string"><xs:enumeration value="noop"/><xs:enumeration value="exception"/><xs:enumeration value="localReads"/><xs:enumeration value="localReadsAndExceptionOnWrite"/></xs:restriction></xs:simpleType><xs:simpleType name="monitoringType"><xs:restriction base="xs:string"><xs:enumeration value="autodetect"/><xs:enumeration value="on"/><xs:enumeration value="off"/></xs:restriction></xs:simpleType><xs:simpleType name="pinningStoreType"><xs:restriction base="xs:string"><xs:enumeration value="localMemory"/><xs:enumeration value="inCache"/></xs:restriction></xs:simpleType><xs:simpleType name="terracottaCacheValueType"><xs:restriction base="xs:string"><xs:enumeration value="serialization"/><xs:enumeration value="identity"/></xs:restriction></xs:simpleType><xs:simpleType name="transactionalMode"><xs:restriction base="xs:string"><xs:enumeration value="off"/><xs:enumeration value="xa_strict"/><xs:enumeration value="xa"/><xs:enumeration value="local"/></xs:restriction></xs:simpleType><xs:element name="cacheWriter"><xs:complexType><xs:sequence><xs:element minOccurs="0" maxOccurs="1" ref="cacheWriterFactory"/></xs:sequence><xs:attribute name="writeMode" use="optional" type="writeModeType" default="write-through"/><xs:attribute name="notifyListenersOnException" use="optional" type="xs:boolean" default="false"/><xs:attribute name="minWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/><xs:attribute name="maxWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/><xs:attribute name="rateLimitPerSecond" use="optional" type="xs:nonNegativeInteger" default="0"/><xs:attribute name="writeCoalescing" use="optional" type="xs:boolean" default="false"/><xs:attribute name="writeBatching" use="optional" type="xs:boolean" default="false"/><xs:attribute name="writeBatchSize" use="optional" type="xs:positiveInteger" default="1"/><xs:attribute name="retryAttempts" use="optional" type="xs:nonNegativeInteger" default="0"/><xs:attribute name="retryAttemptDelaySeconds" use="optional" type="xs:nonNegativeInteger" default="1"/><xs:attribute name="writeBehindConcurrency" use="optional" type="xs:nonNegativeInteger" default="1"/><xs:attribute name="writeBehindMaxQueueSize" use="optional" type="xs:nonNegativeInteger" default="0"/></xs:complexType></xs:element><xs:simpleType name="writeModeType"><xs:restriction base="xs:string"><xs:enumeration value="write-through"/><xs:enumeration value="write-behind"/></xs:restriction></xs:simpleType><xs:element name="cacheWriterFactory"><xs:complexType><xs:attribute name="class" use="required"/><xs:attribute name="properties" use="optional"/><xs:attribute name="propertySeparator" use="optional"/></xs:complexType></xs:element><xs:element name="copyStrategy"><xs:complexType><xs:attribute name="class" use="required" type="xs:string"/></xs:complexType></xs:element><xs:element name="elementValueComparator"><xs:complexType><xs:attribute name="class" use="required" type="xs:string"/></xs:complexType></xs:element><xs:element name="sizeOfPolicy"><xs:complexType><xs:attribute name="maxDepth" use="required" type="xs:integer"/><xs:attribute name="maxDepthExceededBehavior" use="optional" default="continue"type="maxDepthExceededBehavior"/></xs:complexType></xs:element><xs:element name="persistence"><xs:complexType><xs:attribute name="strategy" use="required" type="persistenceStrategy"/><xs:attribute name="synchronousWrites" use="optional" default="false" type="xs:boolean"/></xs:complexType></xs:element><xs:simpleType name="persistenceStrategy"><xs:restriction base="xs:string"><xs:enumeration value="localTempSwap"/><xs:enumeration value="localRestartable"/><xs:enumeration value="none"/><xs:enumeration value="distributed"/></xs:restriction></xs:simpleType><xs:simpleType name="maxDepthExceededBehavior"><xs:restriction base="xs:string"><xs:enumeration value="continue"/><xs:enumeration value="abort"/></xs:restriction></xs:simpleType><xs:simpleType name="notificationScope"><xs:restriction base="xs:string"><xs:enumeration value="local"/><xs:enumeration value="remote"/><xs:enumeration value="all"/></xs:restriction></xs:simpleType><xs:simpleType name="memoryUnit"><xs:restriction base="xs:token"><xs:pattern value="[0-9]+[bBkKmMgG]?"/></xs:restriction></xs:simpleType><xs:simpleType name="memoryUnitOrPercentage"><xs:restriction base="xs:token"><xs:pattern value="([0-9]+[bBkKmMgG]?|100%|[0-9]{1,2}%)"/></xs:restriction></xs:simpleType>
</xs:schema>

每次新增或修改数据字典时候清空当前缓存

/*** 保存* @param entity* @return*/@RequestMapping("/save")@RequiresPermissions("dictionaries:list")@CacheEvict(value="dictEhcache", allEntries=true) //清空缓存public R save(@RequestBody DictionariesEntity entity) {String errMassage = "保存失败";if(entity != null){Map<String,Object> parMap = new HashMap<>();parMap.put("field_name",entity.getFieldName());parMap.put("field_value",entity.getFieldValue());Collection<DictionariesEntity> collections = service.listByMap(parMap);if(collections.size()==0){boolean b = service.save(entity);if (b) {return R.ok();}}else {errMassage="该表'字段名'和'字段码值'已存在";}}return R.error().put("msg",errMassage);}

数据表

pz_dictionaries表字段:

字段名 类型 备注
id varchar uuid,唯一标识
field_name varchar 对应表格字段名
field_value varchar 字段值
field_detail varchar 字段说明
field_describe varchar 具体描述

表格图片:

表格数据样例

使用样例

/*** 子任务状态*/@TableField("subtask_status")@Dict(dictDataSource = "subtask_status")//需要翻译的实体类字段加上注解private String subtaskStatus;==============================前端样例======================================<el-table-columnprop="subtaskStatus_dictText" //在字段后加上_dictTextheader-align="center"align="center"label="子任务状态"></el-table-column>

自定义数据字典翻译注解相关推荐

  1. java 注解 数据字典_Spring实现数据字典翻译

    在开始之前,首先我们要了解一个类:BeanPropertyWriter. 这个类是由SerializerFactory 工厂进行实例化的,其作用是对bean中的每个字段进行jackson操作的封装,其 ...

  2. 自定义hibernate validation注解

    效果和优点 先看最后效果: public class UserEntity {@Password private String password;@Emailprivate String email; ...

  3. return error怎么定义_这一次搞懂Spring自定义标签以及注解解析原理

    自定义标签解析原理 在上一篇分析默认标签解析时看到过这个类DefaultBeanDefinitionDocumentReader的方法parseBeanDefinitions:拉勾IT课小编为大家分解 ...

  4. 自定义数据字典工具类

    字典注解 类注解 import lombok.NonNull; import java.lang.annotation.*;/*** 数据字典类注解** @author huxiang*/ @Targ ...

  5. java 自定义json解析注解 复杂json解析 工具类

    java 自定义json解析注解 复杂json解析 工具类 目录 java 自定义json解析注解 复杂json解析 工具类 1.背景 2.需求-各式各样的json 一.一星难度json[json对象 ...

  6. idea自定义中英文翻译插件

    idea自定义中英文翻译插件 插件的开发 参考网址 前提 idea创建项目 代码 运行 发布到自己的idea 打包方式 总结 插件的开发 参考网址 (gradle例子,真的讲的好) (gradle例子 ...

  7. SpringBoot注解--@SpringBootApplication/@MapperScan/自定义启动类注解

    原文网址:SpringBoot注解--@SpringBootApplication/@MapperScan/自定义启动类注解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SpringBoot启动类 ...

  8. Aop+自定义注解实现数据字典翻译

    目录 前言 源码 思维导图 前言 一般来说,项目开发会用自定义注解去实现日志监控等操作 在实际项目中,前后台数据交互时,每次都需要根据一个code值去进行查询数据库进行中间操作进行获取text值 本博 ...

  9. 适用于Spring Boot的数据字典翻译Starter

    在常见的web应用中,有很多数据库字段会使用字典值,但是在数据查询时,我们需要将存储的字典值转换成对应的字典标签(value>>name),用于展示给用户.常见的转换方式为从数据库查询.逻 ...

  10. java 数据字典翻译_BeanUtils——JavaBean相互转换及字典翻译

    翻译JavaBean中带有@CacheFormat的属性/** * 翻译当前类中需要翻译的字典值 * * @param source 待翻译的对象 */ public static  void dat ...

最新文章

  1. java京东查询物流轨迹事例_Java爬虫实现京东物流查询
  2. [LeetCode]Find Minimum in Rotated Sorted Array
  3. 计算机课件比赛总结,课件制作比赛活动总结
  4. 信息学奥赛C++语言:津津的储蓄计划
  5. 美国IARPA发起公共安全预测机器学习挑战赛(总奖池10万美金)
  6. redid过期策略_Redis数据过期策略详解
  7. java处理最后一周_Java得到的一周的最后一天的一段时间内
  8. 数值分析复习(七)——偏微分方程数值解法
  9. firebug下载地址
  10. 阿正入门深度学习---从EM算法开始
  11. 如何从0搭建公司后端技术栈?
  12. 六(1) Python之列表
  13. 计算机相关缩略语,计算机缩略语精选
  14. 实验matlab滤波器心得,实验报告基于MATLAB的数字滤波器设计
  15. 计算机word表格线设置在哪里,word表格文字显示不全_word表格怎么设置显示最后一行线?_word表格怎么加一行...
  16. powershell导入脚本失败,禁止运行脚本,无法远程连接服务器
  17. VIRTIO PCI 设备
  18. 人生永无止境的意思是什么_永无止境是什么意思
  19. 聚友网任命魏来为首席执行官
  20. 3904三极管是什么功能_为什么有时候我们在电路中串联220电阻

热门文章

  1. 综述-自动驾驶中基于图像的3D目标检测
  2. VBA调用程序时,exe程序一闪而过,解决方法
  3. 打字游戏html代码,JavaScript打字小游戏代码
  4. mamp安装php扩展,mac版mamp下php安装pcntl扩展
  5. python提取全部个股数据_Python 股票历史数据的获取
  6. mysql sql文件在哪里打开_mysql怎么打开sql文件
  7. 单片机课程设计:基于STM32智能交通灯的设计
  8. [Windows] 【强力推荐】可以将任何格式的文档免费转换为高质量PDF文件的软件,珍藏宝贝!!!
  9. JAVA实现Word转Pdf文件
  10. 浅谈 wxWindows FrameWork