春-Mongodb存储/取回枚举为INT不串(Spring -Mongodb storing/ret

2019-06-28 06:00发布

我的枚举形式存储在MongoDB中(从C#应用程序)int类型。 现在在Java中,当我试图找回它们,它抛出一个异常(似乎枚举只能从字符串值转换)。 有没有什么办法可以做到这一点?

此外,当我节省一些收藏到MongoDB中(从Java),它枚举值转换为字符串(不是他们的价值/基数)。 是否有任何超越可用?

这可以通过在类级别写MongoDB的转换器来实现,但是我不想写mondodb转换器为每个类,因为这些枚举在许多不同的班级。

我们这样做对现场级的东西吗?

Answer 1:

在春天,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;   
            }
        }
}

现在对于黑客而言,我personnaly没有找到任何“programmitacly”的方式注册mongoConverter内的转换器工厂,所以我的代码,并用少许铸造挖,这(把这个婴儿2个的函数@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;
    } 


Answer 2:

您将需要实现自定义转换器和弹簧注册。

http://static.springsource.org/spring-data/data-mongo/docs/current/reference/html/#mongo.custom-converters



文章来源: Spring -Mongodb storing/retrieving enums as int not string