将 Spring Data JDBC 与 Azure Database for MySQL 配合使用

本教程演示如何使用 Spring Data JDBC 将数据存储在 Azure Database for MySQL 数据库中。

JDBC 是标准的 Java API,用于连接到传统的关系数据库。

在本教程中,我们包括两种身份验证方法:Microsoft Entra 身份验证和 MySQL 身份验证。 “无密码”选项卡可显示 Microsoft Entra 身份验证,“密码”选项卡则显示 MySQL 身份验证。

Microsoft Entra 身份验证是一种使用 Microsoft Entra ID 中定义的标识连接到 Azure Database for MySQL 的机制。 通过 Microsoft Entra 身份验证,可以在一个中心位置集中管理数据库用户标识和其他 Microsoft 服务,从而简化权限管理。

MySQL 身份验证使用存储在 MySQL 中的帐户。 如果你选择使用密码作为帐户的凭据,这些凭据将存储在 user 表中。 由于这些密码存储在 MySQL 中,因此需要自行管理密码的轮换。

先决条件

  • MySQL 命令行客户端

  • 如果没有 Spring Boot 应用程序,请使用 Spring Initializr 创建 Maven 项目。 请务必选择 Maven 项目,并在“依赖项添加 Spring WebSpring Data JDBCMySQL 驱动程序依赖项,然后选择 Java 版本 8 或更高版本。

请参阅示例应用程序

在本教程中,你将对示例应用程序进行编码。 如果希望加快进程,可通过 https://github.com/Azure-Samples/quickstart-spring-data-jdbc-mysql 获得已编码的应用程序。

为 MySQL 服务器配置防火墙规则

Azure Database for MySQL 实例在默认情况下受保护。 它们有不允许任何传入连接的防火墙。

若要使用数据库,请打开服务器的防火墙,以允许本地 IP 地址访问数据库服务器。 有关详细信息,请参阅使用 Azure 门户 管理 Azure Database for MySQL 灵活服务器的防火墙规则。

如果要从 Windows 计算机上的 适用于 Linux 的 Windows 子系统 (WSL) 连接到 MySQL 服务器,则需要将 WSL 主机 IP 地址添加到防火墙。

创建 MySQL 非管理员用户并授予权限

此步骤将创建非管理员用户,并向该用户授予对数据库的所有权限 demo

可以使用以下方法创建使用无密码连接的非管理员用户。

  1. 使用以下命令安装 Azure CLI 的服务连接或无密码扩展:

     az extension add --name serviceconnector-passwordless --upgrade
    
  2. 使用以下命令创建 Microsoft Entra 非管理员用户:

      az connection create mysql-flexible \
           --resource-group <your_resource_group_name> \
           --connection mysql_conn \
           --target-resource-group <your_resource_group_name> \
           --server mysqlflexibletest \
           --database demo \
           --user-account mysql-identity-id=/subscriptions/<your_subscription_id>/resourcegroups/<your_resource_group_name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<your_user_assigned_managed_identity_name> \
           --query authInfo.userName \
           --output tsv
    

    命令完成后,记下控制台输出中的用户名。

存储 Azure Database for MySQL 中的数据

有了 Azure Database for MySQL 灵活服务器实例后,即可使用 Spring Cloud Azure 来存储数据。

若要安装 Spring Cloud Azure Starter JDBC MySQL 模块,请将以下依赖项添加到 pom.xml 文件:

  • Spring Cloud Azure 材料清单(BOM):

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.azure.spring</groupId>
          <artifactId>spring-cloud-azure-dependencies</artifactId>
          <version>5.11.0</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

    注意

    如果使用 Spring Boot 2.x,请确保将 spring-cloud-azure-dependencies 版本设置为 4.17.0。 此材料清单(BOM)应在pom.xml文件的部分中进行配置<dependencyManagement>。 这可确保所有 Spring Cloud Azure 依赖项都使用相同的版本。 有关用于此 BOM 的版本的详细信息,请参阅 我应使用哪个版本的 Spring Cloud Azure。

  • Spring Cloud Azure Starter JDBC MySQL 项目:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-jdbc-mysql</artifactId>
    </dependency>
    

注意

自版本 4.5.0以来支持无密码连接。

将 Spring Boot 配置为使用 Azure Database for MySQL

若要使用 Spring Data JDBC 从 Azure Database for MySQL 存储数据,请执行以下步骤来配置应用程序:

  1. 通过将以下属性添加到 application.properties 配置文件来配置 Azure Database for MySQL 凭据。

    logging.level.org.springframework.jdbc.core=DEBUG
    
    spring.datasource.url=jdbc:mysql://mysqlflexibletest.mysql.database.azure.com:3306/demo?serverTimezone=UTC
    spring.datasource.username=<your_mysql_ad_non_admin_username>
    spring.datasource.azure.passwordless-enabled=true
    
    spring.sql.init.mode=always
    

    警告

    配置属性 spring.sql.init.mode=always 意味着,每次启动服务器时,Spring Boot 都会使用 下次创建的schema.sql 文件自动生成数据库架构。 此功能非常适合测试,但请记住,它将在每次重启时删除数据,因此不应将其用于生产环境。

    配置属性 spring.datasource.url 中追加了 ?serverTimezone=UTC,以告知 JDBC 驱动程序在连接到数据库时使用 UTC 日期格式(或协调世界时)。 如果没有此参数,Java 服务器不会使用与数据库相同的日期格式,这将导致错误。

请参阅示例应用程序

在本文中,你将对示例应用程序进行编码。 如果希望加快进程,可通过 https://github.com/Azure-Samples/quickstart-spring-data-jdbc-mysql 获得已编码的应用程序。

为 MySQL 服务器配置防火墙规则

Azure Database for MySQL 实例在默认情况下受保护。 它们有不允许任何传入连接的防火墙。

若要使用数据库,请打开服务器的防火墙,以允许本地 IP 地址访问数据库服务器。 有关详细信息,请参阅使用 Azure 门户 创建和管理 Azure Database for MySQL 防火墙规则。

如果要从 Windows 计算机上的 适用于 Linux 的 Windows 子系统 (WSL) 连接到 MySQL 服务器,则需要将 WSL 主机 IP 地址添加到防火墙。

创建 MySQL 非管理员用户并授予权限

此步骤将创建非管理员用户,并向该用户授予对数据库的所有权限 demo

重要

若要使用无密码连接,请为 Azure Database for MySQL 实例创建 Microsoft Entra 管理员用户。 有关详细信息,请参阅使用 Microsoft Entra ID 通过 MySQL 进行身份验证的“设置 Microsoft Entra 管理员用户”部分。

创建一个名为 create_ad_user.sql 的 SQL 脚本用于创建非管理员用户。 添加以下内容,在本地保存该脚本:

export AZ_MYSQL_AD_NON_ADMIN_USERID=$(az ad signed-in-user show --query id --output tsv)

cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;
CREATE AADUSER '<your_mysql_ad_non_admin_username>' IDENTIFIED BY '$AZ_MYSQL_AD_NON_ADMIN_USERID';
GRANT ALL PRIVILEGES ON demo.* TO '<your_mysql_ad_non_admin_username>'@'%';
FLUSH privileges;
EOF

然后,使用以下命令运行该 SQL 脚本以创建 Microsoft Entra 非管理员用户:

mysql -h mysqlsingletest.mysql.database.azure.com --user <your_mysql_ad_admin_username>@mysqlsingletest --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql

提示

若要使用 Microsoft Entra 身份验证连接到 Azure Database for MySQL,需要使用设置的 Microsoft Entra 管理员用户登录,然后获取访问令牌作为密码。 有关详细信息,请参阅 使用 Microsoft Entra ID 通过 MySQL 进行身份验证。

存储 Azure Database for MySQL 中的数据

有了 Azure Database for MySQL 单一服务器实例后,即可使用 Spring Cloud Azure 来存储数据。

若要安装 Spring Cloud Azure Starter JDBC MySQL 模块,请将以下依赖项添加到 pom.xml 文件:

  • Spring Cloud Azure 材料清单(BOM):

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.azure.spring</groupId>
          <artifactId>spring-cloud-azure-dependencies</artifactId>
          <version>5.11.0</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

    注意

    如果使用 Spring Boot 2.x,请确保将 spring-cloud-azure-dependencies 版本设置为 4.17.0。 此材料清单(BOM)应在pom.xml文件的部分中进行配置<dependencyManagement>。 这可确保所有 Spring Cloud Azure 依赖项都使用相同的版本。 有关用于此 BOM 的版本的详细信息,请参阅 我应使用哪个版本的 Spring Cloud Azure。

  • Spring Cloud Azure Starter JDBC MySQL 项目:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-jdbc-mysql</artifactId>
    </dependency>
    

注意

自版本 4.5.0以来支持无密码连接。

将 Spring Boot 配置为使用 Azure Database for MySQL

若要使用 Spring Data JDBC 从 Azure Database for MySQL 存储数据,请执行以下步骤来配置应用程序:

  1. 通过将以下属性添加到 application.properties 配置文件来配置 Azure Database for MySQL 凭据。

    logging.level.org.springframework.jdbc.core=DEBUG
    
    spring.datasource.url=jdbc:mysql://mysqlsingletest.mysql.database.azure.com:3306/demo?serverTimezone=UTC
    spring.datasource.username=<your_mysql_ad_non_admin_username>@mysqlsingletest
    spring.datasource.azure.passwordless-enabled=true
    
    spring.sql.init.mode=always
    

    警告

    配置属性 spring.sql.init.mode=always 意味着,每次启动服务器时,Spring Boot 都会使用 下次创建的schema.sql 文件自动生成数据库架构。 此功能非常适合测试,但请记住,它将在每次重启时删除数据,因此不应将其用于生产环境。

    配置属性 spring.datasource.url 中追加了 ?serverTimezone=UTC,以告知 JDBC 驱动程序在连接到数据库时使用 UTC 日期格式(或协调世界时)。 如果没有此参数,Java 服务器不会使用与数据库相同的日期格式,这将导致错误。

  1. 创建 src/main/resources/schema.sql 配置文件以配置数据库架构,然后添加以下内容。

    DROP TABLE IF EXISTS todo;
    CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
    
  1. 创建新的 Todo Java 类。 此类是映射到由 Spring Boot 自动创建的表的 todo 域模型。 以下代码将 getters 忽略和 setters 方法。

    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;
    
    }
    
  2. 编辑启动类文件以显示以下内容。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.event.ApplicationReadyEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.data.repository.CrudRepository;
    
    import java.util.stream.Stream;
    
    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
        @Bean
        ApplicationListener<ApplicationReadyEvent> basicsApplicationListener(TodoRepository repository) {
            return event->repository
                .saveAll(Stream.of("A", "B", "C").map(name->new Todo("configuration", "congratulations, you have set up correctly!", true)).toList())
                .forEach(System.out::println);
        }
    
    }
    
    interface TodoRepository extends CrudRepository<Todo, Long> {
    
    }
    

    提示

    在本教程中,配置或代码中没有身份验证操作。 但是,连接到 Azure 服务需要身份验证。 要完成身份验证,需要使用 Azure 标识。 Spring Cloud Azure 使用 DefaultAzureCredentialAzure 标识库提供的帮助获取凭据,而无需进行任何代码更改。

    DefaultAzureCredential 支持多种身份验证方法,并确定应在运行时使用哪种方法。 此方法使应用能够在不同环境(如本地环境和生产环境)中使用不同的身份验证方法,而无需实现特定于环境的代码。 有关详细信息,请参阅 DefaultAzureCredential

    若要在本地开发环境中完成身份验证,可以使用 Azure CLI、Visual Studio Code、PowerShell 或其他方法。 有关详细信息,请参阅 Java 开发环境中的 Azure 身份验证。 若要在 Azure 托管环境中完成身份验证,建议使用用户分配的托管标识。 有关详细信息,请参阅什么是 Azure 资源的托管标识?

  3. 启动应用程序。 应用程序将数据存储在数据库中。 你将看到类似于以下示例的日志:

    2023-02-01 10:22:36.701 DEBUG 7948 --- [main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO todo (description, details, done) VALUES (?, ?, ?)]    
    com.example.demo.Todo@4bdb04c8
    

部署到 Azure Spring Apps

现在,你已在本地运行 Spring Boot 应用程序,现在可以将其移动到生产环境。 使用 Azure Spring Apps 可以轻松地将 Spring Boot 应用程序部署到 Azure,而无需进行任何代码更改。 该服务管理 Spring 应用程序的基础结构,让开发人员可以专注于代码。 Azure Spring Apps 可以通过以下方法提供生命周期管理:综合性监视和诊断、配置管理、服务发现、CI/CD 集成、蓝绿部署等。 若要将应用程序部署到 Azure Spring Apps,请参阅将 第一个应用程序部署到 Azure Spring Apps

后续步骤