V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
gancl
V2EX  ›  MySQL

阿里巴巴 Java 开发规范:货币金额,均以最小货币单位且整型类型来进行存储, 和前端的交互也用整形吗?

  •  
  •   gancl · 2021-10-19 11:39:35 +08:00 · 4765 次点击
    这是一个创建于 1127 天前的主题,其中的信息可能已经有所发展或是发生改变。

    和前端的交互也用整形吗? 我们现在内部是给前端用元, 存数据库用分单位.

    如果忘记转换, 差的就是 100 倍的价格, 用 BigDecimal 差的就是 1 分钱的价格, 两个相比较起来, 还不如用 BigDecimal

    在微服务内部互相调用, 返回的价格应该和给前端的是一样的, 会转了又转

    想问下这个规则要怎么使用?

    27 条回复    2024-01-04 22:03:11 +08:00
    EarthChild
        1
    EarthChild  
       2021-10-19 11:41:30 +08:00
    阿里巴巴又不是王法,问你客户去。
    gancl
        2
    gancl  
    OP
       2021-10-19 11:43:04 +08:00
    @EarthChild 有好的就用,如果不好就不用. 所以想问下哪种做法比较好
    liprais
        3
    liprais  
       2021-10-19 11:43:09 +08:00   ❤️ 1
    不用 decimal 就是给自己找不愉快
    wolfie
        4
    wolfie  
       2021-10-19 11:43:43 +08:00
    不是有测试环节吗。
    keshawnvan
        5
    keshawnvan  
       2021-10-19 11:44:40 +08:00   ❤️ 2
    注意描述:“来进行存储”
    lagoon
        6
    lagoon  
       2021-10-19 11:46:47 +08:00   ❤️ 1
    想起之前某次面试,问到类似货币处理的问题,我答使用整型储存,面试官表示这有问题。

    我问我们这么做,但暂未发现有什么问题,能请教一下会有什么问题吗?

    对方表示反正就是有问题。

    我觉得用整型挺好,这种规范还可以全面统一。用 BigDecimal ?全世界只有一种语言:Java !非 Java 不是编程语言!
    NULL2020
        7
    NULL2020  
       2021-10-19 12:22:36 +08:00
    时刻提醒自己要转换就行了。

    我司也是这样做(我说了算),数据库存分,代码里转成(元)字符串的格式,前端传过来也是字符串(元)
    BBCCBB
        8
    BBCCBB  
       2021-10-19 12:23:52 +08:00
    整形性能高啊.
    AoEiuV020
        9
    AoEiuV020  
       2021-10-19 12:24:10 +08:00
    为什么会把“如果忘记转换”纳入考量,这种必须消灭的 bug 来决定设计不奇怪吗,
    钱的东西一分都不能差,整数比较容易控制每一分钱,毕竟拆开再合起来是严格相等的,
    前端的话我觉得最好是返回一样的整数让前端自己转换,除非是纯展示,就直接转换返回需要展示的字符串,
    jackmod
        10
    jackmod  
       2021-10-19 12:24:32 +08:00
    整数也好,不过最小货币单位不一定是分
    gancl
        11
    gancl  
    OP
       2021-10-19 13:08:02 +08:00
    obj.setRechargePrice(AmountConversionUtil.strCentToYuan(obj.getRechargePrice()));
    obj.setComplimentaryPrice(AmountConversionUtil.strCentToYuan(obj.getComplimentaryPrice()));
    obj.setRechargeSurplusPrice(AmountConversionUtil.strCentToYuan(obj.getRechargeSurplusPrice()));
    obj.setComplimentarySurplusPrice(AmountConversionUtil.strCentToYuan(obj.getComplimentarySurplusPrice()));
    请问下这种怎么用一个类似这种写法:
    LambdaQueryWrapper<Dict> lqw = Wrappers.<Dict>query().lambda()
    .eq(Dict::getCode, dict.getCode())
    来写?一不小心就左右两边写错方法了
    @NULL2020
    zzzmode
        12
    zzzmode  
       2021-10-19 13:24:01 +08:00
    然而支付宝自己开放平台下单接口金额好像就是元为单位的😂
    gancl
        13
    gancl  
    OP
       2021-10-19 13:46:22 +08:00
    还有个问题, entity 是 int 类型, vo 是 string 类型, BeanUtil.copy 时是复制不过来的,这个要怎么注意? @AoEiuV020 @NULL2020
    siweipancc
        14
    siweipancc  
       2021-10-19 13:50:13 +08:00 via iPhone
    @gancl hutool 包应该可以隐性 cast
    l00t
        15
    l00t  
       2021-10-19 13:58:08 +08:00
    和前端交互用字符串,还能带个货币单位出来。
    Jooooooooo
        16
    Jooooooooo  
       2021-10-19 14:12:25 +08:00
    大家都用整型方便.
    NULL2020
        17
    NULL2020  
       2021-10-19 14:13:44 +08:00
    BeanUtil.copy 时是复制不过来的
    --- 手动赋值啰,都手动转换了,还差这点功夫吗?
    shellus
        18
    shellus  
       2021-10-19 14:29:07 +08:00
    用整数分为单位没有解决任何问题,反而增加了一些问题
    1:一个系统原本设计商品的价格单位为 0.00 精度,但是后期需求改为 0.0000
    2:给代码各处的储存获取,传递处增加很多无谓的复杂性,创造了更多犯错的机会
    gam2046
        19
    gam2046  
       2021-10-19 14:42:22 +08:00   ❤️ 3
    用最小计量单位作为整型存储,可以避免一些不可预期的精度丢失,尤其是需要对账的时候。

    例如订单金额 100,用户使用优惠券 12.34 ,实付 87.66 ,后期发生部分退款 20,实际需要退款的金额大约为 17.532 ,以分存储即最多损失 1 分,而 BigDecimal 仅存在于 Java,跨语言时,通常还需要转换,最后可能还是转换成了以分为单位。
    pengtdyd
        20
    pengtdyd  
       2021-10-19 16:08:20 +08:00
    我怎么记得 java 开发开发手册里面是说:涉及到金额的要用 Decimal 或者整数和小数分开存储
    opengps
        21
    opengps  
       2021-10-19 22:17:14 +08:00
    前阵子对结果微信支付和支付宝支付,这俩:一个是以分为单位的整数,一个是以 2 位小数点为规范的小数。
    IvanLi127
        22
    IvanLi127  
       2021-10-20 15:58:51 +08:00
    好好的 Decimal 不用,多辜负这个数据类型。。。。如果要整数的话,那就看你们后端愿不愿意把这个特性暴露给前端了。反正后端不处理的话,最后前端兜底呗。

    话说有啥语言没办法封装一个可靠的计算库来计算有限小数位的小数?
    gancl
        23
    gancl  
    OP
       2021-11-02 10:34:32 +08:00
    @AoEiuV020 @NULL2020 请问下微服务内部 feign 调用返回的要用分还是元?
    NULL2020
        24
    NULL2020  
       2021-11-02 10:43:39 +08:00
    @gancl #23 根据自己业务具体问题具体分析啊,跟微服务提供者商量
    NULL2020
        25
    NULL2020  
       2021-11-02 10:45:04 +08:00
    数据库存整数类型,是为了方便有时候 SQL 查询时需要做运算,自己在代码层面做好转换就行了
    chenzheyu
        26
    chenzheyu  
       2021-11-04 09:57:01 +08:00   ❤️ 1
    google ads api 是用 bigint 来存储,1115000000 =》 1115 元
    tyqing
        27
    tyqing  
       319 天前
    如果你的业务分析下来说不出 Long 的弊端也分析不出 BigDecimal 的优势,那么请一定要用 Long 来存储分,我接手了一个烂摊子项目,里面库存数量和商品金额都用 BigDecimal 来计算,真是恶心到了,大量的 BigDecimal 计算带来了极其糟糕的阅读体验和开发体验。
    接手过这种垃圾项目乱用 BigDecimal 之后就知道 Long 是有多美好了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 09:33 · PVG 17:33 · LAX 01:33 · JFK 04:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.