+
-```yaml
-spring:
- datasource:
- url: jdbc:mysql://xxx.tidbcloud.com:4000/test?sslMode=VERIFY_IDENTITY&enabledTLSProtocols=TLSv1.2,TLSv1.3
- username: 2aEp24QWEDLqRFs.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
-```
+1. Navigate to the [**Clusters**](https://tidbcloud.com/console/clusters) page, and then click the name of your target cluster to go to its overview page.
-### Step 5.2 Run
+2. Click **Connect** in the upper-right corner. A connection dialog is displayed.
-Open a terminal session and make sure you are in the `spring-jpa-hibernate` directory. If you are not already in this directory, navigate to the directory with the following command:
+3. Ensure the configurations in the connection dialog match your operating environment.
-```shell
-cd
/tidb-example-java/spring-jpa-hibernate
-```
+ - **Endpoint Type** is set to `Public`
+ - **Connect With** is set to `General`
+ - **Operating System** matches your environment.
-#### Build and run with Make (recommended)
+ > **Tip:**
+ >
+ > If your program is running in Windows Subsystem for Linux (WSL), switch to the corresponding Linux distribution.
-```shell
-make
-```
-
-#### Build and run manually
+4. Click **Create password** to create a random password.
-If you prefer to build manually, follow these steps:
+ > **Tip:**
+ >
+ > If you have created a password before, you can either use the original password or click **Reset password** to generate a new one.
-1. Clear cache and package:
-
- {{< copyable "shell-regular" >}}
+5. Run the following command to copy `env.sh.example` and rename it to `env.sh`:
```shell
- mvn clean package
+ cp env.sh.example env.sh
```
-2. Run applications with JAR files:
-
- {{< copyable "shell-regular" >}}
+6. Copy and paste the corresponding connection string into the `env.sh` file. The example result is as follows:
```shell
- java -jar target/spring-jpa-hibernate-0.0.1.jar
+ export TIDB_HOST='{host}' # e.g. gateway01.ap-northeast-1.prod.aws.tidbcloud.com
+ export TIDB_PORT='4000'
+ export TIDB_USER='{user}' # e.g. xxxxxx.root
+ export TIDB_PASSWORD='{password}'
+ export TIDB_DB_NAME='test'
+ export USE_SSL='true'
```
-### Step 5.3 Output
-
-The final part of the output should look like the following:
-
-```
- . ____ _ __ _ _
- /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
-( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
- \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\__, | / / / /
- =========|_|==============|___/=/_/_/_/
- :: Spring Boot :: (v3.0.1)
-
-2023-01-05T14:06:54.427+08:00 INFO 22005 --- [ main] com.pingcap.App : Starting App using Java 17.0.2 with PID 22005 (/Users/cheese/IdeaProjects/tidb-example-java/spring-jpa-hibernate/target/classes started by cheese in /Users/cheese/IdeaProjects/tidb-example-java)
-2023-01-05T14:06:54.428+08:00 INFO 22005 --- [ main] com.pingcap.App : No active profile set, falling back to 1 default profile: "default"
-2023-01-05T14:06:54.642+08:00 INFO 22005 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2023-01-05T14:06:54.662+08:00 INFO 22005 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 1 JPA repository interfaces.
-2023-01-05T14:06:54.830+08:00 INFO 22005 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
-2023-01-05T14:06:54.833+08:00 INFO 22005 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
-2023-01-05T14:06:54.833+08:00 INFO 22005 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.4]
-2023-01-05T14:06:54.865+08:00 INFO 22005 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
-2023-01-05T14:06:54.865+08:00 INFO 22005 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 421 ms
-2023-01-05T14:06:54.916+08:00 INFO 22005 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
-2023-01-05T14:06:54.929+08:00 INFO 22005 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.1.6.Final
-2023-01-05T14:06:54.969+08:00 WARN 22005 --- [ main] org.hibernate.orm.deprecation : HHH90000021: Encountered deprecated setting [javax.persistence.sharedCache.mode], use [jakarta.persistence.sharedCache.mode] instead
-2023-01-05T14:06:55.005+08:00 INFO 22005 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
-2023-01-05T14:06:55.074+08:00 INFO 22005 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@5e905f2c
-2023-01-05T14:06:55.075+08:00 INFO 22005 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
-2023-01-05T14:06:55.089+08:00 INFO 22005 --- [ 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
-2023-01-05T14:06:55.332+08:00 INFO 22005 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
-2023-01-05T14:06:55.335+08:00 INFO 22005 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2023-01-05T14:06:55.579+08:00 WARN 22005 --- [ 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
-2023-01-05T14:06:55.710+08:00 INFO 22005 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
-2023-01-05T14:06:55.714+08:00 INFO 22005 --- [ main] com.pingcap.App : Started App in 1.432 seconds (process running for 1.654)
-```
-
-The output log indicates the application behavior during startup. In this example, the application starts a **Servlet** using [Tomcat](https://tomcat.apache.org/), uses Hibernate as the ORM, uses [HikariCP](https://github.com/brettwooldridge/HikariCP) as the database connection pool implementation, and uses `org.hibernate.dialect.TiDBDialect` as the database dialect. After startup, Hibernate deletes and re-creates the `player_jpa` table and the `player_jpa_id_seq` sequence. At the end of startup, the application listens on port `8080` to provide HTTP services to the outside.
-
-If you want to learn more about the code of this application, refer to [implementation details](#implementation-details).
-
-## Step 6: HTTP requests
-
-After the service is up and running, you can send the HTTP requests to the backend application. is the base URL that provides services. This tutorial uses a series of HTTP requests to show how to use the service.
-
-### Step 6.1 Use Postman requests (recommended)
-
-You can download this [configuration file](https://raw.githubusercontent.com/pingcap-inc/tidb-example-java/main/spring-jpa-hibernate/Player.postman_collection.json) locally and import it into [Postman](https://www.postman.com/) as shown here:
-
-![import the collection into Postman](/media/develop/IMG_20220402-003303222.png)
-
-#### Create players
-
-Click on the **Create** tab and the **Send** button to send a POST request to `http://localhost:8080/player/`. The return value is the number of players added, which is expected to be 1.
+ Please make sure to replace the placeholders in `{}` with the values obtained from your connection dialog.
-![Postman-Create a player](/media/develop/IMG_20220402-003350731.png)
+ TiDB Serverless requires a TLS (SSL) connection, so the value of `USE_SSL` should be set to `true`.
-#### Get player information by ID
+7. Save the `env.sh` file.
-Click on the **GetByID** tab and the **Send** button to send a GET request to `http://localhost:8080/player/1`. The return value is the information of the player with ID `1`.
+
+
-![Postman-GetByID](/media/develop/IMG_20220402-003416079.png)
+1. Navigate to the [**Clusters**](https://tidbcloud.com/console/clusters) page, and then click the name of your target cluster to go to its overview page.
-#### Get player information in bulk by limit
+2. Click **Connect** in the upper-right corner. A connection dialog is displayed.
-Click on the **GetByLimit** tab and the **Send** button to send a GET request to `http://localhost:8080/player/limit/3`. The return value is a list of information for up to 3 players.
+3. Click **Allow Access from Anywhere** and then click **Download TiDB cluster CA** to download the CA certificate.
-![Postman-GetByLimit](/media/develop/IMG_20220402-003505846.png)
+ For more details about how to obtain the connection string, refer to [TiDB Dedicated standard connection](https://docs.pingcap.com/tidbcloud/connect-via-standard-connection).
-#### Get player information by page
-
-Click on the **GetByPage** tab and the **Send** button to send a GET request to `http://localhost:8080/player/page?index=0&size=2`. The return value is the page with index `0`, with `2` players per page. The return value also contains the paging information such as offset, totalPages, and sort.
-
-![Postman-GetByPage](/media/develop/IMG_20220402-003528474.png)
-
-#### Count players
-
-Click the **Count** tab and the **Send** button to send a GET request to `http://localhost:8080/player/count`. The return value is the number of players.
-
-![Postman-Count](/media/develop/IMG_20220402-003549966.png)
-
-#### Player trading
-
-Click on the **Trade** tab and the **Send** button to send a PUT request to `http://localhost:8080/player/trade`. The request parameters are the seller's ID `sellID`, the buyer's ID `buyID`, the number of goods purchased `amount`, the number of coins consumed for the purchase `price`.
-
-The return value is whether the transaction is successful or not. When there are insufficient goods for the seller, insufficient coins for the buyer, or a database error, the [database transaction](/develop/dev-guide-transaction-overview.md) guarantees that the trade is not successful and no player's coins or goods are lost.
-
-![Postman-Trade](/media/develop/IMG_20220402-003659102.png)
-
-### Step 6.2 Using curl requests
-
-You can also use curl to make requests directly.
-
-#### Create players
-
-To create players, you can send a **POST** request to the `/player` endpoint. For example:
-
-```shell
-curl --location --request POST 'http://localhost:8080/player/' --header 'Content-Type: application/json' --data-raw '[{"coins":100,"goods":20}]'
-```
-
-The request uses JSON as the payload. The example above indicates creating a player with 100 `coins` and 20 `goods`. The return value is the number of players created.
-
-```json
-1
-```
-
-#### Get player information by ID
-
-To get the player information, you can send a **GET** request to the `/player` endpoint. You need to specify the `id` of the player in the path parameter as follows: `/player/{id}`. The following example shows how to get the information of a player with `id` 1:
-
-```shell
-curl --location --request GET 'http://localhost:8080/player/1'
-```
+4. Run the following command to copy `env.sh.example` and rename it to `env.sh`:
-The return value is the player's information:
-
-```json
-{
- "coins": 200,
- "goods": 10,
- "id": 1
-}
-```
-
-#### Get player information in bulk by limit
-
-To get the player information in bulk, you can send a **GET** request to the `/player/limit` endpoint. You need to specify the total number of players in the path parameter as follows: `/player/limit/{limit}`. The following example shows how to get the information of up to 3 players:
-
-```shell
-curl --location --request GET 'http://localhost:8080/player/limit/3'
-```
-
-The return value is a list of player information:
-
-```json
-[
- {
- "coins": 200,
- "goods": 10,
- "id": 1
- },
- {
- "coins": 0,
- "goods": 30,
- "id": 2
- },
- {
- "coins": 100,
- "goods": 20,
- "id": 3
- }
-]
-```
-
-#### Get player information by page
-
-To get paginated player information, you can send a **GET** request to the `/player/page` endpoint. To specify additional parameters, you need to use the URL parameter. The following example shows how to get the information from a page whose `index` is 0, where each page has a maximum `size` of 2 players.
-
-```shell
-curl --location --request GET 'http://localhost:8080/player/page?index=0&size=2'
-```
-
-The return value is the page with `index` 0, where 2 players are listed per page. In addition, the return value contains pagination information such as offset, total pages, and whether the results are sorted.
-
-```json
-{
- "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
-}
-```
-
-#### Count players
-
-To get the number of players, you can send a **GET** request to the `/player/count` endpoint:
-
-```shell
-curl --location --request GET 'http://localhost:8080/player/count'
-```
-
-The return value is the number of players:
-
-```json
-4
-```
-
-#### Player trading
-
-To initiate a transaction between players, you can send a **PUT** request to the `/player/trade` endpoint. For example:
-
-```shell
-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'
-```
+ ```shell
+ cp env.sh.example env.sh
+ ```
-The request uses **Form Data** as the payload. The example request indicates that the seller's ID (`sellID`) is 1, the buyer's ID (`buyID`) is 2, the number of goods purchased (`amount`) is 10, and the number of coins consumed for purchase (`price`) is 100.
+5. Copy and paste the corresponding connection string into the `env.sh` file. The example result is as follows:
-The return value is whether the transaction is successful or not. When there are insufficient goods for the seller, insufficient coins for the buyer, or a database error, the [database transaction](/develop/dev-guide-transaction-overview.md) guarantees that the trade is not successful and no player's coins or goods are lost.
+ ```shell
+ export TIDB_HOST='{host}' # e.g. tidb.xxxx.clusters.tidb-cloud.com
+ export TIDB_PORT='4000'
+ export TIDB_USER='{user}' # e.g. root
+ export TIDB_PASSWORD='{password}'
+ export TIDB_DB_NAME='test'
+ export USE_SSL='false'
+ ```
-```json
-true
-```
+ Be sure to replace the placeholders `{}` with the connection parameters obtained from the connection dialog.
-### Step 6.3 Requests with Shell script
+6. Save the `env.sh` file.
-You can download [this shell script](https://github.com/pingcap-inc/tidb-example-java/blob/main/spring-jpa-hibernate/request.sh) for testing purposes. The script performs the following operations:
+
+
-1. Create 10 players in a loop.
-2. Get the information of players with the `id` of 1.
-3. Get a list of up to 3 players.
-4. Get a page of players with the `index` of 0 and the `size` of 2.
-5. Get the total number of players.
-6. Perform a transaction, where the player with the `id` of 1 is the seller and the player with the `id` of 2 is the buyer, and 10 `goods` are purchased at the cost of 100 `coins`.
+1. Run the following command to copy `env.sh.example` and rename it to `env.sh`:
-You can run this script with `make request` or `./request.sh`. The result should look like this:
+ ```shell
+ cp env.sh.example env.sh
+ ```
-```shell
-cheese@CheesedeMacBook-Pro spring-jpa-hibernate % make request
-./request.sh
-loop to create 10 players:
-1111111111
+2. Copy and paste the corresponding connection string into the `env.sh` file. The example result is as follows:
-get player 1:
-{"id":1,"coins":200,"goods":10}
+ ```shell
+ export TIDB_HOST='{host}'
+ export TIDB_PORT='4000'
+ export TIDB_USER='root'
+ export TIDB_PASSWORD='{password}'
+ export TIDB_DB_NAME='test'
+ export USE_SSL='false'
+ ```
-get players by limit 3:
-[{"id":1,"coins":200,"goods":10},{"id":2,"coins":0,"goods":30},{"id":3,"coins":100,"goods":20}]
+ Be sure to replace the placeholders `{}` with the connection parameters, and set the `USE_SSL` is `false`. If you are running TiDB locally, the default host address is `127.0.0.1`, and the password is empty.
-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}
+3. Save the `env.sh` file.
-get players count:
-14
+
+
-trade by two players:
-false
-```
+### Step 3: Run the code and check the result
-## Implementation details
+1. Execute the following command to run the sample code:
-This subsection describes the components in the sample application project.
+ ```shell
+ make
+ ```
-### Overview
+2. Check the [Expected-Output.txt](https://github.com/tidb-samples/tidb-java-springboot-jpa-quickstart/blob/main/Expected-Output.txt) to see if the output matches.
-The catalog tree for this example project is shown below (some incomprehensible parts are removed):
+## Sample code snippets
-```
-.
-├── 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
-```
+You can refer to the following sample code snippets to complete your own application development.
-- `pom.xml` declares the project's Maven configuration, such as dependencies and packaging.
-- `application.yml` declares the project's user configuration, such as database address, password, and database dialect used.
-- `App.java` is the entry point of the project.
-- `controller` is the package that exposes the HTTP interface to the outside.
-- `service` is the package that implements the interface and logic of the project.
-- `dao` is the package that implements the connection to the database and the persistence of the data.
-
-### Configuration
-
-This part briefly describes the Maven configuration in the `pom.xml` file and the user configuration in the `application.yml` file.
-
-#### Maven configuration
-
-The `pom.xml` file is a Maven configuration file that declares the project's Maven dependencies, packaging methods, and packaging information. You can replicate the process of generating this configuration file by [creating a blank application with the same dependency](#create-a-blank-application-with-the-same-dependency-optional), or copying it directly to your project.
-
-```xml
-
-