优化java枚举类在数据库持久化、前后端交互时的序列化使用方式

实体类持久化到数据库-枚举属性序列化

1.@EnumValue
2.配置
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

mybatis-plus:typeEnumsPackage: xxx
实体类中枚举属性自动转为@EnumValue标记的属性值

从数据库查实体类-枚举属性反序列化

1.@EnumValue
2.配置mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

mybatis-plus:typeEnumsPackage: xxx
数据库中属性值,自动转换为实体类中的枚举属性(对象)
在这里插入图片描述

服务端接口返回前端-枚举属性序列化

  • 1.@JsonSerialize(using = ToStringSerializer.class)
    实体类的枚举属性序列化为toString方法,可自定义返回json,如:
    { "code": 0, "msg": null, "data": { "id": null, "testEnum": "{code:1, desc:'a'}" } }
    注意testEnum的值是字符串
  • 2.@JsonFormat(shape = JsonFormat.Shape.OBJECT)
    import com.fasterxml.jackson.annotation.JsonFormat;
    在枚举类上使用此注解,返回前端的是json对象
    在这里插入图片描述

{ "code": 0, "msg": null, "data": { "id": null, "testEnum": { "code":1, "desc":'a' } } }
注意testEnum的值是json对象
返回json对象,前端接到后处理更方便,推荐此种方式

前端调用服务端接口-枚举属性反序列化

通过json传枚举值到接口中自动转换为对象的枚举属性
@RequestBody TestEnumEntity testEnumEntity
@JsonDeserialize(using = BaseEnumDeserializer.class)

附上代码:

  • 枚举公共接口
    在这里插入图片描述
  • 枚举
    在这里插入图片描述
  • 实体类
    在这里插入图片描述
  • 枚举反序列化器
public class BaseEnumDeserializer extends JsonDeserializer {

    @Override
    public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        JsonNode value = jsonParser.getCodec().readTree(jsonParser);
        String currentName = jsonParser.currentName();
        Object currentValue = jsonParser.getCurrentValue();
        Class findPropertyType = BeanUtils.findPropertyType(currentName, currentValue.getClass());
        if (findPropertyType.isEnum()) {
            BaseEnum[] enumConstants = (BaseEnum[]) findPropertyType.getEnumConstants();
            for (BaseEnum e : enumConstants) {
                if (e.getValue().toString().equals(value.asText())) {
                    return e;
                }
            }
        }
        return null;
    }
}
  • 测试接口
@Slf4j
@RestController
@RequestMapping("/test/enum")
public class TestEnumController {

    @Autowired
    TestEnumEntityMapper testEnumEntityMapper;

    @RequestMapping("/save")
    public R<String> save() {
        TestEnumEntity testEnumEntity = new TestEnumEntity();
        testEnumEntity.setTestEnum(TestEnum.A);
        int insert = testEnumEntityMapper.insert(testEnumEntity);
        return R.ok("insert:" + insert);
    }

    @RequestMapping("/get")
    public R<String> get() {
        TestEnumEntity testEnumEntity = testEnumEntityMapper.selectById(1603210329657991170L);
        return R.ok("get:" + testEnumEntity.toString());
    }

    @RequestMapping("/queryWrapper")
    public R queryWrapper() {
        LambdaQueryWrapper<TestEnumEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TestEnumEntity::getTestEnum, TestEnum.A);
        return R.ok(testEnumEntityMapper.selectList(wrapper));
    }

    @RequestMapping("/querySql")
    public R querySql() {
//        return R.ok(testEnumEntityMapper.selectByEnumCode(TestEnum.A));//ok
        TestEnumEntity testEnumEntity = new TestEnumEntity();
        testEnumEntity.setTestEnum(TestEnum.B);
        return R.ok(testEnumEntityMapper.selectByEntity(testEnumEntity));//OK
    }

    @RequestMapping("/getEnum")
    public R<TestEnumEntity> getEnum() {
        TestEnumEntity testEnumEntity = new TestEnumEntity();
        testEnumEntity.setTestEnum(TestEnum.A);
        return R.ok(testEnumEntity);
    }

    @RequestMapping("/saveEnum")
    public R saveEnum(@RequestBody TestEnumEntity testEnumEntity) {
        System.out.println(testEnumEntity);
        return R.ok(testEnumEntity);
    }

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
protobuf,即Protocol Buffers,是由Google提供的一种数据序列化协议,可以用于结构化的数据存储以及交换。它类似于JSON,但通常能提供更高效的数据传输效率,并支持多种编程语言。 序列化过程简而言之就是将复杂的数据结构转换成字节流的过程,以便于在网络上传输或者持久化存储;而反序列化则是将字节流还原回原来的数据结构的过程。 以下是protobuf序列化过程的基本步骤: ### 1. 定义消息 首先,你需要定义你想要序列化的数据结构。这通过创建.proto文件完成,在该文件中你可以定义各种字段、消息、枚举等。例如: ```proto message User { string name = 1; int32 age = 2; } ``` 在这个例子中,我们定义了一个`User`消息,包含两个字段:一个字符串类型的`name`和一个整数类型的`age`。 ### 2. 编译.proto 文件 一旦有了.proto文件,你需要使用protobuf的编译器protoc将它们转化为特定编程语言的目标代码。比如对于Java,运行以下命令: ```bash protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/User.proto ``` 这会生成Java源代码文件,里面包含了序列化和反序列化的功能。 ### 3. 创建并填充消息实例 在目标语言中,你将根据生成的代码创建`User`消息实例,并填充相应的数据。例如,在Java中: ```java User user = new User(); user.setName("Alice"); user.setAge(30); ``` ### 4. 序列化 之后,你可以使用生成的代码将消息实例转换为二进制形式。对于Java的例子,你可以这样做: ```java ByteString bytes = user.toByteArray(); ``` 这里得到了一个`ByteString`对象,包含了`User`消息的所有数据编码为字节数组。 ### 5. 发送和接收 然后,这个字节流就可以在网络上发送了。在接收到端,你可以从字节流中解析出原来的`User`消息: ```java User receivedUser = User.parseFrom(bytes); System.out.println(receivedUser.getName()); ``` ### 相关问题: 1. **如何自定义protobuf的消息类型?** - 在.proto文件中添加新的消息类型定义即可,包括添加新的字段、嵌套其他消息等。 2. **protobuf相比于JSON有哪些优势?** - 性能更好,因为它是二进制格式而不是文本格式,解码更快。 - 空间占用更少,尤其是在处理大量重复数据。 - 支持选项和验证规则,使得序列化的数据更容易保持一致性。 3. **protobuf是否适用于所有应用?** - 虽然广泛应用于服务通信和数据存储,但在需要高度动态性和频繁变更的应用场景下,如前端Web交互,JSON可能是更好的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值