练习 - 创建 Azure 资源和 Java Spring 应用程序
在此单元中,你将创建一个基本的 Spring Boot 应用程序。 你将使用 Azure CLI 和所选的集成开发环境 (IDE) 来编辑代码。 使用自己所选的终端来运行代码。
准备工作环境
使用以下命令设置某些环境变量:
AZ_RESOURCE_GROUP=azure-spring-workshop
AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
AZ_LOCATION=<YOUR_AZURE_REGION>
AZ_MYSQL_USERNAME=spring
AZ_MYSQL_PASSWORD=<YOUR_MYSQL_PASSWORD>
AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
在你的代码中,将占位符替换为下表中的值。 这些值将在整个模块中使用。
变量 | 说明 |
---|---|
YOUR_DATABASE_NAME<> | 你的 MySQL 服务器的名称。 它在 Azure 中应是唯一的。 |
YOUR_AZURE_REGION<> | 你将使用的 Azure 区域。 默认情况下,你可以使用 eastus ,但建议你使用靠近你居住位置的区域。 若要查看可用区域的完整列表,请输入 az account list-locations |
YOUR_MYSQL_PASSWORD<> | MySQL 数据库服务器的密码。 密码应至少包含八个字符。 字符应该来自以下三个类别:英文大写字母、英文小写字母、数字(0 到 9)及非字母数字字符(!、$、#、% 等)。 |
YOUR_LOCAL_IP_ADDRESS<> | 本地计算机的 IP 地址,你将在其中运行 Spring Boot 应用程序。 若要找到此 IP 地址,请将浏览器指向 whatismyip.akamai.com。 |
接下来,创建一个资源组:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
| jq
注意
本模块使用 jq
工具,该工具默认安装在 Azure Cloud Shell 上,用于显示 JSON 数据并使其更具可读性。
如果不想使用 jq
工具,则可以安全地删除此模块中所有命令的 | jq
部分。
创建 Azure Database for MySQL 的实例
现在,你将创建托管 MySQL 服务器。
注意
要了解有关 Azure Database for MySQL 的详细信息,请在本模块的末尾,访问相关文档的链接。
运行以下脚本,创建一个 Azure Database for MySQL 的小型实例。 此数据库具有 1 个 CPU 和 2 GB RAM。
az mysql server create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME \
--location $AZ_LOCATION \
--sku-name B_Gen5_1 \
--storage-size 5120 \
--admin-user $AZ_MYSQL_USERNAME \
--admin-password $AZ_MYSQL_PASSWORD \
| jq
此脚本创建一个使用你先前设置的变量的小型 MySQL 服务器。
为 MySQL 服务器配置防火墙规则
默认情况下,Azure Database for MySQL 受到保护。 其防火墙不允许传入连接。 因此请添加一个防火墙规则,以允许本地 IP 地址访问数据库服务器。
运行以下命令,打开服务器的防火墙:
az mysql server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME-database-allow-local-ip \
--server-name $AZ_DATABASE_NAME \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS \
| jq
运行以下命令以允许从 Azure 资源访问防火墙:
az mysql server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name allAzureIPs \
--server-name $AZ_DATABASE_NAME \
--start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 \
| jq
配置 MySQL 数据库
之前创建的 MySQL 服务器为空。 它没有可用于 Spring Boot 应用程序的数据库。 创建一个名为 demo
的新数据库:
az mysql db create \
--resource-group $AZ_RESOURCE_GROUP \
--name demo \
--server-name $AZ_DATABASE_NAME \
| jq
使用 Spring Initializr 生成应用程序
Spring Initializr 是一个 Web 应用程序,用于生成 Spring Boot 项目结构。 Spring Initializr 不会生成任何应用程序代码,但为你提供一个基本的项目结构和一个 Maven 生成规范。
你将生成具有以下三个依赖项的应用程序基架:web
、mysql
和 data-jpa
。
无需指定 Azure 依赖项,因为你将在本地运行应用程序。
在命令提示符处,生成应用程序:
curl https://start.spring.io/starter.tgz -d type=maven-project -d dependencies=web,data-jpa,mysql -d baseDir=azure-spring-workshop -d bootVersion=3.1.5.RELEASE -d javaVersion=17 | tar -xzvf -
将 Spring Boot 配置为使用 Azure Database for MySQL
打开 src/main/resources/application.properties 文件,并添加一些属性。 请确保将 $AZ_DATABASE_NAME
和 $AZ_MYSQL_PASSWORD
这两个变量替换为先前设置的值。
logging.level.org.hibernate.SQL=DEBUG
spring.datasource.url=jdbc:mysql://$AZ_DATABASE_NAME.mysql.database.azure.com:3306/demo?serverTimezone=UTC
spring.datasource.username=spring@$AZ_DATABASE_NAME
spring.datasource.password=$AZ_MYSQL_PASSWORD
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
警告
配置属性 spring.jpa.hibernate.ddl-auto=create-drop
意味着 Spring Boot 将在应用程序启动时自动创建数据库架构,并在应用程序关闭时尝试删除该数据库架构。 此属性非常适合测试,但不应在生产中使用!
注意
将 ?serverTimezone=UTC
追加到配置属性 spring.datasource.url
。 此设置会告知 Java Database Connectivity (JDBC) 驱动程序在你连接到数据库时使用协调世界时 (UTC) 日期格式。 否则,Java 服务器将不会使用与数据库相同的日期格式,这将导致错误。
现在,使用提供的 Maven 包装器启动应用程序:
./mvnw spring-boot:run
此屏幕截图显示首次运行的应用程序:
编写应用程序代码
接下来,添加以下 Java 代码。 它使用 Java 持久性 API (JPA) 来存储和检索 MySQL 服务器中的数据。
你将使用 JPA 实体类将 Java Todo
对象直接映射到 MySQL Todo
表。
在 DemoApplication
类旁,创建新的 Todo
实体类。 然后,添加以下代码:
package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Todo {
public Todo() {
}
public Todo(String description, String details, boolean done) {
this.description = description;
this.details = details;
this.done = done;
}
@Id
@GeneratedValue
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;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Todo)) {
return false;
}
return id != null && id.equals(((Todo) o).id);
}
@Override
public int hashCode() {
return 31;
}
}
此类是映射到 Todo
表上的域模型。 它将由 JPA 自动创建。
若要管理该类,需要一个存储库。 在同一包中定义一个新的 TodoRepository
接口:
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TodoRepository extends JpaRepository<Todo, Long> {
}
此存储库是一个由 Spring Data JPA 管理的 JPA 存储库。 通过扩展 JpaRepository
,你可获得一组针对你的类型的通用 create、read、update 和 delete (CRUD) 方法。 因此,你可以执行一些操作,例如保存和删除 Todo
对象。
通过创建可发布 REST 接口的 RestController
来完成应用程序,以便通过 HTTP 存储和检索数据。 在同一包中实现 TodoController
类。 然后,添加以下代码:
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/")
public class TodoController {
private final TodoRepository todoRepository;
public TodoController(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
@PostMapping("/")
@ResponseStatus(HttpStatus.CREATED)
public Todo createTodo(@RequestBody Todo todo) {
return todoRepository.save(todo);
}
@GetMapping("/")
public Iterable<Todo> getTodos() {
return todoRepository.findAll();
}
}
最后,请停止该应用程序,然后使用以下命令再次启动它:
./mvnw spring-boot:run
Spring Boot 应用程序应启动并连接到数据库。
此屏幕截图显示应用程序正连接到数据库:
测试应用程序
若要测试应用程序,可以使用 cURL
。
首先,在数据库中创建新的待办事项:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done": "true"}' \
http://127.0.0.1:8080
此命令应返回创建的项:
{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}
接下来,使用新的 cURL
请求检索数据:
curl http://127.0.0.1:8080
此命令返回待办事项列表,包括已创建的项目:
[{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}]