想问下大家怎么存储 enum 的,是字符串存储还是数值存储? 比如:
Gender { MALE, FEMALE }
1
lower 2020-09-25 18:20:04 +08:00
byte
|
3
huijiewei 2020-09-25 18:20:59 +08:00
|
5
GM 2020-09-25 18:44:08 +08:00
以下为我经常使用的做法,定义一个 enum,enum 里定义好 Json 、Jpa 等转换规则。
仅供参考: ``` @Getter @AllArgsConstructor public enum State { UNKNOWN("未知"), ACTIVE("正常"), INACTIVE("封禁"), ; private final String desc; @JsonCreator public static State fromStr(String strValue) { return Arrays.stream(State.values()).filter(value -> value.value().equals(strValue)).findFirst().orElse(UNKNOWN); } @JsonValue public String value() { return this.name(); } @Converter(autoApply = true) public static class DatabaseColumnConverter implements AttributeConverter<State, String> { public String convertToDatabaseColumn(State state) { return state != null ? state.name() : UNKNOWN.name(); } public State convertToEntityAttribute(String name) { return fromStr(name); } } } ``` |
6
xiangyuecn 2020-09-25 18:49:38 +08:00 1
enum 能做的 class 都能做。
enum 不能做的 class 都能做。 enum 各种蹩脚规范代码编写约束,本质上还是一个 class,但开头不能放别的东西,气不气人? 有什么理由用 enum ?没有! |
8
GM 2020-09-25 19:24:21 +08:00
@xiangyuecn enum 能 switch case,class 能吗?
|
9
GM 2020-09-25 19:25:56 +08:00
@xiangyuecn
enum 可以直接 if(user.state == State.INACTIVE) { ... },class 能吗? |
11
yiyi11 2020-09-25 19:33:30 +08:00 via Android
啊?不是都存码表的码吗?数据库有码表,1-xxx,2-yyy,其他表存的是码“1”或“2”。枚举定义成 xxx(“1”,“xxx”)。不管哪里的数据都是以码为准,码对应的值是描述解释(或做显示用),枚举仅仅是为了消除代码中的魔法值,跟码表一一对应的。
|
12
GM 2020-09-25 19:39:42 +08:00
@huijiewei
enum 存字符串的好处主要是一目了然,不用看着表里的 1 、2 、3 、4 去猜,比较方便。不然就得去代码里找对应文档或注释(碰到那些缺乏注释的项目,会很恶心)。 PS:多一个 .getValue() 感觉还是很不爽的,不如直接 user.state == UserState.INACTIVE |
13
baobao1270 2020-09-25 19:42:20 +08:00
不是 Java,是 .NET ,存 Enum 。数据库里写注释,再说,有 EFCore 基本很少要动数据库
|
14
GM 2020-09-25 19:43:32 +08:00
@huijiewei 去看了一下你的代码,你这做法不是不行,但是定义、使用太麻烦了,不如 enum 好用。
我个人是很喜欢 java 的 enum 设计的,用对路了会感觉很好用。事实上,我写 C#项目的时候,还专门弄了一个 Enum 类来模拟 java 的 enum 。 |
15
wdmx007 2020-09-25 21:18:11 +08:00 via Android
不推荐存数字,也就是 ordinal 。因为这是和枚举各项顺序有关的,有脑抽的调整了顺序就炸了
|
16
lululau 2020-09-25 21:56:41 +08:00 via iPhone
存数值也可以不存 ordinal value,可以自定义使用数值型属性的值的,但我认为应该存字符串,就一个原因,只看 db 存的值我就知道当前这条记录是什么状态、类型了
|
17
MarioLuo 2020-09-25 22:14:36 +08:00 via Android
直接用字符串,许多框架库(spring, mybatis,...)对枚举默认值处理方式就是字符串
|
18
EminemW 2020-09-25 22:40:06 +08:00
我的 enum 是用来看的。。不存数据库,因为我不知道怎么比较合理利用
|
20
sdbybyd OP @GM 这也是我现在在用的方法,就是列举一些值,写个 mybatis 的 converter 转换存储,但是我看了 fb 还有 阿里的很多接口,对外暴露用的字符串,这样 java 的 enum 就简单了,直接命名就行,mybatis 有默认 converter 插入,可能 fb 阿里都有自动化工具转值存储 db
|
22
sdbybyd OP @xiangyuecn enum 的好处很多,比如类型检查(不是 Integer 数值类型检查),如果你可以直接这么写
```java public enum Gender { MALE, FEMALE; } ``` 而且有自动化工具帮你存储数据库时转换为数值存储,如 1,2,提取时自动转换,这种状态维护起来就简单多了 我想要的就是这种自动化工具(不用硬编码数值,看了一些 api,fb 和阿里就有这么搞)。 |
25
dswyzx 2020-09-26 02:06:32 +08:00 via iPhone
c#里,enum 是值类型,class 可是引用类型。根本性不同。enum 映射 db 当然是数值类型了。二楼说 bit 的,刚好性别男女是够用了,以后扩展人妖或者啥啥的时候你怎么存
|
26
MarioLuo 2020-09-26 03:44:14 +08:00 via Android
@sdbybyd 数据量不高的情况下索性性能差异不大, 而且大多数情况下枚举字段并不适合作为索引列
|
27
MarioLuo 2020-09-26 04:13:27 +08:00 via Android
@sdbybyd 枚举增加数值属性, 实现 IntCode 接口,然后为相关的库针对这个接口通用的转换器(mybatis, jpa, spring mvc,...)
enum Gender implement IntCode{ MALE(1), FEMALE(2); private Integer code; public Integer getCode(){ return code; } } interface IntCode{ Integer getCode() } |
28
binux 2020-09-26 05:05:41 +08:00 via Android
数据库也用枚举类型不就完了
|
31
ez728s 2020-09-26 09:06:18 +08:00
|
32
ez728s 2020-09-26 09:12:24 +08:00 via Android
数据库里面应该存储有明确意义的字符串值而不是不知所谓的 1234 数值
|
33
xiangyuecn 2020-09-26 10:29:08 +08:00
@sdbybyd #22 解决硬编码数值(应该叫魔术数值)问题,应当首选常量,而不是 enum,比如 Android 里面的 startActivityForResult 中的 requestCode 这个反人类数值参数,用 enum 当然可以,但不会去用的,基本定义成常量的
|
34
zeroday 2020-09-26 10:58:04 +08:00
直接用 mysql 里的 ENUM 类型. 因为是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。
如果有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 。 |
36
tailf 2020-09-26 12:00:14 +08:00
数据库不要用 enum,用 tinyint
|
37
skypyb 2020-09-26 14:16:29 +08:00
用 postgres 就没这破事了
|
38
notejava 2020-09-26 16:40:00 +08:00
字符串,可读性好
|
39
tairan2006 2020-09-26 17:22:20 +08:00
tinyint/smallint
|