Поделиться через


Использование R2DBC Spring Data с Базой данных SQL Azure

В этой статье показано, как создать пример приложения для хранения данных в Базе данных SQL и их извлечения с помощью R2DBC Spring Data, используя реализацию R2DBC для Microsoft SQL Server из репозитория GitHub r2dbc-mssql.

R2DBC приносит реактивные API к традиционным реляционным базам данных. Вы можете применять это решение со Spring WebFlux для создания полностью реактивных приложений Spring Boot, которые используют неблокирующие API. Оно обеспечивает улучшенную масштабируемость по сравнению с классическим подходом "один поток на подключение".

Необходимые компоненты

  • Программа sqlcmd.

  • cURL или подобная служебная HTTP-программа, с помощью которой можно протестировать функциональные возможности.

См. пример приложения

В этой статье вы закодируем пример приложения. Если вы хотите ускорить работу, готовое приложение доступно здесь: https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-sql-server.

Подготовка среды выполнения

Сначала настройте некоторые переменные среды с помощью следующих команд:

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_SQL_SERVER_ADMIN_USERNAME=spring
export AZ_SQL_SERVER_ADMIN_PASSWORD=<YOUR_AZURE_SQL_ADMIN_PASSWORD>
export AZ_SQL_SERVER_NON_ADMIN_USERNAME=nonspring
export AZ_SQL_SERVER_NON_ADMIN_PASSWORD=<YOUR_AZURE_SQL_NON_ADMIN_PASSWORD>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>

Замените заполнители следующими значениями, которые используются в этой статье:

  • <YOUR_DATABASE_NAME>: имя сервера База данных SQL Azure, который должен быть уникальным в Azure.
  • <YOUR_AZURE_REGION>: регион Azure, который вы будете использовать. Вы можете использовать eastus по умолчанию, но мы рекомендуем настроить регион, расположенный близко к месту проживания. Полный список доступных регионов можно просмотреть с помощью az account list-locations.
  • <AZ_SQL_SERVER_ADMIN_PASSWORD>и <AZ_SQL_SERVER_NON_ADMIN_PASSWORD>: пароль База данных SQL Azure сервера, который должен содержать не менее восьми символов. и включать знаки всех следующих типов: прописные латинские буквы, строчные латинские буквы, цифры (0–9) и небуквенно-цифровые знаки (!, $, #, % и т. д.).
  • <YOUR_LOCAL_IP_ADDRESS>: IP-адрес локального компьютера, с которого будет запущено приложение Spring Boot. Один из удобных способов найти его — открыть whatismyip.akamai.com.

Примечание.

Корпорация Майкрософт рекомендует использовать самый безопасный поток проверки подлинности. Поток проверки подлинности, описанный в этой процедуре, например для баз данных, кэшей, сообщений или служб ИИ, требует очень высокой степени доверия к приложению и несет риски, не присутствующих в других потоках. Используйте этот поток, только если более безопасные параметры, такие как управляемые удостоверения для бессерверных или бессерверных подключений, не являются жизнеспособными. Для локальных операций компьютера предпочитайте удостоверения пользователей для бессерверных или бессерверных подключений.

Чтобы создать группу ресурсов, выполните следующую команду:

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION \
    --output tsv

Создание экземпляра Базы данных SQL Azure

Затем создайте управляемый экземпляр сервера База данных SQL Azure, выполнив следующую команду.

Примечание.

Пароль MS SQL должен соответствовать определенным критериям, и настройка завершится ошибкой с несоответствующим паролем. Дополнительные сведения см. в разделе Политика паролей.

az sql server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --admin-user $AZ_SQL_SERVER_ADMIN_USERNAME \
    --admin-password $AZ_SQL_SERVER_ADMIN_PASSWORD \
    --output tsv

Настройка правила брандмауэра для сервера Базы данных SQL Azure

Экземпляры Базы данных SQL Azure по умолчанию защищены. В них включен брандмауэр, который блокирует все входящие подключения. Чтобы вы могли использовать нашу базу данных, добавьте правило брандмауэра, которое разрешит локальному IP-адресу обращаться к серверу базы данных.

Так как вы настроили локальный IP-адрес ранее, вы можете открыть брандмауэр сервера, выполнив следующую команду:

az sql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    --output tsv

Если вы подключаетесь к серверу База данных SQL Azure из подсистема Windows для Linux (WSL) на компьютере Windows, необходимо добавить идентификатор узла WSL в брандмауэр.

Получите IP-адрес хост-компьютера, выполнив следующую команду в WSL:

cat /etc/resolv.conf

Скопируйте IP-адрес после термина nameserver, а затем используйте следующую команду, чтобы задать переменную среды для IP-адреса WSL:

export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Затем используйте следующую команду, чтобы открыть брандмауэр сервера в приложении на основе WSL:


az sql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip-wsl \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

Настройка базы данных SQL Azure

Сервер Базы данных SQL Azure, который вы создали ранее, сейчас пустой. На нем отсутствует база данных, которую можно использовать с приложением Spring Boot. Создайте базу данных с именем demo, выполнив следующую команду:

az sql db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name demo \
    --server $AZ_DATABASE_NAME \
    --output tsv

Создание пользователя, отличного от администратора базы данных SQL, и предоставление разрешения

На этом шаге будет создан пользователь, отличный от администратора, и предоставят ему все разрешения для demo базы данных.

Создайте скрипт SQL с именем create_user.sql для создания пользователя без администратора. Добавьте следующее содержимое и сохраните его локально:

Примечание.

Корпорация Майкрософт рекомендует использовать самый безопасный поток проверки подлинности. Поток проверки подлинности, описанный в этой процедуре, например для баз данных, кэшей, сообщений или служб ИИ, требует очень высокой степени доверия к приложению и несет риски, не присутствующих в других потоках. Используйте этот поток, только если более безопасные параметры, такие как управляемые удостоверения для бессерверных или бессерверных подключений, не являются жизнеспособными. Для локальных операций компьютера предпочитайте удостоверения пользователей для бессерверных или бессерверных подключений.

cat << EOF > create_user.sql
USE demo;
GO
CREATE USER $AZ_SQL_SERVER_NON_ADMIN_USERNAME WITH PASSWORD='$AZ_SQL_SERVER_NON_ADMIN_PASSWORD'
GO
GRANT CONTROL ON DATABASE::demo TO $AZ_SQL_SERVER_NON_ADMIN_USERNAME;
GO
EOF

Затем выполните следующую команду, чтобы запустить скрипт SQL, чтобы создать пользователя без администратора:

sqlcmd -S $AZ_DATABASE_NAME.database.windows.net,1433  -d demo -U $AZ_SQL_SERVER_ADMIN_USERNAME -P $AZ_SQL_SERVER_ADMIN_PASSWORD  -i create_user.sql

Примечание.

Дополнительные сведения о создании пользователей базы данных SQL см. в статье CREATE USER (Transact-SQL).


Создание реактивного приложения Spring Boot

Чтобы создать реактивное приложение Spring Boot, мы будем использовать Spring Initializr. Приложение, которое мы создадим, использует:

  • Spring Boot 2.7.11.
  • Следующие зависимости: Spring Reactive Web (также известный как Spring WebFlux) и Spring Data R2DBC.

Создание приложения с помощью Spring Initializr

Создайте приложение в командной строке с помощью следующей команды:

curl https://start.spring.io/starter.tgz -d dependencies=webflux,data-r2dbc -d baseDir=azure-database-workshop -d bootVersion=2.7.11 -d javaVersion=17 | tar -xzvf -

Добавление реализации реактивного драйвера Базы данных SQL Azure

Откройте файл pom.xml в созданном проекте, чтобы добавить реактивный драйвер Базы данных SQL Azure из репозитория GitHub r2dbc-mssql.

После зависимости spring-boot-starter-webflux добавьте следующий текст:

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-mssql</artifactId>
    <scope>runtime</scope>
</dependency>

Настройка Spring Boot для использования Базы данных SQL Azure

Откройте файл src/main/resources/application.properties и добавьте следующий текст:

logging.level.org.springframework.data.r2dbc=DEBUG

spring.r2dbc.url=r2dbc:pool:mssql://$AZ_DATABASE_NAME.database.windows.net:1433/demo
spring.r2dbc.username=nonspring@$AZ_DATABASE_NAME
spring.r2dbc.password=$AZ_SQL_SERVER_NON_ADMIN_PASSWORD

Замените две переменные $AZ_DATABASE_NAME и переменную $AZ_SQL_SERVER_NON_ADMIN_PASSWORD значениями, которые вы настроили в начале работы с этой статьей.

Примечание.

Для лучшей производительности в качестве значения свойства spring.r2dbc.url указан пул подключений, как описано в репозитории r2dbc-pool.

Теперь вы можете запустить приложение с помощью предоставленной программы-оболочки Maven:

./mvnw spring-boot:run

Ниже приведен снимок экрана приложения, выполняемого в первый раз:

Снимок экрана: работающее приложение.

Создание схемы базы данных

В основном классе DemoApplication настройте новый bean-компонент Spring, который создаст схему базы данных, с помощью следующего кода:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.r2dbc.connectionfactory.init.ConnectionFactoryInitializer;
import org.springframework.data.r2dbc.connectionfactory.init.ResourceDatabasePopulator;

import io.r2dbc.spi.ConnectionFactory;

@SpringBootApplication
public class DemoApplication {

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

    @Bean
    public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
        ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
        initializer.setConnectionFactory(connectionFactory);
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator(new ClassPathResource("schema.sql"));
        initializer.setDatabasePopulator(populator);
        return initializer;
    }
}

Этот bean-компонент Spring использует файл с именем schema.sql, поэтому создайте этот файл в папке src/main/resources и добавьте следующий текст:

DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id INT IDENTITY PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BIT);

Остановите приложение и запустите его снова с помощью следующей команды. Теперь приложение будет использовать созданную ранее базу данных demo и создаст в ней таблицу todo.

./mvnw spring-boot:run

Ниже приведен снимок экрана с создаваемой таблицей базы данных:

Снимок экрана: создание таблицы базы данных.

Добавление кода приложения

Затем добавьте код Java, который будет использовать R2DBC для хранения и извлечения данных из сервера Базы данных SQL Azure.

Создайте новый класс Java Todo рядом с классом DemoApplication с помощью следующего кода:

package com.example.demo;

import org.springframework.data.annotation.Id;

public class Todo {

    public Todo() {
    }

    public Todo(String description, String details, boolean done) {
        this.description = description;
        this.details = details;
        this.done = done;
    }

    @Id
    private Long id;

    private String description;

    private String details;

    private boolean done;

    public Long getId() {
        return id;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public boolean isDone() {
        return done;
    }

    public void setDone(boolean done) {
        this.done = done;
    }
}

Этот класс является моделью предметной области, сопоставленной с таблицей todo, созданной ранее.

Для управления этим классом необходим репозиторий. Определите новый интерфейс TodoRepository в том же пакете с помощью следующего кода:

package com.example.demo;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

public interface TodoRepository extends ReactiveCrudRepository<Todo, Long> {
}

Этот репозиторий является реактивным репозиторием, управляемым Spring Data R2DBC.

Завершите работу приложения, создав контроллер, который может хранить и извлекать данные. Реализуйте класс TodoController в том же пакете и добавьте следующий код:

package com.example.demo;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/")
public class TodoController {

    private final TodoRepository todoRepository;

    public TodoController(TodoRepository todoRepository) {
        this.todoRepository = todoRepository;
    }

    @PostMapping("/")
    @ResponseStatus(HttpStatus.CREATED)
    public Mono<Todo> createTodo(@RequestBody Todo todo) {
        return todoRepository.save(todo);
    }

    @GetMapping("/")
    public Flux<Todo> getTodos() {
        return todoRepository.findAll();
    }
}

Остановите приложение и запустите его снова с помощью следующей команды:

./mvnw spring-boot:run

Тестирование приложения

Чтобы протестировать приложение, можно использовать cURL.

Сначала создайте новый элемент todo в базе данных с помощью следующей команды:

curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done": "true"}' \
    http://127.0.0.1:8080

Эта команда должна возвращать созданный элемент, как показано здесь:

{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}

Затем извлеките данные, используя новый запрос cURL, с помощью следующей команды:

curl http://127.0.0.1:8080

Эта команда вернет список элементов todo, включая созданный вами элемент, как показано здесь:

[{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}]

Ниже приведен снимок экрана с этими запросами cURL:

Снимок экрана: тест cURL.

Поздравляем! Вы создали полностью реактивное приложение Spring Boot, которое использует R2DBC для хранения и извлечения данных из Базы данных SQL Azure.

Очистка ресурсов

Чтобы очистить все ресурсы, используемые во время этого краткого руководства, удалите группу ресурсов с помощью следующей команды:

az group delete \
    --name $AZ_RESOURCE_GROUP \
    --yes

Следующие шаги

Дополнительные сведения о развертывании приложения Spring Data в Azure Spring Apps и использовании управляемого удостоверения см. в руководстве по развертыванию приложения Spring в Azure Spring Apps с подключением без пароля к базе данных Azure.

Дополнительные сведения о Spring и Azure см. в центре документации об использовании Spring в Azure.

См. также

См. сведения о Spring Data R2DBC в справочной документации по Spring.

См. сведения об использовании Java в Azure в руководствах по использованию Azure для разработчиков Java и Azure DevOps и Java.