本文作者:王琦智
本教程向你展示如何使用 TiDB 构建 Spring Boot Web 应用程序。使用 Spring Data JPA 模块作为数据访问能力的框架。此示例应用程序的代码仓库可在 Github 下载。
这是一个较为完整的构建 Restful API 的示例应用程序,展示了一个使用 TiDB 作为数据库的通用 Spring Boot 后端服务。设计了以下过程,用于还原一个现实场景:
这是一个关于游戏的例子,每个玩家有两个属性:金币数 coins 和货物数 goods。且每个玩家都拥有一个字段 id,作为玩家的唯一标识。玩家在金币数和货物数充足的情况下,可以自由的交易。
你可以以此示例为基础,构建自己的应用程序。
建议:
在云原生开发环境中尝试 Spring Boot 构建 TiDB 应用程序。 预配置完成的环境,自动启动 TiDB 集群,获取和运行代码,只需要一个链接。
第 1 步:启动你的 TiDB 集群
本节将介绍 TiDB 集群的启动方法。
使用 TiDB Cloud 免费集群
使用本地集群
此处将简要叙述启动一个测试集群的过程,若需查看正式环境集群部署,或查看更详细的部署内容,请查阅本地启动 TiDB。
部署本地测试集群
适用场景:利用本地 macOS 或者单机 Linux 环境快速部署 TiDB 测试集群,体验 TiDB 集群的基本架构,以及 TiDB、TiKV、PD、监控等基础组件的运行
- 下载并安装 TiUP。
{{< copyable "shell-regular" >}}
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
- 声明全局环境变量。
注意:
TiUP 安装完成后会提示对应 profile 文件的绝对路径。在执行以下 source 命令前,需要根据 profile 文件的实际位置修改命令。
{{< copyable "shell-regular" >}}
source .bash_profile
-
在当前 session 执行以下命令启动集群。
-
直接执行
tiup playground命令会运行最新版本的 TiDB 集群,其中 TiDB、TiKV、PD 和 TiFlash 实例各 1 个:{{< copyable "shell-regular" >}}
tiup playground -
也可以指定 TiDB 版本以及各组件实例个数,命令类似于:
{{< copyable "shell-regular" >}}
tiup playground v5.4.0 --db 2 --pd 3 --kv 3
上述命令会在本地下载并启动某个版本的集群(例如 v5.4.0)。最新版本可以通过执行tiup list tidb 来查看。运行结果将显示集群的访问方式:
CLUSTER START SUCCESSFULLY, Enjoy it ^-^
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4001 -u root -p (no password)
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4000 -u root -p (no password)
To view the dashboard: http://127.0.0.1:2379/dashboard
PD client endpoints: [127.0.0.1:2379 127.0.0.1:2382 127.0.0.1:2384]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000
注意:
- 支持 v5.2.0 及以上版本的 TiDB 在 Apple M1 芯片的机器上运行
tiup playground。- 以这种方式执行的 playground,在结束部署测试后 TiUP 会清理掉原集群数据,重新执行该命令后会得到一个全新的集群。
- 若希望持久化数据,可以执行 TiUP 的
--tag参数:tiup --tag <your-tag> playground ...,详情参考 TiUP 参考手册。
第 2 步:安装 JDK
请在你的计算机上下载并安装 Java Development Kit (JDK),这是 Java 开发的必备工具。Spring Boot 支持 Java 版本 8 以上的 JDK,由于 Hibernate 版本的缘故,推荐使用 Java 版本 11 以上的 JDK 。
示例应用程序同时支持 Oracle JDK 和 OpenJDK,请自行选择,本教程将使用 版本 17 的 OpenJDK。
第 3 步:安装 Maven
此示例应用程序使用 Maven 来管理应用程序的依赖项。Spring 支持的 Maven 版本为 3.2 以上,作为依赖管理软件,推荐使用当前最新稳定版本的 Maven。
这里给出命令行安装 Maven 的办法:
- macOS 安装:
{{< copyable "shell-regular" >}}
brew install maven
- 基于 Debian 的 Linux 发行版上安装(如 Ubuntu 等):
{{< copyable "shell-regular" >}}
apt-get install maven
-
基于 Red Hat 的 Linux 发行版上安装(如 Fedora、CentOS 等):
-
dnf 包管理器
{{< copyable "shell-regular" >}}
dnf install maven
- yum 包管理器
{{< copyable "shell-regular" >}}
yum install maven
其他安装方法,请参考 Maven 官方文档。
第 4 步:获取应用程序代码
请下载或克隆示例代码库,并进入到目录spring-jpa-hibernate中。
创建相同依赖空白程序(可选)
本程序使用 Spring Initializr 构建。你可以在这个网页上通过点选以下选项并更改少量配置,来快速得到一个与本示例程序相同依赖的空白应用程序,配置项如下:
Project
- Maven Project
Language
- Java
Spring Boot
- 3.0.0-M2
Project Metadata
- Group: com.pingcap
- Artifact: spring-jpa-hibernate
- Name: spring-jpa-hibernate
- Package name: com.pingcap
- Packaging: Jar
- Java: 17
Dependencies
- Spring Web
- Spring Data JPA
- MySQL Driver
配置完毕后如图所示:

注意:
尽管 SQL 相对标准化,但每个数据库供应商都使用 ANSI SQL 定义语法的子集和超集。这被称为数据库的方言。 Hibernate 通过其 org.hibernate.dialect.Dialect 类和每个数据库供应商的各种子类来处理这些方言的变化。
在大多数情况下,Hibernate 将能够通过在启动期间通过 JDBC 连接的一些返回值来确定要使用的正确方言。有关 Hibernate 确定要使用的正确方言的能力(以及你影响该解析的能力)的信息,请参阅方言解析。
如果由于某种原因无法确定正确的方言,或者你想使用自定义方言,则需要设置 hibernate.dialect 配置项。
—— 节选自 Hibernate 官方文档: Database Dialect
随后,此项目即可正常使用,但仅可使用 TiDB 与 MySQL 相同的能力部分,即使用 MySQL 方言。这是由于 Hibernate 支持 TiDB 方言的版本为 6.0.0.Beta2 以上,而 Spring Data JPA 对 Hibernate 的默认依赖版本为 5.6.4.Final。所以,推荐对 pom.xml 作出以下修改:
- 如此依赖文件中所示,将 Spring Data JPA 内引入的
jakarta包进行排除,即将:
{{< copyable "" >}}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
更改为:
{{< copyable "" >}}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core-jakarta</artifactId>
</exclusion>
</exclusions>
</dependency>
- 随后如此依赖文件中所示,引入
6.0.0.Beta2版本以上的 Hibernate 依赖,此处以6.0.0.CR2版本为例:
{{< copyable "" >}}
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.CR2</version>
</dependency>
- 更改完毕后即可获取一个空白的,拥有与示例程序相同依赖的 Spring Boot 应用程序。
第 5 步:运行应用程序
此处对应用程序代码进行编译和运行,将产生一个 Web 应用程序。Hibernate 将创建一个 在数据库 test 内的表 player_jpa,如果你想应用程序的 Restful API 进行请求,这些请求将会在 TiDB 集群上运行数据库事务。
如果你想了解有关此应用程序的代码的详细信息,可参阅本教程下方的实现细节。
第 5 步第 1 部分:TiDB Cloud 更改参数
若你使用非本地默认集群、TiDB Cloud 或其他远程集群,更改 application.yml (位于 src/main/resources 内) 关于 spring.datasource.url、spring.datasource.username、spring.datasource.password 的参数:
spring:
datasource:
url: jdbc:mysql://localhost:4000/test
username: root
# password: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
database-platform: org.hibernate.dialect.TiDBDialect
hibernate:
ddl-auto: create-drop
若你设定的密码为 123456,而且从 TiDB Cloud 得到的连接字符串为:
mysql --connect-timeout 15 -u root -h xxx.tidbcloud.com -P 4000 -p
那么此处应将参数更改为:
spring:
datasource:
url: jdbc:mysql://xxx.tidbcloud.com:4000/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
database-platform: org.hibernate.dialect.TiDBDialect
hibernate:
ddl-auto: create-drop
第 5 步第 2 部分:运行
打开终端,确保你已经进入 spring-jpa-hibernate 目录,若还未在此目录,请使用命令进入:
cd <path>/tidb-example-java/spring-jpa-hibernate
使用 Make 构建并运行(推荐)
make
手动构建并运行
推荐你使用 Make 方式进行构建并运行,当然,若你希望手动进行构建,请依照以下步骤逐步运行,可以得到相同的结果:
清除缓存并打包:
mvn clean package
运行应用程序的 JAR 文件:
java -jar target/spring-jpa-hibernate-0.0.1.jar
第 5 步第 3 部分:输出
输出的最后部分应如下所示:
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _
( ( )___ | '_ | '_| | '_ / _` |
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0-M1)
2022-03-28 18:46:01.429 INFO 14923 --- [ main] com.pingcap.App : Starting App v0.0.1 using Java 17.0.2 on CheesedeMacBook-Pro.local with PID 14923 (/path/code/tidb-example-java/spring-jpa-hibernate/target/spring-jpa-hibernate-0.0.1.jar started by cheese in /path/code/tidb-example-java/spring-jpa-hibernate)
2022-03-28 18:46:01.430 INFO 14923 --- [ main] com.pingcap.App : No active profile set, falling back to default profiles: default
2022-03-28 18:46:01.709 INFO 14923 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-03-28 18:46:01.733 INFO 14923 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 20 ms. Found 1 JPA repository interfaces.
2022-03-28 18:46:02.010 INFO 14923 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-03-28 18:46:02.016 INFO 14923 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-03-28 18:46:02.016 INFO 14923 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.0.16]
2022-03-28 18:46:02.050 INFO 14923 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-03-28 18:46:02.051 INFO 14923 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 598 ms
2022-03-28 18:46:02.143 INFO 14923 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-03-28 18:46:02.173 INFO 14923 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.0.0.CR2
2022-03-28 18:46:02.262 WARN 14923 --- [ main] org.hibernate.orm.deprecation : HHH90000021: Encountered deprecated setting [javax.persistence.sharedCache.mode], use [jakarta.persistence.sharedCache.mode] instead
2022-03-28 18:46:02.324 INFO 14923 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-03-28 18:46:02.415 INFO 14923 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@2575f671
2022-03-28 18:46:02.416 INFO 14923 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-03-28 18:46:02.443 INFO 14923 --- [ main] SQL dialect : HHH000400: Using dialect: org.hibernate.dialect.TiDBDialect
Hibernate: drop table if exists player_jpa
Hibernate: drop sequence player_jpa_id_seq
Hibernate: create sequence player_jpa_id_seq start with 1 increment by 1
Hibernate: create table player_jpa (id bigint not null, coins integer, goods integer, primary key (id)) engine=InnoDB
2022-03-28 18:46:02.883 INFO 14923 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-03-28 18:46:02.888 INFO 14923 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-03-28 18:46:03.125 WARN 14923 --- [ main] org.hibernate.orm.deprecation : HHH90000021: Encountered deprecated setting [javax.persistence.lock.timeout], use [jakarta.persistence.lock.timeout] instead
2022-03-28 18:46:03.132 WARN 14923 --- [ main] org.hibernate.orm.deprecation : HHH90000021: Encountered deprecated setting [javax.persistence.lock.timeout], use [jakarta.persistence.lock.timeout] instead
2022-03-28 18:46:03.168 WARN 14923 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-03-28 18:46:03.307 INFO 14923 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-03-28 18:46:03.311 INFO 14923 --- [ main] com.pingcap.App : Started App in 2.072 seconds (JVM running for 2.272)
输出日志中,提示应用程序在启动过程中做了什么,这里显示应用程序使用 Tomcat 启动了一个 Servlet,使用 Hibernate 作为 ORM ,HikariCP 作为数据库连接池的实现,使用了 org.hibernate.dialect.TiDBDialect 作为数据库方言。启动后,Hibernate 删除并重新创建了表 player_jpa,及序列 player_jpa_id_seq。在启动的最后,监听了 8080 端口,对外提供 HTTP 服务。
如果你想了解有关此应用程序的代码的详细信息,可参阅本教程下方的实现细节。
第 6 步:HTTP 请求
服务完成运行后,即可使用 HTTP 接口请求后端程序。http://localhost:8080 是服务提供根地址。此处使用一系列的 HTTP 请求来演示如何使用该服务。
第 6 步第 1 部分:使用 Postman 请求(推荐)
你可下载此配置文件到本地,并导入 Postman,导入后如图所示:

增加玩家
点击 Create 标签,点击 Send 按钮,发送 Post 形式的 http://localhost:8080/player/ 请求。返回值为增加的玩家个数,预期为 1。

使用 ID 获取玩家信息
点击 GetByID 标签,点击 Send 按钮,发送 Get 形式的 http://localhost:8080/player/1 请求。返回值为 ID 为 1 的玩家信息。

使用 Limit 批量获取玩家信息
点击 GetByLimit 标签,点击 Send 按钮,发送 Get 形式的 http://localhost:8080/player/limit/3 请求。返回值为最多 3 个玩家的信息列表。

分页获取玩家信息
点击 GetByPage 标签,点击 Send 按钮,发送 Get 形式的 http://localhost:8080/player/page?index=0&size=2 请求。返回值为 index 为 0 的页,每页有 2 个玩家信息列表。此外,还包含了分页信息,如偏移量、总页数、是否排序等。

获取玩家个数
点击 Count 标签,点击 Send 按钮,发送 Get 形式的 http://localhost:8080/player/count 请求。返回值为玩家个数。

玩家交易
点击 Trade 标签,点击 Send 按钮,发送 Put 形式的 http://localhost:8080/player/trade 请求,请求参数为售卖玩家 ID sellID、购买玩家 ID buyID、购买货物数量 amount、购买消耗金币数 price。返回值为交易是否成功。当出现售卖玩家货物不足、购买玩家金币不足或数据库错误时,交易将不成功,且由于数据库事务保证,不会有玩家的金币或货物丢失的情况。

第 6 步第 2 部分:使用 curl 请求
当然,你也可以直接使用 curl 进行请求。
增加玩家
使用 Post 方法请求 /player 端点请求来增加玩家,即:
curl --location --request POST 'http://localhost:8080/player/' --header 'Content-Type: application/json' --data-raw '[{"coins":100,"goods":20}]'
这里使用 JSON 作为信息的载荷。表示需要创建一个金币数 coins 为 100,货物数 goods 为 20 的玩家。返回值为创建的玩家个数。
1
使用 ID 获取玩家信息
使用 Get 方法请求 /player 端点请求来获取玩家信息,额外的需要在路径上给出玩家的 id 参数,即 /player/{id} ,例如在请求 id 为 1 的玩家时:
curl --location --request GET 'http://localhost:8080/player/1'
返回值为玩家的信息:
{
"coins": 200,
"goods": 10,
"id": 1
}
使用 Limit 批量获取玩家信息
使用 Get 方法请求 /player/limit 端点请求来获取玩家信息,额外的需要在路径上给出限制查询的玩家信息的总数,即 /player/limit/{limit} ,例如在请求最多 3 个玩家的信息时:
curl --location --request GET 'http://localhost:8080/player/limit/3'
返回值为玩家信息的列表:
[
{
"coins": 200,
"goods": 10,
"id": 1
},
{
"coins": 0,
"goods": 30,
"id": 2
},
{
"coins": 100,
"goods": 20,
"id": 3
}
]
分页获取玩家信息
使用 Get 方法请求 /player/page 端点请求来分页获取玩家信息,额外的需要使用 URL 参数 ,例如在请求页面序号 index 为 0,每页最大请求量 size 为 2 时:
curl --location --request GET 'http://localhost:8080/player/page?index=0&size=2'
返回值为 index 为 0 的页,每页有 2 个玩家信息列表。此外,还包含了分页信息,如偏移量、总页数、是否排序等。
{
"content": [
{
"coins": 200,
"goods": 10,
"id": 1
},
{
"coins": 0,
"goods": 30,
"id": 2
}
],
"empty": false,
"first": true,
"last": false,
"number": 0,
"numberOfElements": 2,
"pageable": {
"offset": 0,
"pageNumber": 0,
"pageSize": 2,
"paged": true,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"unpaged": false
},
"size": 2,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"totalElements": 4,
"totalPages": 2
}
获取玩家个数
使用 Get 方法请求 /player/count 端点请求来获取玩家个数:
curl --location --request GET 'http://localhost:8080/player/count'
返回值为玩家个数
4
玩家交易
使用 Put 方法请求 /player/trade 端点请求来发起玩家间的交易,即:
curl --location --request PUT 'http://localhost:8080/player/trade'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'sellID=1'
--data-urlencode 'buyID=2'
--data-urlencode 'amount=10'
--data-urlencode 'price=100'
这里使用 Form Data 作为信息的载荷。表示售卖玩家 ID sellID 为 1、购买玩家 ID buyID 为 2、购买货物数量 amount 为 10、购买消耗金币数 price 为 100。返回值为交易是否成功。当出现售卖玩家货物不足、购买玩家金币不足或数据库错误时,交易将不成功,且由于数据库事务保证,不会有玩家的金币或货物丢失的情况。
true
第 6 步第 3 部分:使用 Shell 脚本请求
这里已经将请求过程编写为 Shell 脚本,以方便大家的测试,脚本将会做以下操作:
- 循环创建 10 名玩家
- 获取
id为 1 的玩家信息 - 获取至多 3 名玩家信息列表
- 获取
index为 0 ,size为 2 的一页玩家信息 - 获取玩家总数
id为 1 的玩家作为售出方,id 为 2 的玩家作为购买方,购买 10 个货物,耗费 100 金币
你可以使用 make request 或 ./request.sh 命令运行此脚本,结果应如下所示:
> make request
./request.sh
loop to create 10 players:
1111111111
get player 1:
{"id":1,"coins":200,"goods":10}
get players by limit 3:
[{"id":1,"coins":200,"goods":10},{"id":2,"coins":0,"goods":30},{"id":3,"coins":100,"goods":20}]
get first players:
{"content":[{"id":1,"coins":200,"goods":10},{"id":2,"coins":0,"goods":30}],"pageable":{"sort":{"empty":true,"unsorted":true,"sorted":false},"offset":0,"pageNumber":0,"pageSize":2,"paged":true,"unpaged":false},"last":false,"totalPages":7,"totalElements":14,"first":true,"size":2,"number":0,"sort":{"empty":true,"unsorted":true,"sorted":false},"numberOfElements":2,"empty":false}
get players count:
14
trade by two players:
false
实现细节
本小节介绍示例应用程序项目中的组件。
总览
本示例项目的大致目录树如下所示(删除了有碍理解的部分):
.
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── pingcap
│ ├── App.java
│ ├── controller
│ │ └── PlayerController.java
│ ├── dao
│ │ ├── PlayerBean.java
│ │ └── PlayerRepository.java
│ └── service
│ ├── PlayerService.java
│ └── impl
│ └── PlayerServiceImpl.java
└── resources
└── application.yml
其中:
pom.xml内声明了项目的 Maven 配置,如依赖,打包等application.yml内声明了项目的用户配置,如数据库地址、密码、使用的数据库方言等App.java是项目的入口controller是项目对外暴露 HTTP 接口的包service是项目实现接口与逻辑的包dao是项目实现与数据库连接并完成数据持久化的包
配置
本节将简要介绍 pom.xml 文件中的 Maven 配置,及 application.yml 文件中的用户配置。
Maven 配置
pom.xml 文件为 Maven 配置,在文件内声明了项目的 Maven 依赖,打包方法,打包信息等,你可以通过创建相同依赖空白程序 这一节来复刻此配置文件的生成流程,当然,也可直接复制至你的项目来使用。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0-M1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.pingcap</groupId>
<artifactId>spring-jpa-hibernate</artifactId>
<version>0.0.1</version>
<name>spring-jpa-hibernate</name>
<description>an example for spring boot, jpa, hibernate and TiDB</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core-jakarta</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.CR2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
用户配置
application.yml 此配置文件声明了用户配置,如数据库地址、密码、使用的数据库方言等。
spring:
datasource:
url: jdbc:mysql://localhost:4000/test
username: root
# password: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
database-platform: org.hibernate.dialect.TiDBDialect
hibernate:
ddl-auto: create-drop
此配置格式为 YAML 格式。其中:
spring.datasource.url: 数据库连接的 URL。spring.datasource.url: 数据库用户名。spring.datasource.password: 数据库密码,此项为空,需注释或删除。spring.datasource.driver-class-name: 数据库驱动,因为 TiDB 与 MySQL 兼容,则此处使用与 mysql-connector-java 适配的驱动类com.mysql.cj.jdbc.Driver。jpa.show-sql: 为 true 时将打印 JPA 运行的 SQL。jpa.database-platform: 选用的数据库方言,此处连接了 TiDB,自然选择 TiDB 方言,注意,此方言在 6.0.0.Beta2 版本后的 Hibernate 中才可选择,请注意依赖版本。jpa.hibernate.ddl-auto: 此处选择的 create-drop 将会在程序开始时创建表,退出时删除表。请勿在正式环境使用,但此处为示例程序,希望尽量不影响数据库数据,因此选择了此选项。
入口文件
入口文件 App.java:
package com.pingcap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.ApplicationPidFileWriter;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(App.class);
springApplication.addListeners(new ApplicationPidFileWriter("spring-jpa-hibernate.pid"));
springApplication.run(args);
}
}
入口类比较简单,首先,有一个 Spring Boot 应用程序的标准配置注解 @SpringBootApplication。有关详细信息,请参阅 Spring Boot 官方文档中的 Using the @SpringBootApplication Annotation 。随后,使用 ApplicationPidFileWriter 在程序启动过程中,写下一个名为 spring-jpa-hibernate.pid的 PID (process identification number) 文件,可从外部使用此 PID 文件关闭此应用程序。




