MongodB에 열거 값을 저장하는 더 좋은 방법

Java Enum 값을 Enum 이름으로 DB에 저장하려면 Mongo 드라이버가 이를 지원합니다.하면, 만약, 만약...
public enum ProcessType {
    CONVERT_ONE_TO_ONE,
    CONVERT_ONE_TO_MANY;
}
mongo 디코더 공급자에게 등록합니다
import org.bson.codecs.pojo.ClassModel;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.bson.codecs.pojo.PojoCodecProvider.Builder;
import com.ps2pdf.models.enums.ProcessType; // Local
...
Builder builder = <your mongo builder>
ClassModel<ProcessType> classModel = ClassModel.builder(ProcessType.class).build();
builder.register(classModel);
그리고 속성 유형이 ProcessType인 클래스 실례를 DB에 저장할 때마다 생성된 Mongo 문서는 이 속성을 가진 문자열 값 CONVERT_ONE_TO_ONE 이나 CONVERT_ONE_TO_MANY 을 가지고 있습니다.
만약 이것이 네가 필요로 하는 것이라면, 아래의 내용은 너에게 적합하지 않을 것이다.이런 상황에서 당신은 Mongo POJO tutorial에 따라 당신을 지도할 수 있습니다.
다음은 MongodB에 자바와 연결된 값을 저장하는 방법입니다.왜 누군가가 이렇게 하려고 합니까?
  • 자바(TypeScript)는 매거진에서 대문자 이름을 사용하는 관례가 있는데 이것은 상수적으로 대문자 이름을 사용해서 계승된 것일 수 있다.
  • 나는 대상 속성에 소문자 값을 지정하는 것을 더 좋아한다
  • 재산 명칭과 그 가치를 연결하는 것을 방지한다.나는 변수의 이름을 간단하게 유지하고 그 변수에 분배되는 값이 무엇이든 되는 것을 더 좋아한다.
  • MongodB에 이름이 아닌 열거 값을 저장하는 몇 가지 이유입니다.
    나의 또 다른 통증은 전단에서 디코딩을 비교하는 매거값이다.다음은 위의 Java 열거의 프런트엔드 TypeScript 열거입니다.
    export enum WebsocketProcessType {
        CONVERT_ONE_TO_ONE = 'convert-one-to-one',
        CONVERT_ONE_TO_MANY = 'convert-one-to-many',
    }
    
    Mongo 자바 드라이버가 제공하는 기본 Enum 디코더를 사용하려면 자바 Enum의 이름과 같은 값을 사용해야 합니다. 이것은 우리가 읽을 수 있는 코드를 작성하는 데 지나치게 결합되고 엄격해야 합니다.
    다음 명령과 Class Transformer 을 사용하여 백엔드에서 보낸 데이터를 디코딩하면 자바 클래스를 TypeScript (js) 클래스에 빈틈없이 비추게 됩니다.

    구현
    단계:
  • Mongo Code Registry에 디코더 제공 프로그램을 만들고 등록합니다. Mongo는 자바 Enum 값을 사용하는 Enum 디코더를 결정합니다
  • .
  • 작성 및 등록ProcessType의 일괄 디코더
  • DB
  • 에 열거 작성 및 등록
    나는 모든 매거진을 디코딩할 수 있기 때문에 일부 클래스를 범형으로 만들 것이다.

    디코더 공급자 만들기
    Mongo Java 드라이버가 있어야 하고 현대 IDE를 사용하면 모든 가져오기를 자동으로 가져올 수 있기 때문에 가져오기를 제공하지 않습니다.
    public class EnumCodecProvider implements CodecProvider {
        @Override
        public <T> Codec<T> get(Class<T> clazz, CodecRegistry registry) {
            if (clazz == ProcessType.class) {
                return (Codec<T>) new ProcessTypeCodec();
            } 
            return null; // Don't throw here, this tells Mongo this provider doesn't provide a decoder for the requested clazz
        }
    }
    
    이것은 매우 간단하다.Mongo decoder,provider get 방법을 호출하여 디코딩을 할 줄 모르는 클래스에 디코더를 가져옵니다.그것을 호출할 때 ....get(ProcessType.class, MongoRegisty), 우리는 ProcessTypeCodec 을 되돌려줍니다. 이것은 디코딩 ProcessType 을 어떻게 하는지 알고 있습니다.
    CodecRegistry pojoCodecRegistry = 
                    fromRegistries(MongoClient.getDefaultCodecRegistry(),
                        CodecRegistries.fromRegistries(
                            CodecRegistries.fromProviders(new EnumCodecProvider())
                        ), 
                    );
    MongoClientOptions options = MongoClientOptions.builder().codecRegistry(pojoCodecRegistry).build();
    // Register above option with the MongoClient
    
    mongo 등록표에 등록EnumCodeProvider.

    Enum 코덱을 생성하여 Enum을 인코딩/디코딩합니다.
    나는 코드가 중복되지 않도록 디코딩에 필요한 모든 흔한 코드를 넣을 추상적인 디코더를 만들었다
    abstract class AbstractCodec<T extends Enum<T>> implements Codec<T> {
        public AbstractCodec() {
        }
    
        @Override
        final public void encode(final BsonWriter writer, final T value, final EncoderContext encoderContext) {
            String val = ((Enum) value).toString();
            writer.writeString(val);
        }
    
        @Override
        final public T decode(final BsonReader reader, final DecoderContext decoderContext) {
            try {
                String value = reader.readString();
                Method method = getEncoderClass().getDeclaredMethod("fromValue", String.class);
                T enumName = (T) method.invoke(null, value);
                return enumName;
            }catch(Exception e) {
                try {
                    String value = reader.readString();
                    Method method = getEncoderClass().getDeclaredMethod("getDefaultValue");
                    T storageType = (T) method.invoke(null, value);
                    return storageType;
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            return null;
        }
    
        public abstract Class<T> getEncoderClass();
    }
    
    주의, 우리는 위의 toString 방법에서 encode을 호출합니다.이 toString 방법은 ProcessType 매거류에서 이루어져야 매거명칭의 값을 제공할 수 있다.decode 방법에서 우리는 fromValue 매거진에서 getDefaultValueProcessType를 호출하여 데이터베이스에 저장된 특정 값과 관련된 매거 이름을 얻는다.네, 클래스가 T인 대상에 자바 반사를 사용해야 합니다. 반사를 사용하지 않으려면 decode 클래스를 ProcessTypeCodec 전송하고 정적 방법을 직접 호출할 수 있습니다. (아래의 열거 구현 참조)
    위에서 말한 바와 같이, 디코더가 문자열 값을 가진 요청을 받았을 때, 즉 "convert-one-to-one", 우리는 이 디코더와 관련된 클래스 이름을 얻고, 정적 방법 fromValue 을 호출하여 문자열 값에 대응하는 일괄 이름을 얻을 수 있다.
    다음은 ProcessTypeCodec입니다.
    public class ProcessTypeCodec extends AbstractCodec<ProcessType> {
    
        public ProcessTypeCodec() {
            super();
        }
    
        @Override
        public Class<ProcessType> getEncoderClass() {
            return ProcessType.class;
        }
    }
    
    이것은 단지 몬고에게 이 디코더가 인코딩/해독할 수 있다는 것을 알게 하는 종류일 뿐이다.

    ProcessType 열거 구현 및 등록
    public enum ProcessType {
        CONVERT_ONE_TO_ONE("convert-one-to-one"),
        CONVERT_ONE_TO_MANY("convert-one-to-many");
    
        private String value;
        private static final Map<String, ProcessType> ENUM_MAP;
        static {
            Map<String, ProcessType> map = new HashMap<String, ProcessType>();
            for (ProcessType instance : ProcessType.values()) {
                map.put(instance.value(), instance);
            }
            ENUM_MAP = Collections.unmodifiableMap(map);
        }
        ProcessType(String type) {
            this.value = type;
        }
    
        public String value() {
            return this.value;
        }
    
        public static ProcessType fromValue(String value) {
            return ENUM_MAP.get(value);
        }
    
        /**
         * Used by the Mongo codec
         * 
         * @return
         */
        public static ProcessType getDefaultValue() {
            return CONVERT_ONE_TO_ONE;
        }
    
        /**
         * Required to properly convert Java Enum name to value.
         * Value is used by front-end and usually uses <br>
         * 1. lowercase <br>
         * 2. dashes instead of underscores <br> <br>
         */
        @Override
        public String toString() {
            return this.value;
        }
    }
    
    
    ENUM MAP은 단순히 프로세스의 속도를 높이기 위한 것입니다.이것은 디코더가 문자열을 O (1) 의 시간 복잡도로 일괄 이름으로 변환할 수 있도록 합니다.기본값은 사용자의 첫 번째 옵션입니다. 나는 여기에 열거 이름을 사용했지만, 보통 null 입니다.
    Mongo 클래스 레지스트리에 클래스를 등록하는 방법은 위의 문서를 참조하십시오.
    DellPS2PDF Video Compressor은 FFMPEG 압축 또는 비디오 파일 변환에 필요한 명령 매개 변수를 채우기 위해 향상된 기능을 채택했습니다.예를 들어 우리는 전면에 출력을 확장하는 Enum을 가지고 있다
    export enum OutputExtension {
        MP4 = '.mp4',
        WEBM = '.webm'
    }
    
    백엔드
    public enum OutputExtension {
        MP4(".mp4"),
        WEBM(".webm")
        // ... rest of the code similar to above ProcessType Enum
    }
    
    TypeScript에서 생성한 명령줄 매개 변수를 문서의 DB에 저장할 때, DB의 .mp4 extension 을 실제 값으로 저장합니다.백엔드에서, 우리 디코더는 이 값을 관련 자바 매거진에 정확하게 비추었다.FFMPEG 명령을 구축하려면 실제로 Enum 값을 사용할 수 있습니다.

    class Request { // Sample class that deals with request document stored in DB
        OutputExtension outoutExtenstion;
    }
    
    List<String> cmd = List.of("ffmpeg", ..., "-o", Request.outoutExtenstion);
    // This generates % ffmpeg ... -o .mp4
    
    이것은 당신이 더 읽을 수 있는 코드를 작성하는 데 도움을 줄 수 있기를 바랍니다.이 파일에서 오류가 발견되면 수정을 위해 알려 주십시오.

    좋은 웹페이지 즐겨찾기