Java中使用枚举(enum)还是常量?枚举! 您所在的位置:网站首页 接口中使用枚举 Java中使用枚举(enum)还是常量?枚举!

Java中使用枚举(enum)还是常量?枚举!

2024-06-24 02:37| 来源: 网络整理| 查看: 265

这里先说结论:对于一组关联的数值,出于对数据安全的考虑,我们选择使用enum。

问题

定义表结构的时候经常会碰到一类字段:状态 ( status 或者 state ) 、类型 ( type ) ,而通常的做法一般是:

数据库 中定义 tinyint 类型。 比如:status tinyint(1) NOT NULL COMMENT ‘订单状态 1-待支付;2-待发货;3-待收货;4-已收货;5-已完结;’Java 实体类 中定义 Short 类型。 比如:private Short status

然后项目中可能会充斥着下面这样的代码:

order.setStatus((short) 1); if (order.getStatus() == 1) { order.setStatus((short) 2); } if (order.getStatus() == 4) { order.setStatusName("已收货"); }

这都是些什么魔鬼数字啊,没有注释根本没法看,如果手滑可能状态就设错了,而且不好排查是在哪处赋值的。

改进方案是用 常量 ,但是又会产生另一种效果:

public static final Short WAIT_PAY = 1; if (WAIT_PAY.equals(order.getStatus())) { // 混用了解下 order.setStatus((short) 2); }

定义常量对使用者没有约束力,仍然可能会被程序员无视,而直接使用数字。

这时候就该 枚举 出场了,枚举 的本质就是 类 + 常量 ,可以使用 枚举 来定义 一组 相关的元数据 ( 值、描述及其他必要信息 ) ,使用 枚举 类型不仅减小了数据维护 ( 比如调整了值的定义 ) 的成本,还加强了代码的 约束力 。

我们在实体类(DO/DTO/BO/VO/PO)和方法参数中,统一使用枚举类型的属性来保存有固定取值的字段。

要做到上面这一点,有下面三个地方要注意

把接口的参数转化为枚举类型把接口返回的枚举类型转为String把枚举类型保存到数据库中 把接口的参数转化为枚举类型

Spring 默认使用Bean接收枚举参数时支持 字面量,这也是我们常见的做法。

如下:

@Data public class UserCommand { private String name; private Gender gender; private String email; } @ApiOperation("添加用户") @PostMapping("/users") public User users(User command){ User user = new User(); BeanUtils.copyProperties(command,user); return user; }

在这里插入图片描述注意这种方式不支持枚举的ordinal值

把接口返回的枚举类型转为String

《阿里巴巴Java开发手册》将接口中枚举的使用分为两类,即 接口参数和接口返回值,并规定: 接口参数可以使用枚举类型,但接口返回值不可以使用枚举类型(包括含枚举类型的POJO对象)。   这个主要是对dubbo等使用tcp协议的rpc接口调用来说的,为了避免序列化异常;对于spring cloud等使用http协议的框架,没有此限制。   jackson 解析枚举 时,默认会返回字面量( MALE,FEMALE)。也可以通过@JsonValue指定要返回的属性:

public enum Gender { MALE(0,"男"),FEMALE(1,"女"),UNKOWN(2,"未知"); private Integer id; private String name; private Gender(Integer id,String name) { this.id = id; this.name = name; } private Gender(Integer id) { this.id = id; } private Gender(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @JsonValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } } 把枚举类型保存到数据库中

MyBatis内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler。

EnumTypeHandler 这是默认的枚举转换器,该转换器将枚举实例转换为实例名称的字符串,即将SexEnum.MALE转换MALE。EnumOrdinalTypeHandler 顾名思义这个转换器将枚举实例的ordinal属性作为取值,即SexEnum.MALE转换为0,SexEnum.FEMALE转换为1。

使用时,修改mapper的xml文件:

INSERT INTO order_test (status) VALUES ( #{orderStatusEnum, typeHandler=com.example.typeHandler.EnumOrderStatusHandler, jdbcType=INTEGER} )

当然,也可以自定义枚举类型转换器,这里不详述。

注意: 保存枚举的ordinal值时,给枚举增加取值要加在最后,在中间插值会导致数据前后不一致。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有