V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
st78even
V2EX  ›  Java

数据库数据转换中文的这个问题困扰了很久,一致都没有一个自己满意的答案

  •  
  •   st78even · 2018-07-10 14:32:21 +08:00 · 3366 次点击
    这是一个创建于 2358 天前的主题,其中的信息可能已经有所发展或是发生改变。

    举例: 个人信息表,性别( gender )这个字段 0 或者 1, 0 代表男,1 代表女

    POJO 类

    class Person {
      private String name;
      private Integer gender;
    ... 省略 set/get 方法
    } 
    

    新增的时候通过 html select 方式很容易的实现保存。现在我的问题来了,在页面中需要 显示 性别的时候,需要把 数据库中保存的 0 或者 1 转义成

    这个转义的过程我现在发现有三种方式(有大拿可以分享一下其他的方式):

    1. 是在 view 中类似 jsp 中进行值转换
    2. 数据库中建一个 字典,再写一个字典类,根据 字典的 key 值和 value 值转换中文
    3. 新增一个 PersonVO 类
    class PersonVO extends Person {
      private String genderName;     // 这个是新增的性别转换类
      // 增加 get 方法
      public String getGenderName() {
        return this.gender.equals(new Integer("0")) ? "男":"女";
      }
    }
    

    以上的方法 :

    • 第一个最他妈的笨,不用
    • 第二个对于字典的维护比较关键,一旦哪个字典数据被改了,以前保存的数据显示的数据就可晕菜了,字典的维护称为一个重要的事情,程序写起来麻烦,不采用缓存的话,增加数据库访问量,采用缓存还需要管理新增修改后刷新缓存
    • 第三个这个方式不知道是好是坏

    上述问题不知道是否描述清楚了,请各位大佬给讨论分析一下。

    25 条回复    2018-07-11 01:08:56 +08:00
    liuzhedash
        1
    liuzhedash  
       2018-07-10 14:37:29 +08:00
    第一个确实很笨,但是却简单合理
    WEAlex
        2
    WEAlex  
       2018-07-10 14:40:24 +08:00 via Android
    一般都是选第一个吧。
    st78even
        3
    st78even  
    OP
       2018-07-10 14:40:32 +08:00
    第一个如果改了 新增页面,也同时需要去改 查看页面,工作量有点繁琐,而且前后端不分离,如果前端要提供 json restful 方式的信息,前端还得自己去转义,最好 json 就能直接转义(这个情况下我感觉第三个比较好)
    nulIptr
        4
    nulIptr  
       2018-07-10 14:40:37 +08:00
    不太熟悉 jsp 那套,上学的时候学过一点,pojo 不就是要加 getset 方法的么,再说你这个需求看起来是只读的,根本就没必要取出 0 或者 1,直接从数据库里取出男女就行了
    st78even
        5
    st78even  
    OP
       2018-07-10 14:41:41 +08:00
    我想问问实际项目中大家用的是什么方式?
    nulIptr
        6
    nulIptr  
       2018-07-10 14:44:02 +08:00
    @st78even 只读的报表都直接用 sql 取最终的字符串
    表单的话反正要做个控件,肯定是前端做转换
    st78even
        7
    st78even  
    OP
       2018-07-10 14:45:47 +08:00
    @nulIptr 大哥,你用 dao 取数据到 pojo 的时候,一般的 orm (类似 mybatis )取值都是数据中的实际数值
    nulIptr
        8
    nulIptr  
       2018-07-10 14:51:58 +08:00
    @st78even 那你后端 orm 都用这套了,为啥还要在后端加个转换呢?不如自己撸一个 sql 取数灌到 pojo 里面,你想要什么格式就转成什么格式,比你的第三种方法加个扩展高到不知哪里去了
    st78even
        9
    st78even  
    OP
       2018-07-10 15:03:33 +08:00
    @nulIptr 这不讨论呢吗,您别急,我这不是向大家请教呢吗。第三种方法还有一个情况就是用在数据输出到类似 easyui 或者 bootstrap datatable 里面显示方便,否者还得些好多前台的转换代码
    站在巨人的肩膀看了 阿里巴巴的 java 手册,他们对于 pojo 也分为 DTO,VO,DAO 等等
    zydxn
        10
    zydxn  
       2018-07-10 15:06:42 +08:00
    维护数据字典
    arthas2234
        11
    arthas2234  
       2018-07-10 15:15:16 +08:00
    第一种方法,有用到过,直接让前端做,前端好像写了一个公共组件来翻译
    第二种方法,在做 APP 后端时用到过,可以放到配置文件中加载,加上版本号
    第三种方法,改一次字典后端要重新编译发布,原地爆炸

    关于字典维护,不要轻易改动原来的映射关系
    0 待支付、1 已支付、2 已发货、3 已收货,如果要加一个待发货状态,那应该是:4 待收货
    st78even
        12
    st78even  
    OP
       2018-07-10 15:18:36 +08:00
    @arthas2234 您说的对,改一次字典后端要重新编译,这个是有点屎
    st78even
        13
    st78even  
    OP
       2018-07-10 15:18:47 +08:00
    @zydxn 感谢
    wenzhoou
        14
    wenzhoou  
       2018-07-10 15:20:47 +08:00 via Android
    楼上说的对,前段写一个 genderFormatter。渲染这事儿本来就归前端负责。
    lululau
        15
    lululau  
       2018-07-10 15:21:28 +08:00
    用枚举
    tonghuashuai
        16
    tonghuashuai  
       2018-07-10 15:44:59 +08:00
    用枚举啊,或者定义一堆 Const
    st78even
        17
    st78even  
    OP
       2018-07-10 15:57:18 +08:00
    @wenzhoou 您指的前端是纯用 JS 等脚本技术,还是结合着 Java 的前端渲染的处理。
    wenzhoou
        18
    wenzhoou  
       2018-07-10 16:03:17 +08:00 via Android
    无论哪种都是。MVC 结构里面这就是 view 层要做的事情。
    @st78even
    xud6
        19
    xud6  
       2018-07-10 16:06:12 +08:00
    前端用 i18n 框架做
    ChristopherWu
        20
    ChristopherWu  
       2018-07-10 16:20:09 +08:00
    刚刚好我解决过这样的问题,LOL

    请看: https://yonghaowu.github.io/2018/06/08/mongo_aggregate/

    可以直接在 mongo (其他数据库相信也有这样的功能),在取字段出来的时候,用`$project` 判断 0,1,从而改值。

    如:

    ```
    db.molly.aggregate([
    { $match: { birth: {
    $gt: new ISODate("2012-05-25T02:30:58.937Z"), $lt: new ISODate("2019-05-25T02:30:58.937Z") }
    } },
    {
    $project: {
    PDSuc: { $cond: {
    if: { $or: [ {
    $eq: [true, "$leftPDSuc"]}, {$eq: [true, "$rightPDSuc"]}
    ] }, then: 1, else: 0 } },
    CRSuc: { $cond: {
    if: { $or: [ { $eq: [true, "$leftCRSuc"]}, {$eq: [true, "$rightCRSuc"]} ] },
    then: 1, else: 0 } },
    CelerySuc: { $cond: {
    if: { $or: [ {
    $eq: [true, "$leftCelerySuc"]}, {$eq: [true, "$rightCelerySuc"]}
    ] }, then: 1, else: 0 } },
    },
    },
    { $group: { _id: null,
    all_PDSuc: { $sum: "$PDSuc" }, all_CRSuc: { $sum: "$CRSuc"},
    all_CelerySuc: { $sum: "$CelerySuc" },
    }
    },
    ] )
    ```
    ETiV
        21
    ETiV  
       2018-07-10 16:25:19 +08:00 via iPhone
    让我想到了 Java 架构师的那个段子……
    st78even
        22
    st78even  
    OP
       2018-07-10 17:02:10 +08:00
    @ETiV 你说什么段子?才疏学浅
    st78even
        23
    st78even  
    OP
       2018-07-10 17:04:35 +08:00
    @xud6 i18n 指的不是国际化的东西吗?具体是什么框架,贴个地址呗
    xud6
        24
    xud6  
       2018-07-10 20:04:22 +08:00
    @st78even 这个不是要看前端怎么搞的吗?不同的前端 /前端框架 /语言有不同的库。
    如果是传统的 spring 服务器生成页面可以看看这种 https://www.journaldev.com/2610/spring-mvc-internationalization-i18n-and-localization-l10n-example (我不怎么搞 JAVA,所以只是 google 随便搜的)

    同样的时间,与其花费在造轮子不如直接引入 i18n,同样可以实现服务器信息格式到用户本地语言的转换。
    someonedeng
        25
    someonedeng  
       2018-07-11 01:08:56 +08:00
    一开始就在数据库存 ‘男’
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3103 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:39 · PVG 21:39 · LAX 05:39 · JFK 08:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.