V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
st78even
V2EX  ›  Java

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

  •  
  •   st78even · Jul 10, 2018 · 3991 views
    This topic created in 2859 days ago, the information mentioned may be changed or developed.

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

    关于字典维护,不要轻易改动原来的映射关系
    0 待支付、1 已支付、2 已发货、3 已收货,如果要加一个待发货状态,那应该是:4 待收货
    st78even
        12
    st78even  
    OP
       Jul 10, 2018
    @arthas2234 您说的对,改一次字典后端要重新编译,这个是有点屎
    st78even
        13
    st78even  
    OP
       Jul 10, 2018
    @zydxn 感谢
    wenzhoou
        14
    wenzhoou  
       Jul 10, 2018 via Android
    楼上说的对,前段写一个 genderFormatter。渲染这事儿本来就归前端负责。
    lululau
        15
    lululau  
       Jul 10, 2018
    用枚举
    tonghuashuai
        16
    tonghuashuai  
       Jul 10, 2018
    用枚举啊,或者定义一堆 Const
    st78even
        17
    st78even  
    OP
       Jul 10, 2018
    @wenzhoou 您指的前端是纯用 JS 等脚本技术,还是结合着 Java 的前端渲染的处理。
    wenzhoou
        18
    wenzhoou  
       Jul 10, 2018 via Android
    无论哪种都是。MVC 结构里面这就是 view 层要做的事情。
    @st78even
    xud6
        19
    xud6  
       Jul 10, 2018
    前端用 i18n 框架做
    huoru
        20
    huoru  
       Jul 10, 2018
    刚刚好我解决过这样的问题,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  
       Jul 10, 2018 via iPhone
    让我想到了 Java 架构师的那个段子……
    st78even
        22
    st78even  
    OP
       Jul 10, 2018
    @ETiV 你说什么段子?才疏学浅
    st78even
        23
    st78even  
    OP
       Jul 10, 2018
    @xud6 i18n 指的不是国际化的东西吗?具体是什么框架,贴个地址呗
    xud6
        24
    xud6  
       Jul 10, 2018
    @st78even 这个不是要看前端怎么搞的吗?不同的前端 /前端框架 /语言有不同的库。
    如果是传统的 spring 服务器生成页面可以看看这种 https://www.journaldev.com/2610/spring-mvc-internationalization-i18n-and-localization-l10n-example (我不怎么搞 JAVA,所以只是 google 随便搜的)

    同样的时间,与其花费在造轮子不如直接引入 i18n,同样可以实现服务器信息格式到用户本地语言的转换。
    someonedeng
        25
    someonedeng  
       Jul 11, 2018
    一开始就在数据库存 ‘男’
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   971 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 67ms · UTC 20:08 · PVG 04:08 · LAX 13:08 · JFK 16:08
    ♥ Do have faith in what you're doing.