sdbybyd
V2EX  ›  Java

Java enum 数据库存储问题(大家都是存字符串还是数值)

  •  1
     
  •   sdbybyd · Sep 25, 2020 · 6962 views
    This topic created in 2234 days ago, the information mentioned may be changed or developed.

    想问下大家怎么存储 enum 的,是字符串存储还是数值存储? 比如:

    Gender { MALE, FEMALE }

    41 replies  •  2020-09-30 17:30:21 +08:00
    lower
    lower
    Sep 25, 2020
    1
    byte
    lower
    lower
    Sep 25, 2020
    2
    @lower 说错了,bit
    sdbybyd
    sdbybyd
    OP
    Sep 25, 2020
    4
    @lower 你 @ 了自己,bit 指的是数值瞄?
    GM
    GM
    Sep 25, 2020
    5
    以下为我经常使用的做法,定义一个 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);
    }
    }
    }

    ```
    xiangyuecn
    xiangyuecn
    Sep 25, 2020❤️1
    6
    enum 能做的 class 都能做。

    enum 不能做的 class 都能做。

    enum 各种蹩脚规范代码编写约束,本质上还是一个 class,但开头不能放别的东西,气不气人?

    有什么理由用 enum ?没有!
    chana71
    chana71
    Sep 25, 2020
    7
    @huijiewei 你这个是撸了个枚举类吗
    GM
    GM
    Sep 25, 2020
    8
    @xiangyuecn enum 能 switch case,class 能吗?
    GM
    GM
    Sep 25, 2020
    9
    @xiangyuecn
    enum 可以直接 if(user.state == State.INACTIVE) { ... },class 能吗?
    huijiewei
    huijiewei
    Sep 25, 2020
    10
    @GM 我贴的代码可以啊

    user.state == UserState.INACTIVE.getValue()

    即可
    yiyi11
    yiyi11
    Sep 25, 2020 via Android
    11
    啊?不是都存码表的码吗?数据库有码表,1-xxx,2-yyy,其他表存的是码“1”或“2”。枚举定义成 xxx(“1”,“xxx”)。不管哪里的数据都是以码为准,码对应的值是描述解释(或做显示用),枚举仅仅是为了消除代码中的魔法值,跟码表一一对应的。
    GM
    GM
    Sep 25, 2020
    12
    @huijiewei
    enum 存字符串的好处主要是一目了然,不用看着表里的 1 、2 、3 、4 去猜,比较方便。不然就得去代码里找对应文档或注释(碰到那些缺乏注释的项目,会很恶心)。

    PS:多一个 .getValue() 感觉还是很不爽的,不如直接 user.state == UserState.INACTIVE
    baobao1270
    baobao1270
    Sep 25, 2020
    13
    不是 Java,是 .NET ,存 Enum 。数据库里写注释,再说,有 EFCore 基本很少要动数据库
    GM
    GM
    Sep 25, 2020
    14
    @huijiewei 去看了一下你的代码,你这做法不是不行,但是定义、使用太麻烦了,不如 enum 好用。

    我个人是很喜欢 java 的 enum 设计的,用对路了会感觉很好用。事实上,我写 C#项目的时候,还专门弄了一个 Enum 类来模拟 java 的 enum 。
    wdmx007
    wdmx007
    Sep 25, 2020 via Android
    15
    不推荐存数字,也就是 ordinal 。因为这是和枚举各项顺序有关的,有脑抽的调整了顺序就炸了
    lululau
    lululau
    Sep 25, 2020 via iPhone
    16
    存数值也可以不存 ordinal value,可以自定义使用数值型属性的值的,但我认为应该存字符串,就一个原因,只看 db 存的值我就知道当前这条记录是什么状态、类型了
    MarioLuo
    MarioLuo
    Sep 25, 2020 via Android
    17
    直接用字符串,许多框架库(spring, mybatis,...)对枚举默认值处理方式就是字符串
    EminemW
    EminemW
    Sep 25, 2020
    18
    我的 enum 是用来看的。。不存数据库,因为我不知道怎么比较合理利用
    zsdroid
    zsdroid
    Sep 25, 2020
    19
    @huijiewei 1 为什么不推荐用 ENUM ? 2.你的比 java 自带的好在哪?
    sdbybyd
    sdbybyd
    OP
    Sep 26, 2020
    20
    @GM 这也是我现在在用的方法,就是列举一些值,写个 mybatis 的 converter 转换存储,但是我看了 fb 还有 阿里的很多接口,对外暴露用的字符串,这样 java 的 enum 就简单了,直接命名就行,mybatis 有默认 converter 插入,可能 fb 阿里都有自动化工具转值存储 db
    sdbybyd
    sdbybyd
    OP
    Sep 26, 2020
    21
    @huijiewei 你这个做法应该不行,还不如手撸 converter
    sdbybyd
    sdbybyd
    OP
    Sep 26, 2020
    22
    @xiangyuecn enum 的好处很多,比如类型检查(不是 Integer 数值类型检查),如果你可以直接这么写

    ```java
    public enum Gender {
    MALE,
    FEMALE;
    }
    ```

    而且有自动化工具帮你存储数据库时转换为数值存储,如 1,2,提取时自动转换,这种状态维护起来就简单多了

    我想要的就是这种自动化工具(不用硬编码数值,看了一些 api,fb 和阿里就有这么搞)。
    sdbybyd
    sdbybyd
    OP
    Sep 26, 2020
    23
    @yiyi11 你说的数据库码表指的是?特定数据库类型?还是在 java 上编码的数值映射
    sdbybyd
    sdbybyd
    OP
    Sep 26, 2020
    24
    @MarioLuo 直接用字符串的话,作为索引的时候是不是太浪费了,有没优化方法
    dswyzx
    dswyzx
    Sep 26, 2020 via iPhone
    25
    c#里,enum 是值类型,class 可是引用类型。根本性不同。enum 映射 db 当然是数值类型了。二楼说 bit 的,刚好性别男女是够用了,以后扩展人妖或者啥啥的时候你怎么存
    MarioLuo
    MarioLuo
    Sep 26, 2020 via Android
    26
    @sdbybyd 数据量不高的情况下索性性能差异不大, 而且大多数情况下枚举字段并不适合作为索引列
    MarioLuo
    MarioLuo
    Sep 26, 2020 via Android
    27
    @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()
    }
    binux
    binux
    Sep 26, 2020 via Android
    28
    数据库也用枚举类型不就完了
    huijiewei
    huijiewei
    Sep 26, 2020
    29
    @zsdroid 不用 ENUM 是因为如果数据库里面有 ENUM 不存在的值。API 输出会很麻烦
    huijiewei
    huijiewei
    Sep 26, 2020
    30
    @binux 因为大部分人用 mysql,mysql ENUM 类型坑比较多,现在都不推荐使用 ENUM
    ez728s
    ez728s
    Sep 26, 2020 via Android
    32
    数据库里面应该存储有明确意义的字符串值而不是不知所谓的 1234 数值
    xiangyuecn
    xiangyuecn
    Sep 26, 2020
    33
    @sdbybyd #22 解决硬编码数值(应该叫魔术数值)问题,应当首选常量,而不是 enum,比如 Android 里面的 startActivityForResult 中的 requestCode 这个反人类数值参数,用 enum 当然可以,但不会去用的,基本定义成常量的
    zeroday
    zeroday
    Sep 26, 2020
    34
    直接用 mysql 里的 ENUM 类型. 因为是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。
    如果有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 。
    yiyi11
    yiyi11
    Sep 26, 2020 via Android
    35
    @sdbybyd 数值映射
    tailf
    tailf
    Sep 26, 2020
    36
    数据库不要用 enum,用 tinyint
    skypyb
    skypyb
    Sep 26, 2020
    37
    用 postgres 就没这破事了
    notejava
    notejava
    Sep 26, 2020
    38
    字符串,可读性好
    keenkiller
    keenkiller
    Sep 26, 2020
    39
    tinyint/smallint
    sdbybyd
    sdbybyd
    OP
    Sep 30, 2020
    40
    @MarioLuo 我们目前就是这么做的,但是还是需要定义数值,数值定义不好规范,想要数据库插入就是字符串(实际存储用的数值)这部分对开发者隐藏的同时规避 数据库 enum 类型的缺陷
    MarioLuo
    MarioLuo
    Sep 30, 2020 via Android
    41
    @sdbybyd 那问题就是数字从哪儿来,依赖枚举 ordernal 是不应该的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1555 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 09:30 · PVG 17:30 · LAX 01:30 · JFK 04:30
    ♥ Do have faith in what you're doing.