sql >> Database teknologi >  >> NoSQL >> MongoDB

Spring -Mongodb gemmer/henter enums som int ikke streng

Efter en lang gravning i spring-mongodb-konverteringskoden, okay, jeg er færdig, og nu virker den :) her er den (hvis der er en enklere løsning, vil jeg også gerne se, det er hvad jeg har gjort) :

først definere :

public interface IntEnumConvertable {
      public int getValue();    
}

og en simpel enum, der implementerer det:

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;
    }
}

Ok, nu skal du nu bruge 2 konvertere, den ene er enkel, den anden er mere kompleks. den simple (denne simple baby håndterer også den simple konverter og returnerer en streng, når cast ikke er muligt, det er fantastisk, hvis du vil have enum gemt som strenge og for enum, der er tal, der skal gemmes som heltal) :

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();
            }               
        }
    }   
 }

den mere komplekse, er faktisk en konverterfabrik:

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;   
            }
        }
}

og nu til hack-delen, jeg fandt personligt ikke nogen "programmerbar" måde at registrere en konverterfabrik i en mongoConverter, så jeg gravede i koden og med lidt casting, her er den (indsæt disse 2 babyfunktioner i din @Configuration klasse)

      @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;
    } 


  1. Sådan skriver du et python-program, der understøtter flere databaser

  2. Hvordan autentificerer Mongolab REST API

  3. Mongodb - skal _id være globalt unik ved sharding

  4. MongoDB :Indekser rækkefølge og forespørgselsrækkefølge skal matche?