前提:使用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;
}
数据库:
返回结果: