Azure Spring Data Cosmos-clientbibliotheek voor Java

Azure Spring Data Cosmos biedt ondersteuning voor Spring Data voor Azure Cosmos DB met behulp van SQL API,op basis van het Spring Data-framework. Azure Cosmos DB is een wereldwijd gedistribueerde databaseservice waarmee ontwikkelaars met gegevens kunnen werken met behulp van verschillende standaard-API's, zoals SQL, MongoDB, Cassandra, Graph en Table.

Ondersteuning voor Spring Data-versie

Dit project ondersteunt zowel spring-data-commons 2.2.x - als spring-data-commons 2.3.x -versies. Maven-gebruikers kunnen overnemen van het project om een sectie voor afhankelijkheidsbeheer te verkrijgen, zodat Spring de versies spring-boot-starter-parent voor afhankelijkheden kan beheren.

<!-- Inherit defaults from Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>${spring.boot.version}</version>
</parent>

Met deze installatie kunt u ook afzonderlijke afhankelijkheden overschrijven door een eigenschap in uw eigen project te overschrijven. Als u bijvoorbeeld wilt upgraden naar een andere Spring Data-release train, voegt u het volgende toe aan uwpom.xml.

<properties>
    <spring-data-releasetrain.version>${spring.data.version}</spring-data-releasetrain.version>
</properties>

Als u de niet wilt gebruiken, kunt u nog steeds het voordeel van spring-boot-starter-parent afhankelijkheidsbeheer behouden met behulp van een scope=import afhankelijkheid:

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Met deze installatie kunt u afzonderlijke afhankelijkheden niet overschrijven met behulp van een eigenschap, zoals hierboven wordt uitgelegd. Als u hetzelfde resultaat wilt bereiken, moet u vóór de vermelding een vermelding toevoegen in dependencyManagement van uw spring-boot-dependencies project. Als u bijvoorbeeld wilt upgraden naar een andere Spring Data-release train, voegt u het volgende toe aan uw pom.xml.

<dependencyManagement>
    <dependencies>
        <!-- Override Spring Data release train provided by Spring Boot -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>${spring.data.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Notitie

Vervang de ${spring.boot.version} en door de versies van Spring Boot en Spring Data die u in uw project wilt ${spring.data.version} gebruiken.

Aan de slag

Het pakket opnemen

Als u Maven gebruikt, voegt u de volgende afhankelijkheid toe.

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-spring-data-cosmos</artifactId>
    <version>3.13.1</version>
</dependency>

Vereisten

  • Java Development Kit (JDK),versie 8 of hoger.
  • Een actief Azure-account. Als u nog geen account hebt, kunt u zich aanmelden voor een gratis account. U kunt ook de Azure Cosmos DB Emulator voor ontwikkeling en testen. Omdat het HTTPS-certificaat van de emulator zelf is ondertekend, moet u het certificaat importeren in het vertrouwde Java-certificaatopslag. Dit wordt hier uitgelegd
  • (Optioneel) SLF4J is een façade voor logboekregistratie.
  • (Optioneel) SLF4J-binding wordt gebruikt om een specifiek framework voor logboekregistratie te koppelen aan SLF4J.
  • (Optioneel) Maven

SLF4J is alleen nodig als u logboekregistratie wilt gebruiken. Download ook een SLF4J-binding die de SLF4J-API koppelt aan de implementatie van de logboekregistratie van uw keuze. Zie de SLF4J-gebruikershandleiding voor meer informatie.

Configuratieklasse instellen

Als u een configuratieklasse wilt instellen, moet u deze uitbreiden AbstractCosmosConfiguration

Azure-spring-data-cosmos ondersteunt ook Response Diagnostics String en Query Metrics . Stel queryMetricsEnabled de vlag in application.properties in op true om metrische querygegevens in te stellen. Naast het instellen van de vlag implementeert u ResponseDiagnosticsProcessor ook diagnostische logboekgegevens.

@Configuration
@EnableCosmosRepositories
public class AppConfiguration extends AbstractCosmosConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppConfiguration.class);

    @Value("${azure.cosmos.uri}")
    private String uri;

    @Value("${azure.cosmos.key}")
    private String key;

    @Value("${azure.cosmos.secondaryKey}")
    private String secondaryKey;

    @Value("${azure.cosmos.database}")
    private String dbName;

    @Value("${azure.cosmos.queryMetricsEnabled}")
    private boolean queryMetricsEnabled;

    private AzureKeyCredential azureKeyCredential;

    @Bean
    public CosmosClientBuilder getCosmosClientBuilder() {
        this.azureKeyCredential = new AzureKeyCredential(key);
        DirectConnectionConfig directConnectionConfig = new DirectConnectionConfig();
        GatewayConnectionConfig gatewayConnectionConfig = new GatewayConnectionConfig();
        return new CosmosClientBuilder()
            .endpoint(uri)
            .credential(azureKeyCredential)
            .directMode(directConnectionConfig, gatewayConnectionConfig);
    }

    @Override
    public CosmosConfig cosmosConfig() {
        return CosmosConfig.builder()
                           .enableQueryMetrics(queryMetricsEnabled)
                           .responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
                           .build();
    }

    public void switchToSecondaryKey() {
        this.azureKeyCredential.update(secondaryKey);
    }

    @Override
    protected String getDatabaseName() {
        return "testdb";
    }

    private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {

        @Override
        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            LOGGER.info("Response Diagnostics {}", responseDiagnostics);
        }
    }

}

Configuratie aanpassen

U kunt of of beide aanpassen en deze aan te DirectConnectionConfig bieden om aan te GatewayConnectionConfigCosmosClientBuilder passen CosmosAsyncClient

@Bean
public CosmosClientBuilder getCosmosClientBuilder() {

    DirectConnectionConfig directConnectionConfig = new DirectConnectionConfig();
    GatewayConnectionConfig gatewayConnectionConfig = new GatewayConnectionConfig();
    return new CosmosClientBuilder()
        .endpoint(uri)
        .directMode(directConnectionConfig, gatewayConnectionConfig);
}

@Override
public CosmosConfig cosmosConfig() {
    return CosmosConfig.builder()
                       .enableQueryMetrics(queryMetricsEnabled)
                       .responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
                       .build();
}

Standaard wordt het huidige pakket gescand op interfaces die een van de opslagplaatsinterfaces @EnableCosmosRepositories van Spring Data uitbreiden. Gebruik dit om aantekeningen toe te passen op uw configuratieklasse om een ander basispakket te scannen op @EnableCosmosRepositories(basePackageClass=UserRepository.class) als uw projectindeling meerdere projecten heeft.

Een entiteit definiëren

Definieer een eenvoudige entiteit als item in Azure Cosmos DB.

U kunt entiteiten definiëren door de aantekening toe te voegen en eigenschappen op te geven die betrekking hebben op de container, zoals de containernaam, aanvraageenheden (AANVRAAGeenheden), time to live en container voor automatisch @Container maken.

Containers worden automatisch gemaakt, tenzij u dat niet wilt. Ingesteld autoCreateContainer op false in de @Container aantekening om het automatisch maken van containers uit te schakelen.

Notitie

Aanvraageenheden die zijn toegewezen aan nieuw gemaakte containers zijn standaard 400. Geef een andere ru-waarde op om aanvraageenheden aan te passen voor de container die is gemaakt door de SDK (minimale RU-waarde is 400).

@Container(containerName = "myContainer", ru = "400")
public class User {
    private String id;
    private String firstName;


    @PartitionKey
    private String lastName;

    public User() {
        // If you do not want to create a default constructor,
        // use annotation @JsonCreator and @JsonProperty in the full args constructor
    }

    public User(String id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format("User: %s %s, %s", firstName, lastName, id);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Het id veld wordt gebruikt als item-id in Azure Cosmos DB. Als u een ander veld wilt gebruiken, zoals als item, kunt u aantekeningen toevoegen aan firstNameid dat veld met @Id aantekeningen.

De aantekening geeft @Container(containerName="myContainer") de containernaam in Azure Cosmos DB.

Met de aantekening @PartitionKey in het veld geeft u dit veld op als lastName partitiesleutel in Azure Cosmos DB.

Containers maken met doorvoer voor automatisch schalen

Het aantekeningveld geeft aan dat de container moet worden gemaakt met doorvoer voor automatische schaalschalen autoScale als deze is ingesteld op true. De standaardwaarde is false, wat betekent dat containers worden gemaakt met handmatige doorvoer.

Lees hier meer over doorvoer voor automatisch schalen

@Container(containerName = "myContainer", autoScale = true, ru = "4000")
public class UserSample {
    @Id
    private String emailAddress;

}

Ondersteuning voor geneste partitiesleutels

Spring Data Cosmos SDK ondersteunt geneste partitiesleutel. Als u geneste partitiesleutel wilt toevoegen, gebruikt partitionKeyPath u veld in @Container aantekening.

partitionKeyPath mag alleen worden gebruikt ter ondersteuning van het pad van de geneste partitiesleutel. Gebruik de aantekening voor algemene ondersteuning van @PartitionKey partitiesleutels.

De @PartitionKey aantekening heeft standaard prioriteit, tenzij niet opgegeven.

In het volgende voorbeeld ziet u hoe u de functie Geneste partitiesleutel correct kunt gebruiken.

@Container(containerName = "nested-partition-key", partitionKeyPath = "/nestedEntitySample/nestedPartitionKey")
public class NestedPartitionKeyEntitySample {

    private NestedEntitySample nestedEntitySample;
}
public class NestedEntitySample {
    private String nestedPartitionKey;
}

Opslagplaatsen maken

Breidt de CosmosRepository-interface uit, die ondersteuning biedt voor Spring Data-opslagplaatsen.

@Repository
public interface UserRepository extends CosmosRepository<User, String> {
    Iterable<User> findByFirstName(String firstName);
    long countByFirstName(String firstName);
    User findOne(String id, String lastName);
}
  • findByFirstName methode is een aangepaste querymethode. Er worden items per firstName gevonden.

QueryAnnotation: Query's met aantekeningen gebruiken in opslagplaatsen

Azure Spring Data Cosmos ondersteunt het opgeven van query's met aantekeningen in de opslagplaatsen met behulp van @Query .

Hier zijn enkele voorbeelden voor query's met aantekeningen in synchrone CosmosRepository :

public interface AnnotatedQueriesUserRepositoryCodeSnippet extends CosmosRepository<User, String> {
    @Query("select * from c where c.firstName = @firstName and c.lastName = @lastName")
    List<User> getUsersByFirstNameAndLastName(@Param("firstName") String firstName, @Param("lastName") String lastName);

    @Query("select * from c offset @offset limit @limit")
    List<User> getUsersWithOffsetLimit(@Param("offset") int offset, @Param("limit") int limit);

    @Query("select value count(1) from c where c.firstName = @firstName")
    long getNumberOfUsersWithFirstName(@Param("firstName") String firstName);
}

Hier zijn enkele voorbeelden voor query's met aantekeningen in ReactiveCosmosRepository .

public interface AnnotatedQueriesUserReactiveRepositoryCodeSnippet extends ReactiveCosmosRepository<User, String> {
    @Query("select * from c where c.firstName = @firstName and c.lastName = @lastName")
    Flux<User> getUsersByTitleAndValue(@Param("firstName") int firstName, @Param("lastName") String lastName);

    @Query("select * from c offset @offset limit @limit")
    Flux<User> getUsersWithOffsetLimit(@Param("offset") int offset, @Param("limit") int limit);

    @Query("select count(c.id) as num_ids, c.lastName from c group by c.lastName")
    Flux<ObjectNode> getCoursesGroupByDepartment();

    @Query("select value count(1) from c where c.lastName = @lastName")
    Mono<Long> getNumberOfUsersWithLastName(@Param("lastName") String lastName);
}

De query's die zijn opgegeven in de aantekening zijn hetzelfde als de Cosmos-query's. Raadpleeg de volgende artikelen voor meer informatie over het uitvoeren SQL in Cosmos:

Een toepassingsklasse maken

Maak hier een toepassingsklasse met alle onderdelen.

@SpringBootApplication
public class SampleApplication implements CommandLineRunner {

    @Autowired
    private UserRepository repository;

    @Autowired
    private ApplicationContext applicationContext;

    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }

    public void run(String... var1) {

        final User testUser = new User("testId", "testFirstName", "testLastName");

        repository.deleteAll();
        repository.save(testUser);

        // to find by Id, please specify partition key value if collection is partitioned
        final User result = repository.findOne(testUser.getId(), testUser.getLastName());

        //  Switch to secondary key
        UserRepositoryConfiguration bean =
            applicationContext.getBean(UserRepositoryConfiguration.class);
        bean.switchToSecondaryKey();

        //  Now repository will use secondary key
        repository.save(testUser);

    }
}

Autowire de interface om bewerkingen uit te voeren UserRepository zoals opslaan, verwijderen, zoeken, en meer.

Spring Data Azure Cosmos DB gebruikt de en om de query's achter find uit te CosmosTemplateReactiveCosmosTemplateCosmosTemplateReactiveCosmosTemplate op. U kunt de sjabloon zelf gebruiken voor complexere query's.

Belangrijkste concepten

CrudRepository en ReactiveCrudRepository

Azure Spring Data Cosmos biedt ondersteuning voor ReactiveCrudRepository en CrudRepository, dat eenvoudige CRUD-functionaliteit biedt:

  • save
  • findAll
  • findOne by ID
  • Deleteall
  • verwijderen op id
  • entiteit verwijderen

Spring Data-aantekeningen

Er zijn twee manieren om een veld in domeinklasse toe te wijzen aan het veld van Azure Cosmos DB-item: - aantekeningen toevoegen aan een veld in domeinklasse met , wordt dit veld in id@Idid Cosmos DB. - stel de naam van dit veld in op . Dit veld wordt in de idid Azure Cosmos DB.

Ondersteunt het automatisch genereren van UUID's van het type tekenreeks met behulp @GeneratedValue aantekening . Het id-veld van een entiteit met een tekenreekstype-id kan worden geannoeerd met om automatisch een willekeurige UUID te genereren vóór @GeneratedValue de invoeging.

public class GeneratedIdEntity {

    @Id
    @GeneratedValue
    private String id;

}
  • SpEL-expressie en aangepaste containernaam.
    • Standaard is de containernaam de klassenaam van de domeinklasse van de gebruiker. Als u deze wilt aanpassen, voegt u de aantekening @Container(containerName="myCustomContainerName") toe aan de domeinklasse. Het containerveld ondersteunt ook SpEL-expressies (bijvoorbeeld container = "${dynamic.container.name}" of container = "#{@someBean.getContainerName()}" ) om containernamen programmatisch/via configuratie-eigenschappen op te geven.
    • Als u wilt dat SpEL-expressies goed werken, moet u boven @DependsOn("expressionResolver") op de Spring Application-klasse toevoegen.
@SpringBootApplication
@DependsOn("expressionResolver")
public class SampleApplication {

}
  • Aangepaste IndexingPolicy Standaard wordt IndexingPolicy ingesteld door de Azure-service. Als u deze wilt aanpassen, voegt u @CosmosIndexingPolicy aantekening toe aan de domeinklasse. Deze aantekening heeft vier kenmerken om aan te passen. Zie de volgende stappen:
// Indicate if indexing policy use automatic or not
// Default value is true
boolean automatic() default Constants.DEFAULT_INDEXING_POLICY_AUTOMATIC;

// Indexing policy mode, option Consistent.
IndexingMode mode() default IndexingMode.CONSISTENT;

// Included paths for indexing
String[] includePaths() default {};

// Excluded paths for indexing
String[] excludePaths() default {};

Azure Cosmos DB partitie

Azure-spring-data-cosmos ondersteunt Azure Cosmos DB partitie.

Als u een veld van de domeinklasse wilt opgeven als partitiesleutelveld, maakt u er aantekeningen aan met @PartitionKey .

Wanneer u een CRUD-bewerking hebt uitgevoerd, geeft u de partitiewaarde op.

Raadpleeg hier test voor meer voorbeeld over partitie CRUD

Optimistische vergrendeling

Azure-spring-data-cosmos ondersteunt optimistische vergrendeling voor specifieke containers, wat betekent dat upserts/verwijderen per item mislukken met een uitzondering voor het geval het item in de tussentijd door een ander proces wordt gewijzigd.

Als u Optimistische vergrendeling wilt inschakelen voor een container, maakt u een _etag tekenreeksveld en markeert u dit met @Version de aantekening . Bekijk het volgende:

@Container(containerName = "myContainer")
public class MyItem {
    String id;
    String data;
    @Version
    String _etag;
}

Aangepaste Spring Data-query, pageable en sortering

Azure-spring-data-cosmos ondersteunt aangepaste Spring Data-query's,bijvoorbeeld een zoekbewerking zoals

Ondersteunt Spring Data Pageable, Slice en Sort. - Op basis van beschikbare RUs in het databaseaccount kan cosmosDB items retourneren die kleiner zijn dan of gelijk zijn aan de aangevraagde grootte. - Vanwege dit variabele aantal geretourneerde items in elke iteratie moet de gebruiker niet afhankelijk zijn van de totalPageSize en in plaats daarvan moet het itereren over pageable op deze manier worden uitgevoerd.

private List<T> findAllWithPageSize(int pageSize) {

    final CosmosPageRequest pageRequest = new CosmosPageRequest(0, pageSize, null);
    Page<T> page = repository.findAll(pageRequest);
    List<T> pageContent = page.getContent();
    while (page.hasNext()) {
        Pageable nextPageable = page.nextPageable();
        page = repository.findAll(nextPageable);
        pageContent = page.getContent();
    }
    return pageContent;
}
public interface SliceQueriesUserRepository extends CosmosRepository<User, String> {
    @Query("select * from c where c.lastName = @lastName")
    Slice<User> getUsersByLastName(@Param("lastName") String lastName, Pageable pageable);
}
private List<User> getUsersByLastName(String lastName, int pageSize) {

    final CosmosPageRequest pageRequest = new CosmosPageRequest(0, pageSize, null);
    Slice<User> slice = repository.getUsersByLastName(lastName, pageRequest);
    List<User> content = slice.getContent();
    while (slice.hasNext()) {
        Pageable nextPageable = slice.nextPageable();
        slice = repository.getUsersByLastName(lastName, nextPageable);
        content.addAll(slice.getContent());
    }
    return content;
}

Spring Boot Starter Data Rest

Azure-spring-data-cosmos ondersteunt spring-boot-starter-data-rest.

  • Ondersteunt Lijst en genest type in domeinklasse.
  • Configureerbare ObjectMapper-bean met unieke naam , alleen aangepaste ObjectMapper configureren cosmosObjectMapper als dat echt nodig is. Bijvoorbeeld:
@Bean(name = "cosmosObjectMapper")
public ObjectMapper objectMapper() {
    return new ObjectMapper(); // Do configuration to the ObjectMapper if required
}

Controleren

Azure-spring-data-cosmos ondersteunt het controleren van velden in databaseentiteiten met behulp van standaard spring-data-aantekeningen.

Deze functie kan worden ingeschakeld door aantekeningen toe @EnableCosmosAuditing te voegen aan de configuratie van uw toepassing.

Entiteiten kunnen aantekeningen toevoegen aan velden met @CreatedBy behulp van , en @CreatedDate@LastModifiedBy@LastModifiedDate . Deze velden worden automatisch bijgewerkt.

@Container(containerName = "myContainer")
public class AuditableUser {
    private String id;
    private String firstName;
    @CreatedBy
    private String createdBy;
    @CreatedDate
    private OffsetDateTime createdDate;
    @LastModifiedBy
    private String lastModifiedBy;
    @LastModifiedDate
    private OffsetDateTime lastModifiedByDate;
}

Configuratie met meerdere databases

Azure-spring-data-cosmos ondersteunt configuratie met meerdere databases, waaronder 'meerdere databaseaccounts' en 'één account, met meerdere databases'.

Accounts met meerdere databases

In het voorbeeld wordt het bestand application.properties gebruikt:

# primary account cosmos config
azure.cosmos.primary.uri=your-primary-cosmosDb-uri
azure.cosmos.primary.key=your-primary-cosmosDb-key
azure.cosmos.primary.secondaryKey=your-primary-cosmosDb-secondary-key
azure.cosmos.primary.database=your-primary-cosmosDb-dbName
azure.cosmos.primary.populateQueryMetrics=if-populate-query-metrics

# secondary account cosmos config
azure.cosmos.secondary.uri=your-secondary-cosmosDb-uri
azure.cosmos.secondary.key=your-secondary-cosmosDb-key
azure.cosmos.secondary.secondaryKey=your-secondary-cosmosDb-secondary-key
azure.cosmos.secondary.database=your-secondary-cosmosDb-dbName
azure.cosmos.secondary.populateQueryMetrics=if-populate-query-metrics

De definitie van de entiteit en opslagplaats is vergelijkbaar met de bovenstaande definitie. U kunt verschillende database-entiteiten in verschillende pakketten zetten.

De gebruiker of biedt ondersteuning voor het definiëren van de cosmos-sjabloon, gebruik of om de naam van de bean of in te stellen die moet worden gebruikt met @EnableReactiveCosmosRepositories@EnableCosmosRepositories de reactiveCosmosTemplateRefcosmosTemplateRefReactiveCosmosTemplateCosmosTemplate gedetecteerde opslagplaatsen.

Als u meerdere cosmos-databaseaccounts hebt, kunt u meerdere CosmosAsyncClient definiëren. Als het enkele Cosmos-account meerdere databases heeft, kunt u hetzelfde gebruiken om CosmosAsyncClient de cosmos-sjabloon te initialiseren.

@Configuration
@EnableReactiveCosmosRepositories(basePackages = "com.azure.spring.sample.cosmos.multi.database.multiple.account.repository",
    reactiveCosmosTemplateRef = "primaryDatabaseTemplate")
public class PrimaryDatasourceConfiguration extends AbstractCosmosConfiguration{

    private static final String PRIMARY_DATABASE = "primary_database";

    @Bean
    @ConfigurationProperties(prefix = "azure.cosmos.primary")
    public CosmosProperties primary() {
        return new CosmosProperties();
    }

    @Bean
    public CosmosClientBuilder primaryClientBuilder(@Qualifier("primary") CosmosProperties primaryProperties) {
        return new CosmosClientBuilder()
            .key(primaryProperties.getKey())
            .endpoint(primaryProperties.getUri());
    }

    @Bean
    public ReactiveCosmosTemplate primaryDatabaseTemplate(CosmosAsyncClient cosmosAsyncClient,
                                                          CosmosConfig cosmosConfig,
                                                          MappingCosmosConverter mappingCosmosConverter) {
        return new ReactiveCosmosTemplate(cosmosAsyncClient, PRIMARY_DATABASE, cosmosConfig, mappingCosmosConverter);
    }

    @Override
    protected String getDatabaseName() {
        return PRIMARY_DATABASE;
    }
}
@Configuration
@EnableCosmosRepositories(cosmosTemplateRef  = "secondaryDatabaseTemplate")
public class SecondaryDatasourceConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(SecondaryDatasourceConfiguration.class);
    public static final String SECONDARY_DATABASE = "secondary_database";

    @Bean
    @ConfigurationProperties(prefix = "azure.cosmos.secondary")
    public CosmosProperties secondary() {
        return new CosmosProperties();
    }

    @Bean("secondaryCosmosClient")
    public CosmosAsyncClient getCosmosAsyncClient(@Qualifier("secondary") CosmosProperties secondaryProperties) {
        return CosmosFactory.createCosmosAsyncClient(new CosmosClientBuilder()
            .key(secondaryProperties.getKey())
            .endpoint(secondaryProperties.getUri()));
    }

    @Bean("secondaryCosmosConfig")
    public CosmosConfig getCosmosConfig() {
        return CosmosConfig.builder()
            .enableQueryMetrics(true)
            .responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
            .build();
    }

    @Bean
    public CosmosTemplate secondaryDatabaseTemplate(@Qualifier("secondaryCosmosClient") CosmosAsyncClient client,
                                                    @Qualifier("secondaryCosmosConfig") CosmosConfig cosmosConfig,
                                                    MappingCosmosConverter mappingCosmosConverter) {
        return new CosmosTemplate(client, SECONDARY_DATABASE, cosmosConfig, mappingCosmosConverter);
    }

    private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {

        @Override
        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            LOGGER.info("Response Diagnostics {}", responseDiagnostics);
        }
    }
}

In het bovenstaande voorbeeld hebben we twee Cosmos-accounts. U kunt de als CosmosAsyncClient de volgende maken:

@Bean("secondaryCosmosClient")
public CosmosAsyncClient getCosmosAsyncClient(@Qualifier("secondary") CosmosProperties secondaryProperties) {
    return CosmosFactory.createCosmosAsyncClient(new CosmosClientBuilder()
        .key(secondaryProperties.getKey())
        .endpoint(secondaryProperties.getUri()));
}

@Bean("secondaryCosmosConfig")
public CosmosConfig getCosmosConfig() {
    return CosmosConfig.builder()
        .enableQueryMetrics(true)
        .responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
        .build();
}

Als u of wilt queryMetricsEnabledResponseDiagnosticsProcessor definiëren, kunt u de maken CosmosConfig voor uw Cosmos-sjabloon.

@Bean("secondaryCosmosConfig")
public CosmosConfig getCosmosConfig() {
    return CosmosConfig.builder()
        .enableQueryMetrics(true)
        .responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
        .build();
}

Een klasse Application maken:

@SpringBootApplication
public class MultiDatabaseApplication implements CommandLineRunner {

    @Autowired
    private CosmosUserRepository cosmosUserRepository;

    @Autowired
    private MysqlUserRepository mysqlUserRepository;

    @Autowired
    @Qualifier("secondaryDatabaseTemplate")
    private CosmosTemplate secondaryDatabaseTemplate;

    @Autowired
    @Qualifier("primaryDatabaseTemplate")
    private ReactiveCosmosTemplate primaryDatabaseTemplate;

    private final CosmosUser cosmosUser = new CosmosUser("1024", "1024@geek.com", "1k", "Mars");
    private static CosmosEntityInformation<CosmosUser, String> userInfo = new CosmosEntityInformation<>(CosmosUser.class);

    public static void main(String[] args) {
        SpringApplication.run(MultiDatabaseApplication.class, args);
    }

    public void run(String... var1) throws Exception {

        CosmosUser cosmosUserGet = primaryDatabaseTemplate.findById(cosmosUser.getId(), cosmosUser.getClass()).block();
        // Same to this.cosmosUserRepository.findById(cosmosUser.getId()).block();
        MysqlUser mysqlUser = new MysqlUser(cosmosUserGet.getId(), cosmosUserGet.getEmail(), cosmosUserGet.getName(), cosmosUserGet.getAddress());
        mysqlUserRepository.save(mysqlUser);
        mysqlUserRepository.findAll().forEach(System.out::println);
        CosmosUser secondaryCosmosUserGet = secondaryDatabaseTemplate.findById(CosmosUser.class.getSimpleName(), cosmosUser.getId(), CosmosUser.class);
        System.out.println(secondaryCosmosUserGet);
    }


    @PostConstruct
    public void setup() {
        primaryDatabaseTemplate.createContainerIfNotExists(userInfo).block();
        primaryDatabaseTemplate.insert(CosmosUser.class.getSimpleName(), cosmosUser, new PartitionKey(cosmosUser.getName())).block();
        // Same to this.cosmosUserRepository.save(user).block();
        secondaryDatabaseTemplate.createContainerIfNotExists(userInfo);
        secondaryDatabaseTemplate.insert(CosmosUser.class.getSimpleName(), cosmosUser, new PartitionKey(cosmosUser.getName()));
   }

    @PreDestroy
    public void cleanup() {
        primaryDatabaseTemplate.deleteAll(CosmosUser.class.getSimpleName(), CosmosUser.class).block();
        // Same to this.cosmosUserRepository.deleteAll().block();
        secondaryDatabaseTemplate.deleteAll(CosmosUser.class.getSimpleName() , CosmosUser.class);
        mysqlUserRepository.deleteAll();
    }
}

Eén account met meerdere databases

In het voorbeeld wordt het bestand application.properties gebruikt:

azure.cosmos.uri=your-cosmosDb-uri
azure.cosmos.key=your-cosmosDb-key
azure.cosmos.secondary-key=your-cosmosDb-secondary-key
azure.cosmos.database=your-cosmosDb-dbName
azure.cosmos.populate-query-metrics=if-populate-query-metrics

De definitie van de entiteit en opslagplaats is vergelijkbaar met de bovenstaande definitie. U kunt verschillende database-entiteiten in verschillende pakketten zetten.

U kunt met EnableReactiveCosmosRepositories andere gebruiken om meerdere databases in één reactiveCosmosTemplateRef Cosmos-account te definiëren.

@Configuration
public class DatasourceConfiguration {

    private static final String DATABASE1 = "database1";
    private static final String DATABASE2 = "database2";

    @Bean
    public CosmosProperties cosmosProperties() {
        return new CosmosProperties();
    }

    @Bean
    public CosmosClientBuilder primaryClientBuilder(CosmosProperties cosmosProperties) {
        return new CosmosClientBuilder()
            .key(cosmosProperties.getKey())
            .endpoint(cosmosProperties.getUri());
    }

    @EnableReactiveCosmosRepositories(basePackages = "com.azure.spring.sample.cosmos.multi.database.repository1",
        reactiveCosmosTemplateRef = "database1Template")
    public class Database1Configuration extends AbstractCosmosConfiguration {

        @Bean
        public ReactiveCosmosTemplate database1Template(CosmosAsyncClient cosmosAsyncClient,
                                                              CosmosConfig cosmosConfig,
                                                              MappingCosmosConverter mappingCosmosConverter) {
            return new ReactiveCosmosTemplate(cosmosAsyncClient, DATABASE1, cosmosConfig, mappingCosmosConverter);
        }

        @Override
        protected String getDatabaseName() {
            return DATABASE1;
        }
    }

    @EnableReactiveCosmosRepositories(basePackages = "com.azure.spring.sample.cosmos.multi.database.repository2",
        reactiveCosmosTemplateRef = "database2Template")
    public class Database2Configuration {

        @Bean
        public ReactiveCosmosTemplate database2Template(CosmosAsyncClient cosmosAsyncClient,
                                                              CosmosConfig cosmosConfig,
                                                              MappingCosmosConverter mappingCosmosConverter) {
            return new ReactiveCosmosTemplate(cosmosAsyncClient, DATABASE2, cosmosConfig, mappingCosmosConverter);
        }

    }
}

Een klasse Application maken:

@SpringBootApplication
public class MultiDatabaseApplication implements CommandLineRunner {

    @Autowired
    private User1Repository user1Repository;

    @Autowired
    @Qualifier("database1Template")
    private ReactiveCosmosTemplate database1Template;

    @Autowired
    @Qualifier("database2Template")
    private ReactiveCosmosTemplate database2Template;

    private final User1 user1 = new User1("1024", "1024@geek.com", "1k", "Mars");
    private static CosmosEntityInformation<User1, String> user1Info = new CosmosEntityInformation<>(User1.class);

    private final User2 user2 = new User2("2048", "2048@geek.com", "2k", "Mars");
    private static CosmosEntityInformation<User2, String> user2Info = new CosmosEntityInformation<>(User2.class);


    public static void main(String[] args) {
        SpringApplication.run(MultiDatabaseApplication.class, args);
    }

    public void run(String... var1) throws Exception {

        User1 database1UserGet = database1Template.findById(User1.class.getSimpleName(), user1.getId(), User1.class).block();
        // Same to userRepository1.findById(user.getId()).block()
        System.out.println(database1UserGet);
        User2 database2UserGet = database2Template.findById(User2.class.getSimpleName(), user2.getId(), User2.class).block();
        System.out.println(database2UserGet);
    }

    @PostConstruct
    public void setup() {
        database1Template.createContainerIfNotExists(user1Info).block();
        database1Template.insert(User1.class.getSimpleName(), user1, new PartitionKey(user1.getName())).block();
        // Same to this.userRepository1.save(user).block();
        database2Template.createContainerIfNotExists(user2Info).block();
        database2Template.insert(User2.class.getSimpleName(), user2, new PartitionKey(user2.getName())).block();
    }

    @PreDestroy
    public void cleanup() {
        database1Template.deleteAll(User1.class.getSimpleName(), User1.class).block();
        // Same to this.userRepository1.deleteAll().block();
        database2Template.deleteAll(User2.class.getSimpleName(), User2.class).block();
    }
}

Bètaversiepakket

Er zijn bètaversies van vertakkingen beschikbaar. U kunt de instructie mastermaster gebruik van bètaversiepakketten verwijzen.

Problemen oplossen

Algemeen

Als u een fout tegenkomt, kunt u hier een probleem melden.

Als u een nieuwe functie of wijzigingen wilt voorstellen die kunnen worden aangebracht, kunt u een probleem op dezelfde manier indienen als bij een bug.

Logboekregistratie van client inschakelen

Azure-spring-data-cosmos gebruikt SLF4j als de logboekfaçade die logboekregistratie ondersteunt bij populaire frameworks voor logboekregistratie, zoals log4j en logback. Als u bijvoorbeeld Spring Logback wilt gebruiken als framework voor logboekregistratie, voegt u de volgende XML toe aan de map resources.

<configuration>
  <include resource="/org/springframework/boot/logging/logback/base.xml"/>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
      </pattern>
    </encoder>
  </appender>
  <root level="info">
    <appender-ref ref="STDOUT"/>
  </root>
  <logger name="com.azure.cosmos" level="error"/>
  <logger name="org.springframework" level="error"/>
  <logger name="io.netty" level="error"/>
  <!-- This will enable query logging, to include query parameter logging, set this logger to TRACE -->  
  <logger name="com.azure.cosmos.implementation.SqlQuerySpecLogger" level="DEBUG"/>  
</configuration>

Voorbeelden

Raadpleeg hier het voorbeeldproject.

Accounts met meerdere databases

Raadpleeg voorbeeldproject met meerdere databases.

Eén account met meerdere databases

Raadpleeg Single account with Multi-database sample project (Eén account met voorbeeldproject voor meerdere databases).

Volgende stappen

Bijdragen

Wij verwelkomen bijdragen en suggesties voor dit project. Voor de meeste bijdragen moet u akkoord gaan met een licentieovereenkomst voor inzenders (CLA), waarin wordt aangegeven dat u het recht hebt om ons de rechten te verlenen om uw bijdrage te gebruiken.

Wanneer u een pull-aanvraag indient, wordt met een CLA-bot automatisch bepaald of u een CLA moet verschaffen en wordt de pull-aanvraag dienovereenkomstig opgemaakt (bijvoorbeeld met een label of commentaar). Volg gewoon de instructies van de bot. U hoeft dit maar eenmaal te doen voor alle repo's waar gebruik wordt gemaakt van onze CLA.

Op dit project is de Microsoft Open Source Code of Conduct (Microsoft Open Source-gedragscode) van toepassing. Zie de Veelgestelde vragen over de gedragscode voor meer informatie of neem contact op met als u aanvullende vragen of opmerkingen hebt.

Weergaven