Создание Обертки для MongoDB POJO с использованием Generics - PullRequest
0 голосов
/ 26 октября 2018

ОБНОВЛЕНИЕ 2: Я думаю, что добился определенного прогресса.Моя IDE гораздо более довольна моим кодом, но у меня есть только одна последняя строка, которая расстроена:

CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        MongoClientURI connectionString = new MongoClientURI("my-mongo-string");
        MongoClient mongoClient = new MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase("New");
        database = database.withCodecRegistry(pojoCodecRegistry);
        MongoCollection<? extends Person> collection = database.getCollection("people", this.getClass());
        collection = collection.withCodecRegistry(pojoCodecRegistry);
        collection.insertOne(this);

Я поменял название своей «Коллекции» на «Персона», чтобы временно предотвратить столкновения с«Коллекция» Java.Все выглядит хорошо, кроме той последней строки, которая дает мне эту ошибку: insertOne (capture<? extends Utils.Person>) in MongoCollection cannot be applied to (Utils.Person).«Это» относится к моему личному классу.Что я здесь не так делаю?

ОБНОВЛЕНИЕ: Оригинальный вопрос ниже.Я считаю, что теперь я определил, что дженерики - моя лучшая ставка.Однако у меня возникают некоторые проблемы с «обобщением» этих двух строк (при условии, что я правильно инициализировал базу данных):

MongoCollection<MyClass> collection = database.getCollection("SomeString", MyClass.class);

Каков наилучший способ сделать это?Похоже, Java не любит использовать .class в общем случае.

Оригинальный вопрос:

Поэтому я хочу воспользоваться возможностью драйверов MongoDB для хранения PJOS. Пример здесь .Но я планирую хранить несколько классов в базе данных, и я не хочу повторять каждый раз весь код подключения, а также не хочу копировать и вставлять, а затем вносить небольшие изменения в код для каждого класса.У меня была идея создать класс «Коллекция», а затем расширить его, но это не совсем так, как я задумал.Вот мой код:

public class Collection {
    private MongoCollection<Collection> collection;

    public Collection(){}

    public Collection(String databaseName){
        databaseName = databaseName.toLowerCase().replaceAll(" ", "");
        CodecRegistry pojoCodecRegistry = fromRegistries(com.mongodb.MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        MongoClientURI connectionString = new MongoClientURI("my-mongo-connection-string");
        com.mongodb.MongoClient mongoClient = new com.mongodb.MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase(databaseName);
        database = database.withCodecRegistry(pojoCodecRegistry);
        collection = database.getCollection(this.getClass().getName(), Collection.class);
    }

    public Collection findOne(Document document){
        return collection.find(document).first();
    }

    public void save(){
        collection.insertOne(this);
    }

}

Как вы можете видеть, я хочу иметь возможность передавать имя базы данных любому классу, который наследуется от этого класса (или как угодно, что нужно сделать.),и мой код подключиться к базе данных и найти или сохранить POJO соответствующего подкласса должным образом.Например, если бы у меня был класс Person с номером телефона, я мог бы просто расширить свой класс Collections и рассчитывать на то, что все будет работать.Прямо сейчас, когда я вызываю функцию сохранения в дочернем классе, он пытается сохранить родительскую коллекцию, и я получаю сообщение об ошибке Can't find a codec for class Utils.MongoDb.Collection. (мой класс коллекции находится в моем собственном пространстве имен Utils.MongoDb).Я что-то пропустил?Есть ли лучший способ сделать это?Единственный способ заставить это работать, это скопировать и вставить код из моего конструктора Collection в каждый класс и изменить его с помощью подходящих переменных класса.Я надеюсь, что все это ясно.Заранее спасибо!

1 Ответ

0 голосов
/ 31 октября 2018

Aha!Я понял!Мне нужно было обобщить и написать вспомогательный метод, чтобы я мог передать «this» как объект.Я также должен был выполнить приведение к универсальному T. Я знаю, что это неконтролируемое приведение, но я не совсем уверен, как бы я его проверил здесь.В любом случае, это работает!

 public <T> void saveObj(T obj){
        String dbName = "New";
        MongoDatabase database = getMongoDatabase(dbName);
        MongoCollection<T> collection = (MongoCollection<T>) database.getCollection(obj.getClass().getSimpleName(), obj.getClass());
        collection.insertOne(obj);
    }

    public MongoDatabase getMongoDatabase(String dbName) {
        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        MongoClientURI connectionString = new MongoClientURI("my-mongo-string");
        MongoClient mongoClient = new MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase(dbName);
        database = database.withCodecRegistry(pojoCodecRegistry);
        return database;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...