sql >> データベース >  >> NoSQL >> Redis

GenericJackson2JsonRedisSerializerクラスと属性を無視する

    GenericJackson2JsonRedisSerializerを直接伝える方法はありません 一部のフィールドを無視してクラスAをキャストする Bへ 、デシリアライズに必要な戦略を実装できます。

    簡単な例としては、型変換を行うときにマッピングフィールドと無視できるフィールドを登録することが考えられます。

    // Adapted from spring data redis
    public class RqueueRedisSerDes implements RedisSerializer<Object> {
        private ObjectMapper mapper;
    
        @AllArgsConstructor
        @Getter
        class Dataum {
          Class<?> tgtClass;
          String[] ignorableProperties;
        }
    
        private Map<Class<?>, Dataum> classMap = new ConcurrentHashMap<>();
    
        RqueueRedisSerDes() {
          this.mapper = new ObjectMapper();
          this.mapper =
              mapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer()));
          this.mapper = mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
          this.mapper = mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
        }
    
        public void addClassMap(Class<?> source, Class<?> tgt, String[] ignorableProperties) {
          classMap.put(source, new Dataum(tgt, ignorableProperties));
        }
    
        @Override
        public byte[] serialize(Object source) throws SerializationException {
          if (source == null) {
            return SerializationUtils.EMPTY_ARRAY;
          }
          try {
            return mapper.writeValueAsBytes(source);
          } catch (JsonProcessingException e) {
            throw new SerializationException("Could not write JSON: " + e.getMessage(), e);
          }
        }
    
        @Override
        public Object deserialize(byte[] source) throws SerializationException {
          if (SerializationUtils.isEmpty(source)) {
            return null;
          }
          try {
            Object object = mapper.readValue(source, Object.class);
            for (Entry<Class<?>, Dataum> entry : classMap.entrySet()) {
              if (ClassUtils.isAssignable(entry.getKey(), object.getClass())) {
                Dataum dataum = entry.getValue();
                Object tgt = dataum.getTgtClass().newInstance();
                BeanUtils.copyProperties(object, tgt, dataum.getIgnorableProperties());
                return tgt;
              }
            }
            return object;
          } catch (Exception ex) {
            throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
          }
        }
    
        private static class NullValueSerializer extends StdSerializer<NullValue> {
    
          private static final long serialVersionUID = 211020517180777825L;
          private final String classIdentifier;
    
          NullValueSerializer() {
            super(NullValue.class);
            this.classIdentifier = "@class";
          }
    
          @Override
          public void serialize(
              NullValue value, JsonGenerator jsonGenerator, SerializerProvider provider)
              throws IOException {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField(classIdentifier, NullValue.class.getName());
            jsonGenerator.writeEndObject();
          }
        }
      }
    

    RedisSerializer<Object>を実装するクラスを定義します RedisConnectionFactoryでこのクラスを使用して、値をシリアル化/逆シリアル化します。

    class SerializerTest{      
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      public static class First {
        private String attribute1;
        private String attribute2;
        private String attribute3;
      }
      @Data
      @ToString
      public static class Second {
        private Integer attribute1;
        private String attribute2;
        private String attribute4;
      }
    
      public static void main(String[] args) {
        RqueueRedisSerDes serDes = new RqueueRedisSerDes();
        // ignore attribute1 due to different type
        serDes.addClassMap(First.class, Second.class, new String[]{"attribute1"});
        First first = new First("1", "2", "3");
        byte[] out = serDes.serialize(first);
        Second second = (Second) serDes.deserialize(out);
        System.out.println(second);
      }
    }
    

    RepoRqueueからコードを変更しました




    1. フィルタされた配列アイテムだけでMongoDBのオブジェクトを取得する必要があります

    2. グループ数で$groupの結果を取得する

    3. 1つのコマンドでmongoDBを停止する方法

    4. mongodb:マルチキーインデックス構造?