Klientská knihovna Cosmos Azure Spring Data pro Javu

Azure Spring Data Cosmos podporu Spring Data pro Azure Cosmos DB s využitím rozhraní SQL APIzaloženého na rozhraní Spring Data. Azure Cosmos DB je globálně distribuovaná databázová služba, která vývojářům umožňuje pracovat s daty pomocí různých standardních rozhraní API, jako jsou SQL, MongoDB, Cassandra, Graph a Table.

Podpora verzí dat Spring

Tento projekt podporuje verze spring-data-commons 2.2.xspring-data-commons 2.3.x i . Uživatelé Mavenu zdědí z projektu oddíl správy závislostí, aby spring mohl spring-boot-starter-parent spravovat verze závislostí.

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

S tímto nastavením můžete také přepsat jednotlivé závislosti přepsáním vlastnosti ve vlastním projektu. Pokud například chcete upgradovat na jiný trénování vydání Spring Data, přidejte do svéhopom.xml.

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

Pokud nechcete používat , můžete si zachovat výhody správy závislostí spring-boot-starter-parent pomocí scope=import závislosti:

<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>

Toto nastavení neumožňuje přepsat jednotlivé závislosti pomocí vlastnosti, jak je vysvětleno výše. Pokud chcete dosáhnout stejného výsledku, musíte před položku přidat položku do dependencyManagement vašeho spring-boot-dependencies projektu. Pokud například chcete upgradovat na jiný trénování vydání Spring Data, přidejte do svého 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>

Poznámka

Nahraďte ${spring.boot.version}${spring.data.version} a verzemi souborů Spring Boot a Spring Data, které chcete použít ve svém projektu.

Začínáme

Zahrnutí balíčku

Pokud používáte Maven, přidejte následující závislost.

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

Požadavky

  • Java Development Kit (JDK)verze 8 nebo novější.
  • Aktivní účet Azure. Pokud žádný nemáte, můžete si zaregistrovat bezplatný účet. Alternativně můžete použít azure Cosmos DB Emulator pro vývoj a testování. Vzhledem k tomu, že certifikát HTTPS emulátoru je podepsaný svým držitelem, musíte jeho certifikát importovat do úložiště důvěryhodných certifikátů Java, jak je vysvětleno tady.
  • (Volitelné) SLF4J je průčelí protokolování.
  • (Volitelné) Vazba SLF4J slouží k přidružení konkrétního protokolovací architektury k SLF4J.
  • (Volitelné) Maven

SLF4J je potřeba jenom v případě, že máte v plánu používat protokolování. Stáhněte si také vazbu SLF4J, která propoji rozhraní SLF4J API s implementací protokolování podle vašeho výběru. Další informace najdete v uživatelské příručce SLF4J.

Třída konfigurace instalace

Abyste mohli nastavit třídu konfigurace, budete muset rozšířit AbstractCosmosConfiguration

Azure-spring-data-cosmos také podporuje a Response Diagnostics StringQuery Metrics . Pokud queryMetricsEnabled chcete povolit metriky dotazů, nastavte v souboru application.properties příznak na true. Kromě nastavení příznaku implementujte pro ResponseDiagnosticsProcessor protokolování diagnostických informací.

@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);
        }
    }

}

Přizpůsobení konfigurace

Můžete přizpůsobit nebo nebo obojí a poskytnout je k DirectConnectionConfigGatewayConnectionConfigCosmosClientBuilder přizpůsobení. 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();
}

Ve výchozím nastavení @EnableCosmosRepositories prohledá aktuální balíček pro všechna rozhraní, která rozšiřují jedno z rozhraní úložiště Spring Data. Použijte ho k anotování třídy Configuration a naskenujte jiný kořenový balíček pomocí , pokud rozložení projektu @EnableCosmosRepositories(basePackageClass=UserRepository.class) obsahuje více projektů.

Definování entity

Definujte jednoduchou entitu jako položku v Azure Cosmos DB.

Entity můžete definovat přidáním poznámky a zadáním vlastností souvisejících s kontejnerem, jako je například název kontejneru, jednotky žádostí (RU), TTO (Time to Live) a automaticky vytvořit @Container kontejner.

Kontejnery se vytvoří automaticky, pokud je nechcete používat. Pokud chcete zakázat automatické vytváření autoCreateContainer kontejnerů, nastavte v poznámce @Container na false.

Poznámka

Ve výchozím nastavení mají jednotky žádostí přiřazené k nově vytvořeným kontejnerům hodnotu 400. Zadáním jiné hodnoty RU můžete přizpůsobit jednotky žádostí pro kontejner vytvořený sadou SDK (minimální hodnota RU je 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;
    }
}

Pole id se použije jako ID položky v Azure Cosmos DB. Pokud chcete jako položku použít jiné pole, například , stačí k poli přidat firstNameid@Id poznámky.

Poznámka určuje název @Container(containerName="myContainer") kontejneru v Azure Cosmos DB.

Anotace @PartitionKey u lastName pole určuje toto pole jako klíč oddílu v Azure Cosmos DB.

Vytváření kontejnerů s propustností automatického škálování

Pole poznámek určuje kontejner, který se má vytvořit s propustností automatického autoScale škálování, pokud je nastavená na true. Výchozí hodnota je false, což znamená, že kontejnery se vytvářejí s ruční propustností.

Další informace o propustnosti automatického škálování najdete tady.

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

}

Podpora vnořeného klíče oddílu

Spring Data Cosmos SDK podporuje vnořený klíč oddílu. Pokud chcete přidat vnořený klíč oddílu, partitionKeyPath použijte pole @Container v poznámce.

partitionKeyPath by se mělo používat pouze pro podporu cesty ke klíčům vnořených oddílů. Pro obecnou podporu klíčů oddílů použijte @PartitionKey anotaci .

Ve výchozím @PartitionKey nastavení bude mít anotace přednost, pokud není zadána.

Následující příklad ukazuje, jak správně používat funkci klíče vnořeného oddílu.

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

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

Vytváření úložišť

Rozšiřuje rozhraní CosmosRepository, které poskytuje podporu úložiště Spring Data.

@Repository
public interface UserRepository extends CosmosRepository<User, String> {
    Iterable<User> findByFirstName(String firstName);
    long countByFirstName(String firstName);
    User findOne(String id, String lastName);
}
  • findByFirstName metoda je metoda vlastního dotazu, najde položky podle firstName.

QueryAnnotation: Použití dotazů s poznámkami v úložištích

Azure Spring Data Cosmos podporuje zadávání dotazů s poznámkami v úložištích pomocí @Query .

Tady je několik příkladů pro dotazy s poznámkami v synchronní operaci 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);
}

Tady je několik příkladů pro dotazy s poznámkami v 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);
}

Dotazy zadané v anotaci jsou stejné jako dotazy Cosmos dotazy. Další informace o dotazech na dotazy SQL v následujících článcích Cosmos:

Vytvoření třídy Application

Tady vytvořte třídu aplikace se všemi komponentami.

@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 the UserRepository interface, to perform operations like save, delete, find, atd.

Spring Data Azure Cosmos DB používá a k provádění dotazů za CosmosTemplateReactiveCosmosTemplateCosmosTemplatea ReactiveCosmosTemplate Šablonu můžete použít sami pro složitější dotazy.

Klíčové koncepty

CrudRepository a ReactiveCrudRepository

Azure Spring Data Cosmos podporuje ReactiveCrudRepository a CrudRepository, které poskytují základní funkce CRUD:

  • save
  • Findall
  • findOne by ID
  • deleteAll
  • delete by ID
  • odstranění entity

Poznámky Spring Data

Existují dva způsoby mapování pole ve třídě domény na pole položky Azure Cosmos DB: – anotace pole ve třídě domény pomocí , toto pole se namapuje na Item v id@Id Cosmos id DB. – nastavte název tohoto pole na , toto pole se namapuje na id Item v Azure Cosmos id DB.

Podporuje automatické generování identifikátorů UUID typu řetězce pomocí @GeneratedValue poznámek. Pole ID entity s ID typu řetězce lze anotovat pomocí , aby se před vložením automaticky vygeneroval @GeneratedValue náhodný identifikátor UUID.

public class GeneratedIdEntity {

    @Id
    @GeneratedValue
    private String id;

}
  • SpEL Expression (Výraz SpEL) a Custom Container Name (Název vlastního kontejneru).
    • Ve výchozím nastavení bude název kontejneru názvem třídy domény uživatele. Pokud ho chcete změnit, přidejte do doménové třídy anotaci @Container(containerName="myCustomContainerName"). Pole kontejneru podporuje také výrazy SpEL (např. container = "${dynamic.container.name}" nebo container = "#{@someBean.getContainerName()}" ), aby bylo možné zadat názvy kontejnerů prostřednictvím kódu programu nebo prostřednictvím vlastností konfigurace.
    • Aby výrazy SpEL fungovaly správně, musíte přidat @DependsOn("expressionResolver") nad třídu Spring Application.
@SpringBootApplication
@DependsOn("expressionResolver")
public class SampleApplication {

}
  • Vlastní zásady indexování: Ve výchozím nastavení bude IndexingPolicy nastaven službou Azure. Chcete-li jej přizpůsobit, přidejte @CosmosIndexingPolicy poznámku do třídy domény. Tato poznámka má 4 atributy k přizpůsobení. Viz následující:
// 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 {};

Oddíl azure Cosmos DB

Azure-spring-data-cosmos podporuje oddíl Azure Cosmos DB.

Pokud chcete zadat pole třídy domény, které má být pole klíče oddílu, stačí ho anotovat pomocí @PartitionKey .

Při provádění operace CRUD zadejte hodnotu oddílu.

Další ukázku crud oddílů najdete tady.

Optimistické uzamykání

Azure-spring-data-cosmos podporuje optimistické zamykání pro konkrétní kontejnery, což znamená, že upserty/odstranění podle položek selžou s výjimkou v případě, že je položka mezitím upravena jiným procesem.

Pokud chcete pro kontejner povolit optimistické zamykání, stačí vytvořit pole řetězce a označit ho _etag@Version poznámkou. Projděte si následující:

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

Vlastní dotaz Spring Data, stránkovatelný a řazení

Azure-spring-data-cosmos podporuje vlastní dotazy Spring Data,například operaci hledání, jako je

Podporuje Spring Data Pageable, Slice a Sort. – V závislosti na dostupných POLOŽEK v databázovém účtu může cosmosDB vracet položky, které jsou menší nebo rovny požadované velikosti. – Vzhledem k tomuto proměnlivýmu počtu vrácených položek v každé iteraci by uživatel neměl spoléhat na hodnotu totalPageSize a iterace přes stránkovatelné položky by se měla provést tímto způsobem.

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 počátečního datového restu

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

  • Podporuje seznam a vnořený typ ve třídě domény.
  • Konfigurovatelná vlastnost ObjectMapper s jedinečným názvem cosmosObjectMapper nakonfigurujte přizpůsobený ObjectMapper jenom v případě, že to opravdu potřebujete. Například:
@Bean(name = "cosmosObjectMapper")
public ObjectMapper objectMapper() {
    return new ObjectMapper(); // Do configuration to the ObjectMapper if required
}

Auditování

Azure-spring-data-cosmos podporuje pole auditování u databázových entit pomocí standardních poznámek spring-data.

Tuto funkci můžete povolit přidáním @EnableCosmosAuditing poznámky do konfigurace aplikace.

Entity mohou anotovat pole pomocí @CreatedBy , @CreatedDate a @LastModifiedBy@LastModifiedDate . Tato pole se automaticky aktualizují.

@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;
}

Konfigurace více databází

Azure-spring-data-cosmos podporuje konfiguraci více databází, včetně "více databázových účtů" a "jednoho účtu, s více databázemi".

Účty s více databázemi

V příkladu se používá soubor application.properties:

# 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

Definice entitya úložiště je podobná jako výše. Různé databázové entity můžete umístit do různých balíčků.

Šablona cosmos definuje uživatel s podporou nebo , použijte nebo ke konfiguraci názvu objektu nebo bean, který se má použít se @EnableReactiveCosmosRepositories@EnableCosmosRepositoriesreactiveCosmosTemplateRefcosmosTemplateRefReactiveCosmosTemplateCosmosTemplate zjištěná úložištěmi.

Pokud máte více účtů databáze Cosmos, můžete definovat více CosmosAsyncClient účtů . Pokud má jeden účet cosmos více databází, můžete stejnou databázi použít CosmosAsyncClient k inicializaci šablony cosmos.

@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);
        }
    }
}

Ve výše uvedeném příkladu máme dva Cosmos účty. Můžete vytvořit CosmosAsyncClient , jak je vidět tady:

@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();
}

Pokud chcete definovat queryMetricsEnabled nebo , můžete vytvořit pro vaši šablonu Cosmos ResponseDiagnosticsProcessorCosmosConfig .

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

Vytvořte Application třídu:

@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();
    }
}

Jeden účet s více databázemi

V příkladu se používá soubor application.properties:

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

Definice entitya úložiště je podobná jako výše. Různé databázové entity můžete umístit do různých balíčků.

S jiným můžete EnableReactiveCosmosRepositories použít k definování více databází v jednom účtu reactiveCosmosTemplateRef cosmos.

@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);
        }

    }
}

Vytvořte Application třídu:

@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();
    }
}

Balíček beta verze

K dispozici je beta verze vytvořená z větve . Můžete se také obrátit na pokyny k master používání balíčků beta verze. master

Řešení potíží

Obecné

Pokud narazíte na nějakou chybu, zakašte problém tady.

Pokud chcete navrhnout novou funkci nebo změny, které by se mohly provést, zakažte problém stejným způsobem jako v případě chyby.

Povolení protokolování klienta

Azure-spring-data-cosmos používá SLF4j jako průčelí protokolování, které podporuje přihlašování k oblíbeným protokolovacím rozhraním, jako je log4j a logback. Pokud například chcete jako protokolovací rozhraní použít spring logback, přidejte do složky resources následující kód XML.

<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>

Příklady

Projděte si ukázkový projekt tady.

Účty s více databázemi

Projděte si ukázkový projekt s více databázemi.

Jeden účet s více databázemi

Projděte si jeden účet s ukázkovým projektem s více databázemi.

Další kroky

Přispívání

Tento projekt vítá příspěvky a návrhy. Většina příspěvků vyžaduje, abyste souhlasíte s licenční smlouvou přispěvatele (CLA), která deklaruje, že máte právo a ve skutečnosti nám udělit práva k používání vašeho příspěvku.

Při odesílání žádosti o přijetí změn robot CLA automaticky určí, jestli je potřeba poskytnout smlouvu CLA, a příslušným způsobem žádost o přijetí změn upraví (např. přidáním jmenovky nebo komentáře). Stačí postupovat podle pokynů robota. Pro všechna úložiště používající naši smlouvu CLA to stačí udělat jenom jednou.

Tento projekt přijal pravidla chování pro Microsoft Open Source. Další informace najdete v nejčastějších dotazech k etickým kodexům. S dalšími dotazy nebo připomínkami se obraťte na .

Imprese