关于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.

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

	private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class<?> target) {
		if (target==null){
			return value;
		}
        //对Decimal128转换为BigDecimal
		if (value.getClass() == Decimal128.class){
			return ((Decimal128) value).bigDecimalValue();
		}
		if (ClassUtils.isAssignableValue(target, value)) {
			return value;
		}

		if (conversions.hasCustomReadTarget(value.getClass(), target)) {
			return doConvert(value, target);
		}

		if (Enum.class.isAssignableFrom(target)) {
			return Enum.valueOf((Class<Enum>) target, value.toString());
		}

		return doConvert(value, target);
	}

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

来自ClassUtils.java

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

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

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

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

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

@ReadingConverter
public class BigDecimalToDecimal128Converter implements Converter<BigDecimal, Decimal128> {
    @Override
    public Decimal128 convert(BigDecimal bigDecimal) {
        return new Decimal128(bigDecimal);
    }
}
	private static MongoConverter getDefaultMongoConverter(MongoDatabaseFactory factory) {

		DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
		//增加对BigDecimalToDecimal28的转换
		List<Object> list = new ArrayList<>();
		list.add(new BigDecimalToDecimal128Converter());
		MongoCustomConversions conversions = new MongoCustomConversions(list);
		MongoMappingContext mappingContext = new MongoMappingContext();
		mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
		mappingContext.afterPropertiesSet();

		MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext);
		converter.setCustomConversions(conversions);
		converter.setCodecRegistryProvider(factory);
		converter.afterPropertiesSet();

		return converter;
	}

 数据库:

 返回结果:

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值