https://github.com/tangxbai/dictionary-map-spring-boot
Dictionary map for springboot
https://github.com/tangxbai/dictionary-map-spring-boot
Last synced: 9 months ago
JSON representation
Dictionary map for springboot
- Host: GitHub
- URL: https://github.com/tangxbai/dictionary-map-spring-boot
- Owner: tangxbai
- License: apache-2.0
- Created: 2023-08-01T09:00:15.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-08-15T02:37:41.000Z (over 2 years ago)
- Last Synced: 2025-01-27T06:31:34.218Z (11 months ago)
- Language: Java
- Size: 119 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: changelog.md
- License: LICENSE
Awesome Lists containing this project
README
### Dictionary Map
[](https://github.com/tangxbai/dictionary-map)  [](http://www.apache.org/licenses/LICENSE-2.0.html)
### 项目简介
基本每个项目或者系统都会有字典数据配置,而这又是一项重复不讨好的工作,就算写好了复制过去也相当麻烦,这些东西基本每个项目都大同小异,不会怎么变化,做国际化自适应也是一项很麻烦的事,所以这里为大家提供一套完整的字典操作Api,支持多语言、支持国际化、支持动态增删改查、支持国际化快速复制、支持字典对象自动转换等操作,这样就无须单独去维护这部分业务逻辑了。
*注意:此项目是一款完全开源的项目,您可以在任何适用的场景使用它,商用或者学习都可以,如果您有任何项目上的疑问,可以在issue上提出您问题,我会在第一时间回复您,如果您觉得它对您有些许帮助,希望能留下一个您的星星(★),谢谢。*
------
此项目遵照 [Apache 2.0 License]( http://www.apache.org/licenses/LICENSE-2.0.txt ) 开源许可
### 核心亮点
- **支持国际化**:方便快捷的拓展语言种类,并支持从已有语种上拷贝备份;
- **支持语言扩展**:可随意添加或复制新的语种;
- **支持CRUD**:提供对字典表进行增删改查等,并且如果涉及到缓存时会自动更新缓存;
- **支持自动缓存**:数据操作过后自动缓存,并可以指定数据缓存方式(内存或者基于Redis);
- **数据语义化**:通过将字典键进行处理,返回语义化的字典表数据(便于前端处理的格式);
- **自动参数转换**:支持通过传递 code/alias 转换成字典实体对象,普通传参方式和 JavaBean 均可。
- **支持各种查询**:查询指定键的字典列表,或者精确匹配,亦或是查询所有字典列表等;
- **使用多样化**:提供静态上下文直接访问,或者是使用spring进行对象注入等;
- **自定义国际化方式**:可以通过请求头获取,也可以通过请求参数获取,更可以直接固定语言;
### 关于语义化的说明
> 原始表格数据
| id | type | key | code | alias | text |
| ---- | ---- | ------------------ | ---- | ----- | ---------------- |
| 1 | TEXT | settings.title | 0 | | 字典映射 |
| 2 | TEXT | settings.author | 0 | | tangxbai |
| 3 | TEXT | settings.copyright | 0 | | 2023 |
| 4 | TEXT | demo.level.A | 0 | | 多层级文本 |
| 5 | TEXT | demo.level.B | 0 | | 多层级文本数组 A |
| 6 | TEXT | demo.level.B | 0 | | 多层级文本数组 B |
| 7 | TEXT | demo.level.B | 0 | | 多层级文本数组 C |
| 8 | ENUM | demo.level.C | 1 | em | 多层级枚举 |
| 8 | ENUM | demo.level.D | 1 | em | 多层级枚举数组 A |
| 8 | ENUM | demo.level.D | 2 | em | 多层级枚举数组 B |
> 接口响应的 JSON 化数据
```json
{
"settings": {
"title": "字典映射",
"author": "tangxbai",
"copyright": "2023"
},
{
"demo": {
"level": {
"A": "多层级文本",
"B": [ "多层级文本数组 A", "多层级文本数组 B", "多层级文本数组 C" ],
"C" : {
"code": 1,
"text": "多层级枚举"
},
"D" : [
{
"code": 1,
"text": "多层级枚举数组 A"
},
{
"code": 2,
"text": "多层级枚举数组 B"
}
]
}
}
}
}
```
### 切换国际化
1、通过配置项 `spring.dict.locale` 来指定语言环境,这种属于固定语言种类,无法切换其他语言;
2、通过请求参数中携带 `lang` 参数来确定语言,比如:`?lang=zh-CN`等,此属性可以通过 `spring.dict.locale-query` 配置项来更改;
3、通过请求头携带的语言,自动获取请求头 `Accept-Language` 中的指定的语言种类;
*请注意:决定国际化语言的 **优先级** 按照序号从高到低进行排列*
### 快速开始
Maven方式(**推荐**)
```xml
com.viiyue.plugins
dictionary-map
[VERSION]
```
如果你没有使用Maven构建工具,那么可以通过以下途径下载相关jar包,并导入到你的编辑器。
[点击跳转下载页面](https://search.maven.org/search?q=g:com.viiyue.plugins%20AND%20a:dictionary-map&core=gav)
如何获取最新版本?[点击这里获取最新版本](https://search.maven.org/search?q=g:com.viiyue.plugins%20AND%20a:dictionary-map&core=gav)
### 核心注解
注解
类型
描述
@Dict( "dict.key" )
Parameter( Controller ) | Field( Java bean )
指定字典的 Key
@FromHeader
Parameter( Controller )
从 Header 中获取 Locale 对象
@FromSpring
Parameter( Controller )
通过 Spring 的 LocaleResolver 获取 Locale
### 偏好配置
属性
描述
类型
默认
spring.dict.jackson.enable
是否启用基于 JSON 的字典对象转换
Boolean
true
spring.dict.redis-first
在配置了 Redis 环境的前提下,优先使用 Redis 进行数据缓存
Boolean
true
spring.dict.loaded-default
是否在程序启动后,自动加载默认字典数据
Boolean
true
spring.dict.locale
设置默认 Locale,如果你使用了此属性,会优先使用此值作为主要语言
Boolean
true
spring.dict.locale-query
更改从请求参数中获取 Locale 的参数名
Boolean
lang
spring.dict.locale-argument-resolver
是否开启对于 Locale 参数的解析,需要配合 @FromHeader/@FromSpring 来使用
Boolean
true
spring.dict.small-batch-size
执行批量操作时,最小批量操作阈值
Integer
500
spring.dict.big-batch-size
执行批量操作时,大批量操作的批次处理阈值
Integer
1000
spring.dict.cache-key
数据缓存的前缀
String
cacheable:dict:
spring.dict.dict-table
默认字典表名
String
global_dictionary
spring.dict.lang-table
字典语言种类表
String
global_dictionary_lang
spring.dict.expands
语义化展开的字段
String[]
["code", "text"]
spring.dict.column-wrap-text
数据库列的包裹字符,用于区分关键字和自定义字符,避免自定义字符被认定为关键字
String
`
### 如何使用?
1、在启动类上启用支持
```java
@EnableDictionaryMap
@SpringBootApplication
public class Application {
public static void main( String [] args ) throws Exception {
SpringApplication.run( Application.class, args );
}
}
```
2、获取引用,以下两种均可
```java
// 1、在 spring bean 中,通过注入的方式获取引用
@Autowired
private DictManager dictManager;
dictManager.xxx();
// 2、在普通类中直接使用静态上下文
DictManager dictManager = DictContext.manager();
dictManager.xxx();
```
2、设计的 API 列表,[ 点击查看接口文档](https://console-docs.apipost.cn/preview/bb2a2baf59e88546/4e611f53b633548e)
```java
// 国际化相关
List getLanguages(); // 查询所有语种
boolean addLanguage( Language language ); // 添加一个语种
int updateLanguage( Language language ); // 更新已有语种
int removeLanguage( Language language ); // 删除一个语种
boolean existLanguage( Language language ); // 检测是否存在某语种
boolean addSnapshot( Locale source, Locale destination ); // 从指定语言快速拷贝
// 字典相关
Map expandAll(); // 展开语义化的JSON数据格式
List getAll(); // 查询所有字典列表【仅包含启用的】
List getAllAlways(); // 查询所有字典列表【忽略状态】
List get( String key ); // 查询指定键的字典列表【仅包含启用的】
List getAlways( String key ); // 查询指定键的字典列表【忽略状态】
List get( String ... key ); // 查询指定键的字典列表【仅包含启用的】
List getAlways( String ... key ); // 查询指定键的字典列表【忽略状态】
Dictionary match( String key, Integer code ); // 精确匹配指定key和code的字典项【仅包含启用的】
Dictionary matchAlways( String key, Integer code ); // 精确匹配指定key和code的字典项【忽略状态】
Dictionary match( String key, String alias ); // 精确匹配指定key和alias的字典项【仅包含启用的】
Dictionary matchAlways( String key, String alias ); // 精确匹配指定key和alias的字典项【忽略状态】
Dictionary matching( String key, Predicate predicate ); // 自定义精确匹配筛选
boolean add( Locale locale, Dictionary dict ); // 为某个语种添加一个字典项
boolean addBatch( Locale locale, List {
// 1. 尝试获取本地 HttpServletRequest(一般都能获取到)
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
if ( attributes == null ) {
return null;
}
HttpServletRequest request = ( ( ServletRequestAttributes ) attributes ).getRequest();
if ( request == null ) {
return null;
}
// 2. 首先尝试从请求参数中获取
String queryName = props.getLocaleQuery();
String language = request.getParameter( queryName ); // zh-CN
if ( !StringUtils.isEmpty( language ) ) {
language = language.replace( '_', '-' ); // Or zh_CN
return Locale.forLanguageTag( language );
}
// 3. 如果请求中未获取到则尝试通过Spring的国际化解析器获取,还是未果则最后获取请求头中的语言设置。
return RequestContextUtils.getLocale( request );
});
}
}
```
### 类型自动转换
##### 1、输入转换
1.1、在数据库实体中,通过向 mybatis 中注册类型处理器 **DictionaryTypeHandler ** 提供转换支持
```java
com.viiyue.plugins.dict.spring.boot.config.mybatis.DictionaryInterceptor
com.viiyue.plugins.dict.spring.boot.config.mybatis.DictionaryTypeHandler
```
```java
@Table( name = "t_your_table" )
public class YourModelBean {
@Id
private Long id;
@Dict( "user.gender" )
private Dictionary gender; // 数据库的 code 值会自动转换为字典对象
@Dict( "dict.key.xxx" )
private Dictionary xxxxxx; // 数据库的 code 值会自动转换为字典对象
}
```
1.2、在请求参数中,通过向 Spring 注册参数解析器 **DictionaryArgumentResolver ** 提供转换支持
```java
com.viiyue.plugins.dict.spring.boot.config.resolver.DictionaryArgumentResolver
```
```java
URL: /query/xxx?gender=1
@GetMapping( "/query/xxx" )
public void doQuery( @Dict( "user.gender" ) Dictionary gender ) {
System.out.println( gender );
}
```
1.3、在对象属性中
```java
com.viiyue.plugins.dict.spring.boot.config.resolver.DictionaryConverter
com.viiyue.plugins.dict.spring.boot.config.resolver.DictionaryJsonSerializer
```
```java
public class User {
private int id;
private String username;
@Dict( "user.gender" )
private Dictionary gender;
}
/**
* 1、From 表单
* 通过向 Spring 注册 Converter 提供转换支持
*
* @param user 表单参数
* @see com.viiyue.plugins.dict.spring.boot.config.resolver.DictionaryConverter
*/
@GetMapping( "/query/xxx" )
public void doQuery( User user ) {
System.out.println( user );
}
/**
* 2、JSON 参数
* 通过向 Jackson 中注册 JsonSerrializer 提供转换支持
*
* @param user JSON格式的参数
* @see com.viiyue.plugins.dict.spring.boot.config.resolver.DictionaryJsonSerializer
*/
@GetMapping( "/query/xxx" )
public void doQuery( @RrquestBody User user ) {
System.out.println( user );
}
```
##### 2、输出转换
```java
public class User {
private int id;
private String username;
private Dictionary gender;
}
@RestController
@RequestMapping( "/demo" )
public class YourController {
@Autowired
private YourService service;
@GetMapping( "/users" )
public List doQuery() {
return service.selectAll();
}
}
```
```json
// 请求URL
URL: /demo/users
// 响应结果
[
{
"id": 1,
"username": "xxx",
"gender": {
"code": 1,
"text": "Male"
}
},
{
"id": 2,
"username": "yyy",
"gender": {
"code": 2,
"text": "Famale"
}
}
]
```
### 关于作者
- 邮箱:tangxbai@hotmail.com
- 掘金: https://juejin.im/user/5da5621ce51d4524f007f35f
- 简书: https://www.jianshu.com/u/e62f4302c51f
- Issuse:https://github.com/tangxbai/dictionary-map/issues