码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 关于MongoDb查询Decimal128转BigDecimal问题


    前提:使用MongoTemplate查询数据库,返回结果类型为Map

    Decimal128是无法转换BigDecimal的,除非你的返回类型中定义了对象中的类型为BigDecimal,那如果无法确定返回值是什么的情况下只能用Map去接返回结束。

    解决方法:

    可以使用jackson对Decimal128进行转换BigDecimal

    我使用的第二种方法:

    改源码。

    MappingMongoConverter中的getPotentiallyConvertedSimpleRead方法

    Checks whether we have a custom conversion for the given simple object. Converts the given value if so, applies {@link Enum} handling or returns the value as is. Can be overridden by subclasses.

    检查给定的简单对象是否有自定义转换。如果是,则转换给定值,并应用

    1. private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class target) {
    2. if (target==null){
    3. return value;
    4. }
    5. //对Decimal128转换为BigDecimal
    6. if (value.getClass() == Decimal128.class){
    7. return ((Decimal128) value).bigDecimalValue();
    8. }
    9. if (ClassUtils.isAssignableValue(target, value)) {
    10. return value;
    11. }
    12. if (conversions.hasCustomReadTarget(value.getClass(), target)) {
    13. return doConvert(value, target);
    14. }
    15. if (Enum.class.isAssignableFrom(target)) {
    16. return Enum.valueOf((Class) target, value.toString());
    17. }
    18. return doConvert(value, target);
    19. }

    左边是未修改的代码,因为我是使用Map接的结果,所以类型都是Object,而在还没有检查是否有自定义转换的时候就出现了误区,因为在之前先调用了ClassUtils.isAssignableValue方法

    来自ClassUtils.java

    1. public static boolean isAssignableValue(Class type, @Nullable Object value) {
    2. Assert.notNull(type, "Type must not be null");
    3. return (value != null ? isAssignable(type, value.getClass()) : !type.isPrimitive());
    4. }

     Determine if the given type is assignable from the given value, assuming setting by reflection.

    确定给定的类型是否可以从给定的值赋值,假设由反射设置。认为原始封装类可赋值给相应的原始类型。

    所以右边的代码改为只要value是Decimal128就去强转调取Decimal128的bigDecimalValue()

    BigDecimal转Decimal128很简单,写一个配置类,并让MongoTemplate去加载即可,

    1. @ReadingConverter
    2. public class BigDecimalToDecimal128Converter implements Converter {
    3. @Override
    4. public Decimal128 convert(BigDecimal bigDecimal) {
    5. return new Decimal128(bigDecimal);
    6. }
    7. }
    1. private static MongoConverter getDefaultMongoConverter(MongoDatabaseFactory factory) {
    2. DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
    3. //增加对BigDecimalToDecimal28的转换
    4. List list = new ArrayList<>();
    5. list.add(new BigDecimalToDecimal128Converter());
    6. MongoCustomConversions conversions = new MongoCustomConversions(list);
    7. MongoMappingContext mappingContext = new MongoMappingContext();
    8. mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
    9. mappingContext.afterPropertiesSet();
    10. MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext);
    11. converter.setCustomConversions(conversions);
    12. converter.setCodecRegistryProvider(factory);
    13. converter.afterPropertiesSet();
    14. return converter;
    15. }
    16.  数据库:

       返回结果:

       

       

       

    17. 相关阅读:
      Ardupilot — AP_OpticalFlow代码梳理
      GPT接入飞书
      IBM Spectrum LSF Application Center 提供单一界面来管理应用程序、用户、资源和数据
      LeetCode 1624. 两个相同字符之间的最长子字符串
      文本关键信息抽取-面向复杂文本结构的实体关系联合抽取研究(论文研读)(一)
      Vue异步更新机制、$nextTick实现同步更新
      linux-常用命令
      01|JVM类加载机制
      Operator介绍
      mikumikumoving 一些插件记录
    18. 原文地址:https://blog.csdn.net/u013600907/article/details/126140856
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | Kerberos协议及其部分攻击手法
        0day的产生 | 不懂代码的"代码审计"
        安装scrcpy-client模块av模块异常,环境问题解决方案
        leetcode hot100【LeetCode 279. 完全平方数】java实现
        OpenWrt下安装Mosquitto
        AnatoMask论文汇总
        【AI日记】24.11.01 LangChain、openai api和github copilot
      • 热门文章
      • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
        奉劝各位学弟学妹们,该打造你的技术影响力了!
        五年了,我在 CSDN 的两个一百万。
        Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
        面试官都震惊,你这网络基础可以啊!
        你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
        心情不好的时候,用 Python 画棵樱花树送给自己吧
        通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
        13 万字 C 语言从入门到精通保姆级教程2021 年版
        10行代码集2000张美女图,Python爬虫120例,再上征途
      Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
      正则表达式工具 cron表达式工具 密码生成工具

      京公网安备 11010502049817号