Commit f7e12556 authored by 马超's avatar 马超

doc: 更新路径

parent df915a1d
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
​ 2、[Example样例工程开发文档](开发文档/Example样例工程开发文档.md) ​ 2、[Example样例工程开发文档](开发文档/Example样例工程开发文档.md)
​ 3、[LDP 框架自定义注解.md](http://gitlab.dev.shxrtech.com/doc/ldp-docs/blob/master/开发文档/LDP 框架自定义注解.md) ​ 3、[LDP框架自定义注解.md](http://gitlab.dev.shxrtech.com/doc/ldp-docs/blob/master/开发文档/LDP框架自定义注解.md)
​ 4、[git提交规范说明](开发文档/git提交规范说明.md) ​ 4、[git提交规范说明](开发文档/git提交规范说明.md)
......
# LDP 框架自定义注解使用说明文档
本文档是帮助开发者快速熟悉LDP框架中的自定义注解。
## 一、自动填充注解
### 1.1. @AutoComputed
依赖:base-api。
#### 1.1.1 注解介绍
**@AutoComputed**是一个字段注解,标识**实体类**字段为自动填充的注解,需要配合服务层的 **@AutoService** 使用,拥有四个属性,command、ref、refs、format。注解可以通过command标识字段自动装配的方式,根据字段名查找对应计算方法,或根据command类型查找对应系统计算方法。command默认值为 **ComputedCommand.AUTO** ,以下是内置command每个值的解释:
**AUTO**:根据字段名进行填充。
**MD5**:将字段值进行一次md5加密。
**DATETIME**:当前时间。
**USERID**:当前登录用户。
**UUID**:生成32位随机字符串。
**PINYIN**:将ref字段的拼音填充到此字段中
**REFERENCE**:将refs字段的值通过format规则填充到此字段
#### 1.1.2 使用案例
```java
// 值为AUTO,通过属性名查找计算方式,这里的计算方式就是createId
@AutoComputed
private String createId;
// 值为MD5,将原本的明文做一次md5加密并重新赋值到字段中
@AutoComputed(command = ComputedCommand.MD5)
private String userPassword;
// 值为DATETIME,将当前时间填充到字段中
@AutoComputed(command = ComputedCommand.DATETIME)
private Date createTime;
// 值为USERID,将当前登录用户ID填充到字段中
@AutoComputed(command = ComputedCommand.USERID)
private String updateId;
// 值为UUID,将随机生成的UUID填充到字段中
@AutoComputed(command = ComputedCommand.UUID)
private String uuId;
// 值为PINYIN,ref为userName,将userName字段的中文拼音自动填充到字段中
@AutoComputed(command = ComputedCommand.PINYIN, ref = "userName")
private String sortName;
// 值为REFERENCE,refs是一个数组, 将数组中的字段值按照format的规则填充到字段中
@AutoComputed(command = ComputedCommand.REFERENCE, refs = {"name", "age", "gender"}, format = "%s-%s-%s")
private String referenceValue;
```
#### 1.1.3 自定义填充算法
当command值为 **ComputedCommand.AUTO** 时,会通过字段名查找计算方式,这里介绍一下如何自定义填充算法。自动填充算法分为三种:
- 第一种是有参算法,例如MD5算法需要使用到原字段中的值作为参数:
```java
// 值为MD5,将原本的明文做一次md5加密并重新赋值到字段中
@AutoComputed(command = ComputedCommand.MD5)
private String userPassword;
```
需要实现 **ComputerArgs** 接口,将自动填充算法写到computed中。例如Md5填充算法代码如下:
```java
public class ComputerMd5 implements ComputerArgs {
@Override
public String computed(Object plain) {
//这里进行处理,并返回自动填充内容
return DigestUtils.md5Hex(plain.toString());
}
}
```
- 第二种也是有参算法,主要是为了按照format进行自动填充,例如:
```java
// 值为REFERENCE,refs是一个数组, 将数组中的字段值按照format的规则填充到字段中
@AutoComputed(command = ComputedCommand.REFERENCE, refs = {"name", "age", "gender"}, format = "%s-%s-%s")
private String referenceValue;
```
需要实现 **ComputerFormatArgs** 接口,将自动填充算法写到computed中。例如REFERENCE填充算法如下:
```java
public class ComputerReference implements ComputerFormatArgs {
@Override
public String computed(Object target, String format) {
String result = "";
//核心代码如下,如果format为空则默认以下划线拼接,否则按fromat格式化
if (StringUtils.isEmpty(format)) {
result = StringUtils.joinWith("_", objects);
} else {
result = String.format(format, objects);
}
return result;
}
}
```
- 第三种是无参算法,例如DATETIME算法就是一个无参算法,只需要获取当前时间:
```java
// 值为DATETIME,将当前时间填充到字段中
@AutoComputed(command = ComputedCommand.DATETIME)
private Date createTime;
```
无参算法与有参类似,只是没有参数,需要实现 **ComputerNoArgs** 接口
```java
public class ComputerDate implements ComputerNoArgs<Date> {
@Override
public Date computed() {
return new Date();
}
}
```
- 完成算法编写后,还需要将计算类与字段名对应起来。
在service包中新建computed包(推荐),新建一个类,加上 **@Configuration** 注解,在 **@Bean** 注解中的name属性填上字段名。例如字段createId的填充算法是一个无参算法,方法返回类型为 **ComputerNoArgs** ,如果为有参算法,则应该返回 **ComputerArgs** 或者 **ComputerFormatArgs**
```java
@Configuration
public class ComputedResolver {
@Bean(name = "createId")
public ComputerNoArgs getCreateId() {
return new ComputerUser();
}
}
```
当AOP在处理自动填充时,这个字段就会根据上面编辑的算法进行自动填充。
### 1.2. @AutoService
依赖:mcs-common
#### 1.2.1 注解介绍
**@AutoService**是一个方法注解,被 **@AutoService** 注解的方法,都会被AOP拦截,并根据实体类字段中的 **@AutoComputed** 规则对字段自动填充。拥有两个属性 mode、init,mode为填充方式,默认为 **ComputedMode.COMPUTED** ,init为是否初始化,初始化则全部填充,否则只填充updateId、updateTime、sortName。
默认取方法的第一个参数进行填充,支持单个实体,也支持List集合。
#### 1.2.2 使用案例
一般@AutoService用于新增方法,以及更新方法
```java
// 新增方法
@AutoService
public void add(LdpMcsElementInfo elementInfo) {
genericDaoService.insert(elementInfo);
}
// 更新方法
@AutoService(init = false)
public void update(LdpMcsElementInfo elementInfo) {
genericDaoService.dynamicUpdate(elementInfo);
}
```
### 1.3. @AutoRelativeComputed
依赖:mcs-common
#### 1.3.1 注解介绍
**@AutoRelativeComputed** 是一个方法注解,对使用JPA配置了关联关系实体类进行自动填充,主要作用于Service层,对新增关联和移除关联方法参数进行自动填充。
@AutoRelativeComputed字段详解:
**mode**:关联类型,目前支持RelativeMode.MTM(多对多)、RelativeMode.OTM(一对多)、RelativeMode.MTO(多对一)。**PS:一对多、多对一暂时不建议使用**
**inverse**:是否为逆向,false为单向绑定,true为双向绑定,默认为false。
**source**:参数源类型。
**target**:参数目标类型。
**joinField**:关联字段。
**inverseField**:逆向关联字段。
**exComputed**:扩展的填充字段。
#### 1.3.2 使用案例
##### 1). 多对多关系
这里举例为用户和角色的多对多关系。
用户表(user):
| 字段名称 | 类型 | 备注 |
| --------- | ------ | ---------------- |
| id | String | 用户ID,唯一标识 |
| user_name | String | 用户名 |
角色表(role):
| 字段名称 | 类型 | 备注 |
| --------- | ------ | ---------------- |
| id | String | 角色ID,唯一标识 |
| role_name | String | 角色名称 |
用户角色关联表(user_role):
| 字段名称 | 类型 | 备注 |
| -------- | ------ | ------------ |
| id | String | ID,唯一标识 |
| user_id | String | 用户ID |
| role_id | String | 角色ID |
1. 使用JPA配置实体类关联关系
**User.java**
```java
/**
* 与角色的多对多关联
*/
@JsonIgnoreProperties("userInfos")//避免互相关联死循环
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", //中间表的名称
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
private Set<Role> roleInfos = new HashSet<>();
```
**Role.java**
```java
@JsonIgnoreProperties("roleInfos")
@ManyToMany(mappedBy = "roleInfos", fetch = FetchType.EAGER, targetEntity = User.class)
private Set<User> userInfos = new HashSet<>(0);
```
2. **UserServiceImpl**中添加方法和注解
```java
/**
* 添加角色关联
*
* @param id 用户ID
* @param list 通过注解将List<Role>转换为List<UserRole>
* @param param 作为删除条件,避免重复数据
*/
@AutoRelativeComputed(mode = RelativeMode.MTM, source = Role.class, target = UserRole.class, joinField = "userId", inverseField = "roleId")
public void addRoleToUser(String id, List list, Map<String, Object> param) {
LinkedList<TranscationEntity> entityList = new LinkedList<>();
// 删除重复数据
entityList.add(new TranscationEntity(TransItemExeType.DELETE_ENTITY, UserRole.class, param));
// 新增
entityList.add(new TranscationEntity(TransItemExeType.INSERT_ENTITY, list));
genericDaoService.executeTrans(entityList);
}
/**
* 移除角色关联
*
* @param id 用户ID
* @param list 通过注解将List<Role>转换为List<UserRole>
* @param param 作为删除条件,避免重复数据
*/
@AutoRelativeComputed(mode = RelativeMode.MTM, source = Role.class, target = UserRole.class,joinField = "userId", inverseField = "roleId")
public void removeRoleFromUser(String id, List list, Map<String, Object> param) {
genericDaoService.deleteList(UserRole.class, param);
}
```
#### 1.3.3 扩展填充算法
**@AutoRelativeComputed** 注解主要填充中间关联数据,有部分数据和关联无关,但是又必须填充,这种时候就需要 **exComputed** 来扩展填充算法,可以通过算法来填充其它字段。例如,岗位和组织多对多关联自动填充, exComputed字段值为**orgPosition**
```java
@AutoRelativeComputed(mode = RelativeMode.MTM, source = LdpMcsOrganization.class, target = LdpMcsPositionOrganization.class,joinField = "postId", inverseField = "orgId", exComputed = "orgPosition")
```
编写扩展算法需要实现 **CustomComputer** 接口,并在computed方法中编写自动填充逻辑。computed方法有一个参数,这个参数是注解中target类的对象,可以在方法中拿到对象,并对对象中的其它字段进行填充。这里对manager字段进行填充:
```java
public class ComputerOrgPosition implements CustomComputer {
@Override
public void computed(Object target) {
LdpMcsPositionOrganization positionOrganization = (LdpMcsPositionOrganization) target;
positionOrganization.setManager(false);
}
}
```
在有 **@Configuration** 注解类中完成Bean的装配:
```java
@Configuration
public class ExtraComputer {
/**
* 关联表其它业务数据填充
*
* @return
*/
@Bean(name = "orgPosition")
public CustomComputer getUserPositionComputer() {
return new ComputerOrgPosition();
}
}
```
## 二 、缓存注解
### 2.1. @ApplicationCacheable
依赖:common-cache
#### 2.1.1 注解介绍
**@ApplicationCacheable** 注解是方法注解,将注解添加到方法上,会自动将方法结果缓存下来,之后再次调用此接口,会直接从缓存中获取结果。缓存key是自动生成的,生成算法为application:+包名+类名+方法名+:参数长度。其它属性字段与Spring cache 注解 **@Cacheable** 属性字段一致。
#### 2.1.2 使用案例
一般此注解在REST层使用,需要注意的是Application缓存不会过期,会一直存在,如果需要刷新,需要另外写刷新方法,建议在数据变化较小,数据量大的接口使用。
```java
/**
* rest获取用户分页数据
*
* @return
*/
@GetMapping("/rest/page")
@ApplicationCacheable
public RestResult getListByRest() {
return new RestResult(ResultMsg.SUCCESS, exampleService.getUserListByRest());
}
```
### 2.2. @SessionCacheable
依赖:common-cache
#### 2.2.1 注解介绍
**@SessionCacheable** 注解是方法注解,用法与 **@ApplicationCacheable** 注解基本一致,不一致的地方有两点:1、SessionCache生命周期是跟随登录的,也就是退出登录后失效; 2、缓存key生成规则不一致,生成算法:token:+包名+类名+方法名+:参数长度。
#### 2.2.2 使用案例
退出登录后,Session缓存失效
```java
/**
* jdbc 获取用户list
*
* @param paramMap
* @return
* @throws Exception
*/
@GetMapping("/jdbc/list")
@SessionCacheable
public RestResult getListByJdbc(@RequestParamMap(typeCovertMapping = ExampleUserInfo.class) Map<String, Object> paramMap) throws Exception {
List<ExampleUserInfo> userInfoList = exampleService.getUserListByJDBC(StringUtils.EMPTY, paramMap);
return new RestResult(ResultMsg.SUCCESS, userInfoList);
}
```
## 三、日志注解
### 3.1. @AvoidRepeatableSubmit
#### 3.1.1 注解介绍
此注解配合定时任务进行使用,在被需要定时任务调用的服务接口上,添加此注解防止接口由于网络波动或其他原因重复调用。
#### 3.2.2 使用案例
```java
@PostMapping(value = "/testExampleJob")
@AvoidRepeatableSubmit
public RestResult testJob(@RequestParam String taskJobId, @RequestBody ExampleUserInfo userInfo){
exampleService.add(userInfo);
return new RestResult(ResultMsg.SUCCESS,"");
}
```
**使用时仅需要在被定时任务调用的接口上添加@AvoidRepeatableSubmit即可**
### 3.2. @SysAuditLog
#### 3.2.1 注解介绍
@SysAuditLog 是一个方法注解,需要放在controller方法上。 会拦截包裹的方法,会根据登陆信息自动获取当前用户。此注解进行被请求方法拦截,获取请求地址、请求参数、请求内容、请求方法(GET OR POST)、客户端浏览器信息。
根据请求状态,判断是异常请求还是正常请求。
#### 3.2.2 使用案例
```java
/**
* 用户列表(非分页)
*
* @param paramMap 字段条件
* @return
*/
@GetMapping("/get/list")
@SysAuditLog(moduleKey = "example",subKey = "test")
public RestResult findList(@RequestParamMap(typeCovertMapping = ExampleUserInfo.class) Map<String, Object> paramMap) throws Exception {
List<ExampleUserInfo> userInfoList = exampleService.findList(paramMap);
return new RestResult(ResultMsg.SUCCESS, userInfoList);
}
```
**使用时需传递 moduleKey(模块名称,如果是新模块需提前建立表,以ldp_audit_log_ 开头+ modulekey 录入的值结尾的表 如ldp_audit_log_example , 表结构可参考 ldp_audit_log_sys), subKey 子模块名称最终会保存在日志中作为二级子模块**;
### 3.3. @SysJobLog
#### 3.3.1 注解介绍
由于系统架构为微服务,服务与服务之间解耦合。因此定时任务设计之初,考虑为定时接口任务调用。
定时任务执行接口调用, 在被调用接口引用的Service具体业务方法添加此@SysJobLog 注解。
注解包含两大功能,1 异步执行,防止接口执行时间过长,否则定时任务调用机器一直连接被占用; 2 更新定时任务执行情况。
定时任务执行流程:
1 定时任务调度服务启动后,满足定时条件自动执行任务调度。 根据后台配置好的服务名称、接口信息调用其他服务接口。
2 被调用接口,必须添加@RequestParam String taskJobId 作为接收参数,此参数后续作为更新任务执行状态使用。由于在业务方法上添加@SysJobLog, 业务方法与Controller不在同一个线程中,无法
获取上一个线程中的信息。因此具体业务Service也必须添加名称为String taskJobId 的参数,后续会自动获取参数的值进行更新任务执行情况。
3 被调用接口也必须添加 @AvoidRepeatableSubmit 防止重复执行
#### 3.3.2 使用案例
Controller
```java
@PostMapping(value = "/testExampleJob")
@AvoidRepeatableSubmit
public RestResult testJob(@RequestBody ExampleUserInfo userInfo, @RequestParam String taskJobId){
exampleService.doJob (userInfo, taskJobId);
return new RestResult(ResultMsg.SUCCESS,"");
}
```
具体Service
```java
@Override
@AutoService
@SysJobLog
public void doJob(ExampleUserInfo exampleUserInfo, String taskJobId) {
genericDaoService.insert(exampleUserInfo);
}
```
**具体业务方法上添加@SysJobLog 进行异步任务及String taskJobId 参数,名称需要保持一致,系统会自动进行更新执行状态**``
## 四、数据库查询注解
### 4.1. @QueryBind
依赖:common-query
#### 4.1.1 注解介绍
@QueryBind是一个方法注解,将 **xxxxservice-query.xml** 中的参数SQL语句绑定到方法中的第一个参数中。需要先在 **xxxxservice-query.xml** 中将ref属性指向绑定的xxxServiceImpl类中。
#### 4.1.2 使用案例
**Service层代码:**
```java
/**
* jdbc查询, QueryBind所对应的sql语句在resource/query/exampleservice中
* 调用时 getUserListByJDBC(StringUtils.EMPTY); 注解会将sql语句自动注入到参数中
*
* @param sql
* @return
*/
@QueryBind("examplelist")
@Override
public List<ExampleUserInfo> getUserListByJDBC(String sql, Map<String, Object> param) {
List<ExampleUserInfo> exampleUserInfos = jdbcDaoService.queryForList(sql, ExampleUserInfo.class, param);
return exampleUserInfos;
}
```
**REST层代码:**调用时 **getUserListByJDBC(StringUtils.EMPTY)**; 注解会将sql语句自动注入到参数中
```java
Map<String, Object> param = new HashMap<>(1);
param.put("userType", 0);
List<ExampleUserInfo> exampleUserInfos = exampleService.getUserListByJDBC(StringUtils.EMPTY, param);
```
### 4.2. @QueryContextComponent与 @QueryParams
依赖:common-query
#### 4.2.1 注解介绍
**@QueryContextComponent**是一个类注解, **@QueryParams** 是一个方法注解。除了使用 **@QueryBind** 注解注入sql到参数中,还可以使用 **@QueryContextComponent** 结合 **@QueryParams** 注解将xml中的sql全部注入到一个Map对象中。
#### 4.2.2 使用案例
首先在类名上添加 **@QueryContextComponent** 注解,定义一个sqlMap字段,加上 **@QueryParams** 注解,由于 **@QueryParams** 是一个方法注解,所以需要在字段上加上 **@Setter** ,这样会自动生成set方法,注解也会添加到自动生成的方法上
```java
@QueryContextComponent
public class UserBizService {
// 由于@QueryParams是一个方法注解,所以此处需要加上@Setter注解
@Setter
@QueryParams
public Map<String,String> sqlMap;
public void getSqlKey() {
sqlMap.forEach((k,v)->{
log.info("id:{} {} {} ",k,String.format("%n"),v);
});
}
}
```
## 五、REST层参数解析注解
### 5.1. @RequestParamMap
依赖:mcs-common
#### 5.1.1 注解介绍
**@RequestParamMap**是一个参数注解,主要用于在REST层接收GET参数时保持参数类型与实体类一致,可以直接将GET参数接收到的map作为查询条件,另外也是为了将分页参数从查询参数中区分开来。
#### 5.1.2 使用案例
直接在Map参数前使用**@RequestParamMap(typeCovertMapping = XXXX.class)**,这里的XXX指实体类类型。
```java
/**
* 用户列表(非分页)
*
* @param paramMap 字段条件
* @return
*/
@GetMapping("/get/list")
public List<LdpMcsUserInfo> findList(@RequestParamMap(typeCovertMapping = LdpMcsUserInfo.class) Map<String, Object> paramMap) throws Exception {
return userService.findList(paramMap);
}
```
### 5.2 @RequestParamPage
依赖:mcs-common
#### 5.2.1 注解介绍
**@RequestParamPage**是一个参数注解,主要用于GET请求时接收分页参数。
#### 5.2.2 使用案例
使用封装好的分页类 **Pagination** 来接收分页参数,在分页参数前添加 **@RequestParamPage** 即可。这里是将分页参数和查询参数进行拆分的案例:
```java
/**
* 用户列表(分页)
*
* @param paramPage 分页参数为pageIndex,pageSize
* @param paramMap 字段条件
* @return
*/
@GetMapping("/get/page")
public Pagination findPage(@RequestParamPage Pagination paramPage,
@RequestParamMap(typeCovertMapping = LdpMcsUserInfo.class) Map<String, Object> paramMap)
throws Exception {
return userService.findPage(paramPage, paramMap);
}
```
## 六、Excel导入导出注解
### 6.1. @ExcelImport
依赖:common-biz-annotation
#### 6.1.1 注解介绍
**@ExcelImport** 是一个方法注解,主要用于实现Excel导入逻辑。
#### 6.1.2 使用案例
将注解直接加到导入方法上,会自动构建ExcelOptions参数。
```java
/**
* 通过注解导入Excel,注解完成三件事情:
* 1、上传文件
* 2、读取Excel数据
* 3、根据实体类导入到指定的表中
*
* @param file
* @param excelOptions
*/
@ExcelImport(targetClass = ExampleUserInfo.class)
public void importExcelByAnnotation(MultipartFile file, ExcelOptions excelOptions) {
excelService.importExcel(excelOptions);
}
```
### 6.2. @ExcelExport
依赖:common-biz-annotation
#### 6.2.1 注解介绍
**@ExcelExport** 是一个方法注解,主要用于实现Excel导入逻辑。
#### 6.2.2 使用案例
将注解直接加到导出方法上,会自动构建ExcelOptions参数。
```java
/**
* 通过注解导出Excel,注解完成两件事情:
* 1、读取数据库数据
* 2、写入到Excel文件中
*
* @param outputStream
* @param excelOptions
*/
@Override
@ExcelExport(sourceClass = ExampleUserInfo.class)
public void exportExcelByAnnotation(OutputStream outputStream, ExcelOptions excelOptions) {
excelService.exportExcel(excelOptions);
}
```
## 七、模糊查询注解
### 7.1. @HqlQueryFilter
依赖:common-biz-annotation
#### 7.1.1 注解介绍
**@HqlQueryFilter** 是一个字段注解,主要用于标识实体类字段作为列表过滤字段时,数据库查询的匹配方式。目前仅包含精确匹配(QueryFilterType.EQUAL)、模糊匹配(QueryFilterType.ELIKE)
#### 7.1.2 使用案例
在过滤字段上加上注解,以及匹配方式
```java
/**
* 名称
*/
@HqlQueryFilter(type = QueryFilterType.LIKE)
@Column(name = "name")
private String name;
```
### 7.1. @HqlQueryFilterService
依赖:common-biz-annotation
#### 7.1.1 注解介绍
**@HqlQueryFilterService** 是一个方法注解,根据实体类字段中的 **@HqlQueryFilter** 规则自动构建查询条件数组LinkedList<Condition>。
#### 7.1.2 使用案例
当Rest层调用此方法时,Aop拦截会通过遍历参数Map,并从实体类中获取相应字段及注解,来构建Condition数组。
```java
@Override
@HqlQueryFilterService(target = ExampleUserInfo.class)
public List<ExampleUserInfo> findListByLikeCondition(Map<String, Object> param, LinkedList<Condition> conditionList) {
return genericDaoService.findByConditions(ExampleUserInfo.class, conditionList);
}
```
## 八、字典对象属性填充注解
### 8.1. @DictProperties
依赖:common-biz-annotation
#### 8.1.1 注解介绍
**@DictProperties** 是一个类注解,通过属性`propertyPref`标识字典项key的前缀,配合工具类DictCommonDto使用,通过构建一个DTO获取相同字典类型下所有的字典value。
#### 8.1.2 使用案例
这里使用读取邮箱配置相关字典值来举例,邮箱服务器相关字典类型编码为**sys.email.code**,其余属性分别为
| 字典项编码 | 备注 |
| -------------- | -------------- |
| email.host | 邮件服务器地址 |
| email.port | 邮件服务器端口 |
| email.account | 发件方账号 |
| email.password | 发件方密码 |
| email.ssl | 是否使用ssl |
第一步,对应字典项编写一个DTO,加上注解 **@DictProperties** ,`propertyPref`指定字典项的前缀,属性名称为除开前缀后的部分,如果有多段名称,需要使用驼峰命名,例:字典项为email.prof.demo时,属性名为profDemo。
```java
@Getter
@Setter
@DictProperties(propertyPref = "email")
public class EmailServerDTO {
private String host;
private String port;
private String account;
private String password;
private String ssl;
private String testEmail;
}
```
第二步,通过字典接口,使用字典类型编码获取字典项列表,并使用工具类对DTO对象进行赋值
```java
//getEmailDictList方法通过sys.email.code获取所有字典项列表
List<DictInfo2> emailDictList = getEmailDictList();
EmailServerDTO serverDTO = new EmailServerDTO();
try {
//通过工具类将值赋值到Dto对象中
serverDTO = DictCommonDto.toDictDto(emailDictList, serverDTO);
} catch (Exception e) {
e.printStackTrace();
}
```
### 8.2. @DictAlias
依赖:common-biz-annotation
#### 8.2.1 注解介绍
**@DictAlias** 是一个字段注解,需要配合**@DictProperties** 使用,由于使用统一的前缀要求属性名称与字典项编码一一对应,使用@DictAlias注解的字段可以不与字典项编码保持一致。
#### 8.2.2 使用案例
第一步仍然是编写DTO类,类似下方案例,没有通用的前缀,所以通过@DictAlias注解指定对应的字典项。
```java
@Setter
@Getter
@NoArgsConstructor
@DictProperties(propertyPref = "")
public class RootCodeDTO {
@DictAlias(name = "org.root.code")
private String orgRoot;
@DictAlias(name = "func.app.root.code")
private String funcRoot;
@DictAlias(name = "func.manage.root.code")
private String manageRoot;
}
```
第二步与8.1.2中的填充方式一致。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment