sql >> Databasteknik >  >> NoSQL >> MongoDB

Anpassa Spring Data repository bean namn för användning med flera datakällor

Skapa ditt förvarsgränssnitt med @NoRepositoryBean , vi kopplar upp det själva:

@NoRepositoryBean
public interface ModelMongoRepository extends MongoRepository<Model, String> {
}      

Sedan, i en @Configuration klass, instansiera de 2 förvarsbönorna med MongoRepositoryFactoryBean . Båda arkiven kommer att returnera samma Spring Data Repository-gränssnitt, men vi kommer att tilldela dem olika MongoOperations (dvs:databasdetaljer):

@Configuration
@EnableMongoRepositories
public class MongoConfiguration {

    @Bean
    @Qualifier("one")
    public ModelMongoRepository modelMongoRepositoryOne() throws DataAccessException, Exception {
        MongoRepositoryFactoryBean<ModelMongoRepository, Model, String> myFactory = new MongoRepositoryFactoryBean<ModelMongoRepository, Model, String>();
        myFactory.setRepositoryInterface(ModelMongoRepository.class);
        myFactory.setMongoOperations(createMongoOperations("hostname1", 21979, "dbName1", "username1", "password1"));
        myFactory.afterPropertiesSet();
        return myFactory.getObject();
    }

    @Bean
    @Qualifier("two")
    public ModelMongoRepository modelMongoRepositoryTwo() throws DataAccessException, Exception {
        MongoRepositoryFactoryBean<ModelMongoRepository, Model, String> myFactory = new MongoRepositoryFactoryBean<ModelMongoRepository, Model, String>();
        myFactory.setRepositoryInterface(ModelMongoRepository.class);
        myFactory.setMongoOperations(createMongoOperations("hostname2", 21990, "dbName2", "username2", "password2"));
        myFactory.afterPropertiesSet();
        return myFactory.getObject();
    }

    private MongoOperations createMongoOperations(String hostname, int port, String dbName, String user, String pwd) throws DataAccessException, Exception {
        MongoCredential mongoCredentials = MongoCredential.createScramSha1Credential(user, dbName, pwd.toCharArray());
        MongoClient mongoClient = new MongoClient(new ServerAddress(hostname, port), Arrays.asList(mongoCredentials));
        Mongo mongo = new SimpleMongoDbFactory(mongoClient, dbName).getDb().getMongo();
        return new MongoTemplate(mongo, dbName);
    }
    //or this one if you have a connection string
    private MongoOperations createMongoOperations(String dbConnection) throws DataAccessException, Exception {
        MongoClientURI mongoClientURI = new MongoClientURI(dbConnection);
        MongoClient mongoClient = new MongoClient(mongoClientURI);
        Mongo mongo = new SimpleMongoDbFactory(mongoClient, mongoClientURI.getDatabase()).getDb().getMongo();
        return new MongoTemplate(mongo, mongoClientURI.getDatabase());
    }
}

Du har nu 2 bönor med distinkta @Qualifier namn, var och en konfigurerad för olika databaser och använder samma modell.

Du kan injicera dem med @Qualifier :

@Autowired
@Qualifier("one")
private ModelMongoRepository mongoRepositoryOne;

@Autowired
@Qualifier("two")
private ModelMongoRepository mongoRepositoryTwo;

För enkelhetens skull har jag hårdkodat värdena i konfigurationsklassen, men du kan injicera dem från egenskaper i application.properties/yml.

Här är ändringen om du vill skapa en anpassad implementering utan att förlora fördelarna med vårdatagränssnittsförråd. specifikationerna säger så här:

Skapa ett nytt gränssnitt, som tekniskt sett inte har något med fjäderdata att göra, gamla bra gränssnitt:

public interface CustomMethodsRepository {
    public void getById(Model model){
}

Låt ditt förvarsgränssnitt utöka detta nya gränssnitt:

@NoRepositoryBean
public interface ModelMongoRepository extends MongoRepository<Model, String>, CustomMethodsRepository {
} 

Skapa sedan din implementeringsklass, som endast implementerar ditt icke-fjäderdata-gränssnitt:

public class ModelMongoRepositoryImpl  implements CustomModelMongoRepository {
    private MongoOperations mongoOperations;

    public ModelMongoRepositoryImpl(MongoOperations mongoOperations) {
        this.mongoOperations = mongoOperations;
    }
    public void getById(Model model){
        System.out.println("test");
    }
}

Ändra Java-konfigurationen för att lägga till myFactory.setCustomImplementation(new ModelMongoRepositoryImpl()); :

@Bean
@Qualifier("one")
public ModelMongoRepository modelMongoRepositoryOne() throws DataAccessException, Exception {
    MongoRepositoryFactoryBean<ModelMongoRepository, Model, String> myFactory = new MongoRepositoryFactoryBean<ModelMongoRepository, Model, String>();
    MongoOperations mongoOperations = createMongoOperations("hostname1", 21979, "dbName1", "usdername1", "password1");
    myFactory.setCustomImplementation(new ModelMongoRepositoryImpl(mongoOperations));
    myFactory.setRepositoryInterface(ModelMongoRepository.class);
    myFactory.setMongoOperations(mongoOperations);

    myFactory.afterPropertiesSet();
    return myFactory.getObject();
}

Om du inte kopplade förvaret manuellt via Java-konfiguration, skulle denna implementering MÅSTE heta ModelMongoRepositoryImpl för att matcha gränssnittet ModelMongoRepository +"Impl" . Och det skulle hanteras automatiskt till våren.



  1. Kapslade objekt i mongoosescheman

  2. BsonSerializationException vid serialisering av en Dictionary<DateTime,T> till BSON

  3. hur man undviker $push-ing-nullvärden i mongo-aggregationsramverk

  4. Hur hämtar man data från MongoDB?