Использование R2DBC Spring Data с Базой данных SQL Azure
В этой статье показано, как создать пример приложения для хранения данных в Базе данных SQL и их извлечения с помощью R2DBC Spring Data, используя реализацию R2DBC для Microsoft SQL Server из репозитория GitHub r2dbc-mssql.
R2DBC приносит реактивные API к традиционным реляционным базам данных. Вы можете применять это решение со Spring WebFlux для создания полностью реактивных приложений Spring Boot, которые используют неблокирующие API. Оно обеспечивает улучшенную масштабируемость по сравнению с классическим подходом "один поток на подключение".
Необходимые компоненты
Подписка Azure — создайте бесплатную учетную запись.
Пакет средств разработки Java (JDK) версии 8 или более поздней.
Программа 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:
Поздравляем! Вы создали полностью реактивное приложение 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.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по