字段序列化
大约 3 分钟
字段序列化
序列化属性:
- serialize: 后端序列化函数 SerializeEnum 或者 自定义序列化函数,默认为serialize.NON(NON或缺省就是JSON)
- 可选值:
- JSON:JSON格式
- XML:XML格式(暂不支持)
- COMMA:逗号分隔格式
- DOT:点分隔格式
- requestSerialize: 前端序列化函数 SerializeEnum 或者 自定义序列化函数,默认为serialize.NON(NON或缺省就是JSON)
数据存储的序列化
使用@Field注解的serialize属性来配置非基础类型属性的序列化与反序列化方式,最终会以序列化后的字符串持久化到存储中。
实现数据存储序列化的举例:
在PetItem中配置两个字段petItemDetails类型为List<PetItemDetail>
和tags类型为List<String>
,并设置为不同的序列化方式,petItemDetails为JSON(缺省就是JSON,可不配),tags为COMMA。同时设置 @Field.Advanced(columnDefinition = "varchar(1024)")
防止序列化后存储过长
@Model.model(PetItemDetail.MODEL_MODEL)
@Model(displayName = "商品详情",summary = "商品详情",labelFields = {"remark"})
public class PetItemDetail extends TransientModel {
public static final String MODEL_MODEL="demo.PetItemDetail";
@Field.String(min = "2",max = "20")
@Field(displayName = "备注",required = true)
private String remark;
@Field(displayName = "备注人",required = true)
private PamirsUser user;
}
@Model.model(PetItem.MODEL_MODEL)
@Model(displayName = "宠物商品",summary="宠物商品",labelFields = {"itemName"})
public class PetItem extends CodeModel{
public static final String MODEL_MODEL="demo.PetItem";
@Field(displayName = "详情", serialize = Field.serialize.JSON, store = NullableBoolEnum.TRUE)
@Field.Advanced(columnDefinition = "varchar(1024)")
private List<PetItemDetail> petItemDetails;
@Field(displayName = "商品标签",serialize = Field.serialize.COMMA,store = NullableBoolEnum.TRUE,multi = true)
@Field.Advanced(columnDefinition = "varchar(1024)")
private List<String> tags;
}
添加字段数据,查看商品数据表,我们可以看到【详情】字段和【商品标签】字段,按指定序列化方式进行存储
字段序列化注意点
- 必须使用
Field#store
属性将字段存储设置为NullableBoolEnum.TRUE
。 - 使用
Field#serialize
属性指定序列化方式,默认为JSON。 - 如把PetItemDetail设置为存储模型,须在PetItem的petItemDetails字段上使用
Field.Relation#store
属性将关联关系存储设置为false。不然会同时存储petItemDetails字段和对应的PetItemDetail表记录
字段序列化方式说明
序列化方式 | 说明 | 备注 |
---|---|---|
JSON | JSON序列化 | 主要用于模型相关类型字段的序列化,是@Field.serialize默认选项 |
DOT | 点拼接集合元素 | |
COMMA | 逗号拼接集合元素 | |
BIT | 按位与,2次幂数求和 | 非@Field.serialize可选项列表,用于二进制枚举序列化不需要配置,由oinone自动推断 |
注册自己的序列化器
注册自己的序列化器(实现pro.shushi.pamirs.meta.api.core.orm.serialize.Serializer
接口), 如oinone的DOT的序列化方式,用type()方法返回值做匹配,serialize和deserialize分别对应序列化和反序列化方法。
package pro.shushi.pamirs.framework.compute.serialize;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.core.orm.serialize.Serializer;
import pro.shushi.pamirs.meta.common.constants.CharacterConstants;
import pro.shushi.pamirs.meta.enmu.SerializeEnum;
import pro.shushi.pamirs.meta.util.TypeUtils;
/**
* 点表达式序列生成处理器实现
*
* @author d@shushi.pro
* @version 1.0.0
* date 2020/3/4 2:48 上午
*/
@SuppressWarnings("rawtypes")
@Slf4j
@Component
public class DotSerializeProcessor implements Serializer<Object, String> {
@Override
public String serialize(String ltype, Object value) {
if (null == value) {
return null;
}
if (List.class.isAssignableFrom(value.getClass())) {
return StringUtils.join((List) value, CharacterConstants.SEPARATOR_DOT);
} else {
return StringUtils.join(Collections.singletonList(value), CharacterConstants.SEPARATOR_DOT);
}
}
@SuppressWarnings("unchecked")
@Override
public Object deserialize(String ltype, String ltypeT, String value, String format) {
if (null == value) {
return null;
}
String[] dots = value.split(CharacterConstants.SEPARATOR_ESCAPE_DOT);
List list = new ArrayList();
for (String dot : dots) {
Object object = TypeUtils.valueOfPrimary(ltypeT, dot, null);
list.add(object);
}
return list;
}
@Override
public String type() {
return SerializeEnum.DOT.value();
}
}
字段默认值的反序列化
用@Field.defaultValue
注解在字段上配置defaultValue属性时,将根据字段的Ttype类型及字段的Ltype等类型属性,自动进行反序列化。包括但不限于以下几种情况:
- OBJ、STRING、TEXT、HTML——保持不变
- BINARY、INTEGER——转换为整数
- FLOAT、MONEY——转换为浮点数
- DATETIME、DATE、TIME、YEAR——根据Field.Date#format属性决定反序列化日期格式
- BOOLEAN——仅允许null、true、false
- ENUM——使用value进行匹配