共用方式為


搭配 Azure SQL 資料庫 使用 Spring Data R2DBC

本文示範如何使用 R2dbc-mssql GitHub 存放庫的 R2DBC Microsoft 實作,建立使用 Spring Data R2DBC 在 Azure SQL 資料庫儲存和擷取資訊的範例應用程式。

R2DBC 會將反應式 API 帶入傳統關係資料庫。 您可以將它與 Spring WebFlux 搭配使用,以建立使用非封鎖 API 的完整回應式 Spring Boot 應用程式。 其可提供比傳統「每個連線一個線程」方法更好的延展性。

必要條件

請參閱範例應用程式

在本文中,您將撰寫範例應用程式的程序代碼。 如果您想要更快速地執行,此應用程式已編碼,且可在取得 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>:Azure SQL 資料庫 伺服器的名稱,在 Azure 中應該是唯一的。
  • <YOUR_AZURE_REGION>:您將使用的 Azure 區域。 根據預設,您可以使用 eastus,但建議您將區域設定為您居住地附近的位置。 您可以使用 檢視可用區域 az account list-locations的完整清單。
  • <AZ_SQL_SERVER_ADMIN_PASSWORD><AZ_SQL_SERVER_NON_ADMIN_PASSWORD>:Azure SQL 資料庫 伺服器的密碼,至少應有八個字元。 這些字元應屬於下列三種類別:英文大寫字母、英文小寫字母、數字 (0-9) 及非英數字元 (!、$、#、% 等等)。
  • <YOUR_LOCAL_IP_ADDRESS>:本機電腦的 IP 位址,您將在此電腦執行 Spring Boot 應用程式。 您可以開啟 whatismyip.akamai.com,以便找出此資訊。

注意

Microsoft 建議您使用最安全的可用驗證流程。 此程式中所述的驗證流程,例如資料庫、快取、傳訊或 AI 服務,在應用程式中需要高度的信任,而且不會在其他流程中帶來風險。 只有在更安全的選項,例如無密碼或無密鑰連線的受控識別時,才能使用此流程。 針對本機計算機作業,偏好使用無密碼或無密鑰連線的使用者身分識別。

接下來,使用下列命令建立資源群組:

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

建立 Azure SQL 資料庫執行個體

接下來,執行下列命令來建立受控 Azure SQL 資料庫 伺服器實例。

注意

MS SQL 密碼必須符合特定準則,且安裝程式會失敗,且密碼不符合規範。 如需詳細資訊,請參閱< Password Policy>。

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

設定 Azure SQL 資料庫伺服器的防火牆規則

Azure SQL 資料庫執行個體預設受到保護。 它們具有不允許任何連入連線的防火牆。 若要能夠使用您的資料庫,您必須新增防火牆規則,讓本機 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

如果您要從 Windows 電腦上的 Windows 子系統 Linux 版 (WSL) 連線到 Azure SQL 資料庫 伺服器,您必須將 WSL 主機標識元新增至防火牆。

在 WSL 中執行下列命令,以取得您主機電腦的 IP 位址:

cat /etc/resolv.conf

複製 nameserver 一詞後面的 IP 位址,然後使用下列命令來設定 WSL IP 位址的環境變數:

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

設定 Azure SQL 資料庫

您稍早建立的 Azure SQL 資料庫伺服器是空的。 它沒有任何資料庫可以搭配 Spring Boot 應用程式使用。 執行下列命令來建立名為 demo 的新資料庫:

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

建立 SQL Database 非系統管理員使用者並授與許可權

此步驟會建立非系統管理員使用者,並將資料庫的所有許可權 demo 授與其。

建立名為 create_user.sql 的 SQL 指令碼,以建立非管理使用者。 新增下列內容,並將其儲存在本地:

注意

Microsoft 建議您使用最安全的可用驗證流程。 此程式中所述的驗證流程,例如資料庫、快取、傳訊或 AI 服務,在應用程式中需要高度的信任,而且不會在其他流程中帶來風險。 只有在更安全的選項,例如無密碼或無密鑰連線的受控識別時,才能使用此流程。 針對本機計算機作業,偏好使用無密碼或無密鑰連線的使用者身分識別。

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 -

新增回應式 Azure SQL 資料庫 驅動程序實作

開啟產生的專案pom.xml檔案,從 r2dbc-mssql GitHub 存放庫新增回應式 Azure SQL 資料庫 驅動程式。

spring-boot-starter-webflux 依性之後,新增下列文字:

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

設定 Spring Boot 以使用 Azure SQL 資料庫

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

以下是第一次執行的應用程式螢幕快照:

執行中應用程式的螢幕快照。

建立資料庫結構描述

在 main DemoApplication 類別內,使用下列程式代碼,設定將建立資料庫架構的新 Spring bean:

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

這個 Spring bean 使用稱為 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

以下是建立資料庫資料表的螢幕快照:

建立資料庫數據表的螢幕快照。

編碼應用程式

接下來,新增將使用 R2DBC 的 Java 程式代碼,以儲存和擷取 Azure SQL 資料庫 伺服器中的數據。

使用下列程式代碼,在 類別旁邊DemoApplication建立新的 Todo Java 類別:

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 測試的螢幕快照。

恭喜! 您已建立使用 R2DBC 從 Azure SQL 資料庫 儲存和擷取數據的完整回應式 Spring Boot 應用程式。

清除資源

若要清除本快速入門期間使用的所有資源,請使用下列命令刪除資源群組:

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

下一步

若要深入瞭解如何將 Spring Data 應用程式部署至 Azure Spring Apps 和使用受控識別,請參閱 教學課程:使用無密碼連線將 Spring 應用程式部署至 Azure Spring Apps。

若要深入了解 Spring 和 Azure,請繼續閱讀「Azure 上的 Spring」文件中心中的資訊。

另請參閱

如需 Spring Data R2DBC 的詳細資訊,請參閱 Spring 的 參考檔

如需如何搭配使用 Azure 和 Java 的詳細資訊,請參閱適用於 Java 開發人員的 Azure使用 Azure DevOps 和 Java