An open API service indexing awesome lists of open source software.

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

Awesome Lists containing this project

README

          

### Dictionary Map

[![dictionary-map](https://img.shields.io/badge/plugin-dictionary--map--spring--boot--starter-green?style=flat-square)](https://github.com/tangxbai/dictionary-map) ![size](https://img.shields.io/badge/size-70kB-green?style=flat-square) [![license](https://img.shields.io/badge/license-Apache%202-blue?style=flat-square)](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