核心的目标是,用户传递的某个字段的值,在@RequestBody转换后,自动转换成枚举,因为枚举是全局的,所以可以直接赋值给entity的相应字段,然后调用mapper的方法进行入库。
这个过程核心需求解决的问题如下:
- 用户提交数据时,需要将用户提交的值转换成一个枚举
- controller方法是,需要将entity中的枚举的值返回回去
- entity写入到库中时,需要完成枚举到值的转换
- 从库中读取数据到entity时,自动完成值到枚举的转换
提交、查询阶段
request类如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@Data
public class CreateDomainModelRequest {
/**
* 领域ID
*/
private String domainId;
/**
* 模型名
*/
private String modelName;
/**
* 类型
* @see com.sdstc.dyf.meta.common.constant.enums.ModelType#value
*/
@JSONField(serializeUsing = EnumCodec.class, deserializeUsing = EnumCodec.class)
private ModelType modelType;
/**
* 组织ID
*/
private String orgId;
/**
* 注意事项
*/
private String note;
}
|
其中ModelType枚举的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package com.sdstc.dyf.meta.common.constant.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.AccessLevel;
/**
* 类型
*/
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public enum ModelType {
/**
* 系统
*/
SYSTEM("1"),
/**
* 自定义
*/
CUSTOM("3"),
;
@Getter
private String value;
public static ModelType convert(String inputValue) {
for (ModelType enumItem : ModelType.values()) {
if (enumItem.getValue().equals(inputValue)) {
return enumItem;
}
}
throw new RuntimeException("Enum Transfer Wrong.");
}
}
|
入库、出库阶段
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@TableName(value = "t_dyf_domain_model", autoResultMap = true)
public class DomainModelPo extends BasePo {
/**
* 领域ID
*/
private String domainId;
/**
* 模型名
*/
private String modelName;
/**
* 类型
*/
@TableField(typeHandler = ModelTypeTypeHandler.class)
private ModelType modelType;
/**
* 组织ID
*/
private String orgId;
/**
* 注意事项
*/
private String note;
}
|
其中ModelTypeTypeHandler.java的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Slf4j
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ModelTypeTypeHandler extends AbstractEnumTypeHandler<ModelType> {
@Override
protected ModelType parseValue(String inputParam) {
return ModelType.convert(inputParam);
}
@Override
protected String toValue(ModelType isModelRequired) {
return isModelRequired.getValue();
}
}
|
其中AbstractEnumTypeHandler.java的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public abstract class AbstractEnumTypeHandler<T> extends BaseTypeHandler<T> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, toValue(parameter));
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
final Object inputParam = rs.getObject(columnName);
return parseValue(String.valueOf(inputParam));
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
final Object inputParam = rs.getObject(columnIndex);
return parseValue(String.valueOf(inputParam));
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
final Object inputParam = cs.getObject(columnIndex);
return parseValue(String.valueOf(inputParam));
}
protected abstract T parseValue(String inputParam);
protected abstract String toValue(T enumObject);
}
|
参考资料
-
MybatisPlus中@TableField注解的使用
-
https://blog.csdn.net/intersting/article/details/93768803
-
深入解析Spring使用枚举接收参数和返回值机制并提供自定义最佳实践
这部分内容包含了一些知识,但是我这次解决问题并没有使用到这些知识。
-
自定义fastjson对枚举类型的序列化及反序列化过程
有参考该份文档。