gpt4 book ai didi

Spring -Mongodb 将枚举存储/检索为 int 而不是字符串

转载 作者:行者123 更新时间:2023-12-02 05:03:06 27 4
gpt4 key购买 nike

我的枚举在 mongodb 中存储为 int(来自 C# 应用程序)。现在在 Java 中,当我尝试检索它们时,它会抛出异常(似乎枚举只能从字符串值转换)。有什么办法可以做到吗?

此外,当我将一些集合保存到 mongodb(来自 Java)时,它会将枚举值转换为字符串(而不是它们的值/基数)。有可用的覆盖吗?

这可以通过在类级别编写 mongodb-converter 来实现,但我不想为每个类编写 mondodb-converter,因为这些枚举位于许多不同的类中。

那么我们在现场层面有什么东西吗?

最佳答案

经过长时间挖掘 spring-mongodb 转换器代码,好的,我完成了,现在它正在工作了:)就在这里(如果有更简单的解决方案,我也会很高兴看到,这就是我所做的):

首先定义:

public interface IntEnumConvertable {
public int getValue();
}

以及一个实现它的简单枚举:

public enum tester implements IntEnumConvertable{   
vali(0),secondvali(1),thirdvali(5);

private final int val;
private tester(int num)
{
val = num;
}
public int getValue(){
return val;
}
}

好的,现在你需要 2 个转换器,一个很简单,另一个则更复杂。简单的(这个简单的婴儿还处理简单的转换,并在无法进行强制转换时返回一个字符串,如果您希望将枚举存储为字符串,并且对于将数字存储为整数的枚举,那么这很好):

public class IntegerEnumConverters {
@WritingConverter
public static class EnumToIntegerConverter implements Converter<Enum<?>, Object> {
@Override
public Object convert(Enum<?> source) {
if(source instanceof IntEnumConvertable)
{
return ((IntEnumConvertable)(source)).getValue();
}
else
{
return source.name();
}
}
}
}

更复杂的,实际上是一个转换器工厂:

public class IntegerToEnumConverterFactory implements ConverterFactory<Integer, Enum> {
@Override
public <T extends Enum> Converter<Integer, T> getConverter(Class<T> targetType) {
Class<?> enumType = targetType;
while (enumType != null && !enumType.isEnum()) {
enumType = enumType.getSuperclass();
}
if (enumType == null) {
throw new IllegalArgumentException(
"The target type " + targetType.getName() + " does not refer to an enum");
}
return new IntegerToEnum(enumType);
}
@ReadingConverter
public static class IntegerToEnum<T extends Enum> implements Converter<Integer, Enum> {
private final Class<T> enumType;

public IntegerToEnum(Class<T> enumType) {
this.enumType = enumType;
}

@Override
public Enum convert(Integer source) {
for(T t : enumType.getEnumConstants()) {
if(t instanceof IntEnumConvertable)
{
if(((IntEnumConvertable)t).getValue() == source.intValue()) {
return t;
}
}
}
return null;
}
}
}

现在对于黑客部分,我个人没有找到任何“programmitacly”方式在 mongoConverter 中注册转换器工厂,所以我深入研究了代码并进行了一些转换,这就是(将这两个婴儿函数放入你的@Configuration类)

      @Bean
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
converters.add(new IntegerEnumConverters.EnumToIntegerConverter());
// this is a dummy registration , actually it's a work-around because
// spring-mongodb doesnt has the option to reg converter factory.
// so we reg the converter that our factory uses.
converters.add(new IntegerToEnumConverterFactory.IntegerToEnum(null));
return new CustomConversions(converters);
}

@Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setApplicationContext(appContext);
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
mongoConverter.setCustomConversions(customConversions());
ConversionService convService = mongoConverter.getConversionService();
((GenericConversionService)convService).addConverterFactory(new IntegerToEnumConverterFactory());
mongoConverter.afterPropertiesSet();
return mongoConverter;
}

关于Spring -Mongodb 将枚举存储/检索为 int 而不是字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12385920/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com