From d14b8bd14b74d20de07fb4820cee45afc084dbb0 Mon Sep 17 00:00:00 2001 From: Icemap Date: Mon, 4 Sep 2023 16:49:00 +0800 Subject: [PATCH] feat: mybatis doc translate --- ...v-guide-sample-application-java-mybatis.md | 824 +++++------------- 1 file changed, 200 insertions(+), 624 deletions(-) diff --git a/develop/dev-guide-sample-application-java-mybatis.md b/develop/dev-guide-sample-application-java-mybatis.md index 625cb2de4cde7..1d2f3f044b5b4 100644 --- a/develop/dev-guide-sample-application-java-mybatis.md +++ b/develop/dev-guide-sample-application-java-mybatis.md @@ -1,645 +1,195 @@ --- -title: Build a Simple CRUD App with TiDB and MyBatis -summary: Learn how to build a simple CRUD application with TiDB and MyBatis. +title: Connect to TiDB with MyBatis +summary: Learn how to connect to TiDB using MyBatis. This tutorial gives Java sample code snippets that work with TiDB using MyBatis. --- - - +# Connect to TiDB with MyBatis -# Build a Simple CRUD App with TiDB and MyBatis +TiDB is a MySQL-compatible database. [MyBatis](https://mybatis.org/mybatis-3/index.html) is a popular open-source Java application persistence framework. -[MyBatis](https://mybatis.org/mybatis-3/index.html) is a popular open-source Java class persistence framework. +In this tutorial, you can learn how to use TiDB and MyBatis to accomplish the following tasks: -This document describes how to use TiDB and MyBatis to build a simple CRUD application. +- Set up your environment. +- Connect to your TiDB cluster using MyBatis. +- Build and run your application. Optionally, you can find [sample code snippets](#sample-code-snippets) for basic CRUD operations. > **Note:** > -> It is recommended to use Java 8 or a later Java version. +> This tutorial works with TiDB Serverless, TiDB Dedicated, and TiDB Self-Hosted. -## Step 1. Launch your TiDB cluster +## Prerequisites - - -The following introduces how to start a TiDB cluster. +To complete this tutorial, you need: -**Use a TiDB Serverless cluster** +- It is recommended to use **Java Development Kit** (JDK) **17** or higher. You can choose between [OpenJDK](https://openjdk.org/) and [Oracle JDK](https://www.oracle.com/hk/java/technologies/downloads/) based on your company's or personal preferences. +- [Maven](https://maven.apache.org/install.html) **3.8** or higher is required. +- [Git](https://git-scm.com/downloads). +- A TiDB cluster. -For detailed steps, see [Create a TiDB Serverless cluster](/develop/dev-guide-build-cluster-in-cloud.md#step-1-create-a-tidb-serverless-cluster). + -**Use a local cluster** +**If you don't have a TiDB cluster, you can create one as follows:** -For detailed steps, see [Deploy a local test cluster](/quick-start-with-tidb.md#deploy-a-local-test-cluster) or [Deploy a TiDB Cluster Using TiUP](/production-deployment-using-tiup.md). +- (Recommended) Follow [Creating a TiDB Serverless cluster](/develop/dev-guide-build-cluster-in-cloud.md) to create your own TiDB Cloud cluster. +- Follow [Deploy a local test TiDB cluster](/quick-start-with-tidb.md#deploy-a-local-test-cluster) or [Deploy a production TiDB cluster](/production-deployment-using-tiup.md) to create a local cluster. - -See [Create a TiDB Serverless cluster](/develop/dev-guide-build-cluster-in-cloud.md#step-1-create-a-tidb-serverless-cluster). +**If you don't have a TiDB cluster, you can create one as follows:** - +- (Recommended) Follow [Creating a TiDB Serverless cluster](/develop/dev-guide-build-cluster-in-cloud.md) to create your own TiDB Cloud cluster. +- Follow [Deploy a local test TiDB cluster](https://docs.pingcap.com/tidb/stable/quick-start-with-tidb#deploy-a-local-test-cluster) or [Deploy a production TiDB cluster](https://docs.pingcap.com/tidb/stable/production-deployment-using-tiup) to create a local cluster. -## Step 2. Get the code + -```shell -git clone https://github.com/pingcap-inc/tidb-example-java.git -``` +## Run the sample app to connect to TiDB -Compared with [MyBatis](https://mybatis.org/mybatis-3/index.html), the JDBC implementation might be not a best practice, because you need to write error handling logic manually and cannot reuse code easily, which makes your code slightly redundant. +This section demonstrates how to run the sample application code and connect to TiDB. -The following uses [MyBatis Generator](https://mybatis.org/generator/quickstart.html) as a Maven plugin to generate the persistence layer code. +### Step 1: Clone the sample app repository -Change to the `plain-java-mybatis` directory: +Run the following commands in your terminal window to clone the sample code repository: ```shell -cd plain-java-mybatis +git clone https://github.com/tidb-samples/tidb-java-mybatis-quickstart.git +cd tidb-java-mybatis-quickstart ``` -The structure of this directory is as follows: +### Step 2: Configure connection information -``` -. -├── Makefile -├── pom.xml -└── src - └── main - ├── java - │   └── com - │   └── pingcap - │   ├── MybatisExample.java - │   ├── dao - │   │   └── PlayerDAO.java - │   └── model - │   ├── Player.java - │   ├── PlayerMapper.java - │   └── PlayerMapperEx.java - └── resources - ├── dbinit.sql - ├── log4j.properties - ├── mapper - │   ├── PlayerMapper.xml - │   └── PlayerMapperEx.xml - ├── mybatis-config.xml - └── mybatis-generator.xml -``` +Connect to your TiDB cluster depending on the TiDB deployment option you've selected. -The automatically generated files are: + +
-- `src/main/java/com/pingcap/model/Player.java`: The `Player` entity class. -- `src/main/java/com/pingcap/model/PlayerMapper.java`: The interface of `PlayerMapper`. -- `src/main/resources/mapper/PlayerMapper.xml`: The XML mapping of `Player`. MyBatis uses this configuration to automatically generate the implementation class of the `PlayerMapper` interface. +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. -The strategy for generating these files is written in `mybatis-generator.xml`, which is the configuration file for [MyBatis Generator](https://mybatis.org/generator/quickstart.html). There are comments in the following configuration file to describe how to use it. +2. Click **Connect** in the upper-right corner. A connection dialog is displayed. -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` +3. Ensure the configurations in the connection dialog match your operating environment. -`mybatis-generator.xml` is included in `pom.xml` as the configuration of `mybatis-generator-maven-plugin`. + - **Endpoint Type** is set to `Public` + - **Connect With** is set to `General` + - **Operating System** matches your environment. -```xml - - org.mybatis.generator - mybatis-generator-maven-plugin - 1.4.1 - - src/main/resources/mybatis-generator.xml - true - true - - - - - - mysql - mysql-connector-java - 5.1.49 - - - -``` + > **Tip:** + > + > If your program is running in Windows Subsystem for Linux (WSL), switch to the corresponding Linux distribution. -Once included in the Maven plugin, you can delete the old generated files and make new ones using `mvn mybatis-generate`. Or you can use `make gen` to delete the old file and generate a new one at the same time. +4. Click **Create password** to create a random password. -> **Note:** -> -> The property `configuration.overwrite` in `mybatis-generator.xml` only ensures that the generated Java code files are overwritten. But the XML mapping files are still written as appended. Therefore, it is recommended to delete the old file before Mybaits Generator generating a new one. + > **Tip:** + > + > If you have created a password before, you can either use the original password or click **Reset password** to generate a new one. -`Player.java` is a data entity class file generated using MyBatis Generator, which is a mapping of database tables in the application. Each property of the `Player` class corresponds to a field in the `player` table. +5. Run the following command to copy `env.sh.example` and rename it to `env.sh`: -```java -package com.pingcap.model; + ```shell + cp env.sh.example env.sh + ``` -public class Player { - private String id; +6. Copy and paste the corresponding connection string into the `env.sh` file. The example result is as follows: - private Integer coins; + ```shell + 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' + ``` - private Integer goods; + Please make sure to replace the placeholders in `{}` with the values obtained from your connection dialog. - public Player(String id, Integer coins, Integer goods) { - this.id = id; - this.coins = coins; - this.goods = goods; - } + TiDB Serverless requires a TLS (SSL) connection, so the value of `USE_SSL` should be set to `true`. - public Player() { - super(); - } +7. Save the `env.sh` file. - public String getId() { - return id; - } + +
- public void setId(String id) { - this.id = id; - } +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. - public Integer getCoins() { - return coins; - } +2. Click **Connect** in the upper-right corner. A connection dialog is displayed. - public void setCoins(Integer coins) { - this.coins = coins; - } +3. Click **Allow Access from Anywhere** and then click **Download TiDB cluster CA** to download the CA certificate. - public Integer getGoods() { - return goods; - } + 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). - public void setGoods(Integer goods) { - this.goods = goods; - } -} -``` +4. Run the following command to copy `env.sh.example` and rename it to `env.sh`: -`PlayerMapper.java` is a mapping interface file generated using MyBatis Generator. This file only defines the interface, and the implementation classes of interface are automatically generated using XML or annotations. + ```shell + cp env.sh.example env.sh + ``` -```java -package com.pingcap.model; +5. Copy and paste the corresponding connection string into the `env.sh` file. The example result is as follows: -import com.pingcap.model.Player; + ```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' + ``` -public interface PlayerMapper { - int deleteByPrimaryKey(String id); + Be sure to replace the placeholders `{}` with the connection parameters obtained from the connection dialog. - int insert(Player row); +6. Save the `env.sh` file. - int insertSelective(Player row); +
+
- Player selectByPrimaryKey(String id); +1. Run the following command to copy `env.sh.example` and rename it to `env.sh`: - int updateByPrimaryKeySelective(Player row); + ```shell + cp env.sh.example env.sh + ``` - int updateByPrimaryKey(Player row); -} -``` +2. Copy and paste the corresponding connection string into the `env.sh` file. The example result is as follows: -`PlayerMapper.xml` is a mapping XML file generated using MyBatis Generator. MyBatis uses this to automatically generate the implementation class of the `PlayerMapper` interface. + ```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' + ``` -```xml - - - - - - - - - - - - id, coins, goods - - - - delete from player - where id = #{id,jdbcType=VARCHAR} - - - insert into player (id, coins, goods - ) - values (#{id,jdbcType=VARCHAR}, #{coins,jdbcType=INTEGER}, #{goods,jdbcType=INTEGER} - ) - - - insert into player - - - id, - - - coins, - - - goods, - - - - - #{id,jdbcType=VARCHAR}, - - - #{coins,jdbcType=INTEGER}, - - - #{goods,jdbcType=INTEGER}, - - - - - update player - - - coins = #{coins,jdbcType=INTEGER}, - - - goods = #{goods,jdbcType=INTEGER}, - - - where id = #{id,jdbcType=VARCHAR} - - - update player - set coins = #{coins,jdbcType=INTEGER}, - goods = #{goods,jdbcType=INTEGER} - where id = #{id,jdbcType=VARCHAR} - - -``` + 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. -Since MyBatis Generator needs to generate the source code from the table definition, the table needs to be created first. To create the table, you can use `dbinit.sql`. +3. Save the `env.sh` file. -```sql -USE test; -DROP TABLE IF EXISTS player; +
+ -CREATE TABLE player ( - `id` VARCHAR(36), - `coins` INTEGER, - `goods` INTEGER, - PRIMARY KEY (`id`) -); -``` +### Step 3: Run the code and check the result -Split the interface `PlayerMapperEx` additionally to extend from `PlayerMapper` and write a matching `PlayerMapperEx.xml` file. Avoid changing `PlayerMapper.java` and `PlayerMapper.xml` directly. This is to avoid overwrite by MyBatis Generator. +1. Execute the following command to run the sample code: -Define the added interface in `PlayerMapperEx.java`: + ```shell + make + ``` -```java -package com.pingcap.model; +2. Check the [Expected-Output.txt](https://github.com/tidb-samples/tidb-java-mybatis-quickstart/blob/main/Expected-Output.txt) to see if the output matches. -import java.util.List; +## Sample code snippets -public interface PlayerMapperEx extends PlayerMapper { - Player selectByPrimaryKeyWithLock(String id); +You can refer to the following sample code snippets to complete your own application development. - List selectByLimit(Integer limit); +For complete sample code and how to run it, check out the [tidb-samples/tidb-java-mybatis-quickstart](https://github.com/tidb-samples/tidb-java-mybatis-quickstart) repository. - Integer count(); -} -``` +### Connect to TiDB -Define the mapping rules in `PlayerMapperEx.xml`: - -```xml - - - - - - - - - - - - id, coins, goods - - - - - - - - - -``` - -`PlayerDAO.java` is a class used to manage data, in which `DAO` means [Data Access Object](https://en.wikipedia.org/wiki/Data_access_object). The class defines a set of data manipulation methods for writing data. In it, MyBatis encapsulates a large number of operations such as object mapping and CRUD of basic objects, which greatly simplifies the code. - -```java -package com.pingcap.dao; - -import com.pingcap.model.Player; -import com.pingcap.model.PlayerMapperEx; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; - -import java.util.List; -import java.util.function.Function; - -public class PlayerDAO { - public static class NotEnoughException extends RuntimeException { - public NotEnoughException(String message) { - super(message); - } - } - - // Run SQL code in a way that automatically handles the - // transaction retry logic, so we don't have to duplicate it in - // various places. - public Object runTransaction(SqlSessionFactory sessionFactory, Function fn) { - Object resultObject = null; - SqlSession session = null; - - try { - // open a session with autoCommit is false - session = sessionFactory.openSession(false); - - // get player mapper - PlayerMapperEx playerMapperEx = session.getMapper(PlayerMapperEx.class); - - resultObject = fn.apply(playerMapperEx); - session.commit(); - System.out.println("APP: COMMIT;"); - } catch (Exception e) { - if (e instanceof NotEnoughException) { - System.out.printf("APP: ROLLBACK BY LOGIC; \n%s\n", e.getMessage()); - } else { - System.out.printf("APP: ROLLBACK BY ERROR; \n%s\n", e.getMessage()); - } - - if (session != null) { - session.rollback(); - } - } finally { - if (session != null) { - session.close(); - } - } - - return resultObject; - } - - public Function createPlayers(List players) { - return playerMapperEx -> { - Integer addedPlayerAmount = 0; - for (Player player: players) { - playerMapperEx.insert(player); - addedPlayerAmount ++; - } - System.out.printf("APP: createPlayers() --> %d\n", addedPlayerAmount); - return addedPlayerAmount; - }; - } - - public Function buyGoods(String sellId, String buyId, Integer amount, Integer price) { - return playerMapperEx -> { - Player sellPlayer = playerMapperEx.selectByPrimaryKeyWithLock(sellId); - Player buyPlayer = playerMapperEx.selectByPrimaryKeyWithLock(buyId); - - if (buyPlayer == null || sellPlayer == null) { - throw new NotEnoughException("sell or buy player not exist"); - } - - if (buyPlayer.getCoins() < price || sellPlayer.getGoods() < amount) { - throw new NotEnoughException("coins or goods not enough, rollback"); - } - - int affectRows = 0; - buyPlayer.setGoods(buyPlayer.getGoods() + amount); - buyPlayer.setCoins(buyPlayer.getCoins() - price); - affectRows += playerMapperEx.updateByPrimaryKey(buyPlayer); - - sellPlayer.setGoods(sellPlayer.getGoods() - amount); - sellPlayer.setCoins(sellPlayer.getCoins() + price); - affectRows += playerMapperEx.updateByPrimaryKey(sellPlayer); - - System.out.printf("APP: buyGoods --> sell: %s, buy: %s, amount: %d, price: %d\n", sellId, buyId, amount, price); - return affectRows; - }; - } - - public Function getPlayerByID(String id) { - return playerMapperEx -> playerMapperEx.selectByPrimaryKey(id); - } - - public Function printPlayers(Integer limit) { - return playerMapperEx -> { - List players = playerMapperEx.selectByLimit(limit); - - for (Player player: players) { - System.out.println("\n[printPlayers]:\n" + player); - } - return 0; - }; - } - - public Function countPlayers() { - return PlayerMapperEx::count; - } -} -``` - -`MybatisExample` is the main class of the `plain-java-mybatis` sample application. It defines the entry functions: - -```java -package com.pingcap; - -import com.pingcap.dao.PlayerDAO; -import com.pingcap.model.Player; -import org.apache.ibatis.io.Resources; -import org.apache.ibatis.session.SqlSessionFactory; -import org.apache.ibatis.session.SqlSessionFactoryBuilder; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; - -public class MybatisExample { - public static void main( String[] args ) throws IOException { - // 1. Create a SqlSessionFactory based on our mybatis-config.xml configuration - // file, which defines how to connect to the database. - InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); - SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); - - // 2. And then, create DAO to manager your data - PlayerDAO playerDAO = new PlayerDAO(); - - // 3. Run some simple examples. - - // Create a player who has 1 coin and 1 goods. - playerDAO.runTransaction(sessionFactory, playerDAO.createPlayers( - Collections.singletonList(new Player("test", 1, 1)))); - - // Get a player. - Player testPlayer = (Player)playerDAO.runTransaction(sessionFactory, playerDAO.getPlayerByID("test")); - System.out.printf("PlayerDAO.getPlayer:\n => id: %s\n => coins: %s\n => goods: %s\n", - testPlayer.getId(), testPlayer.getCoins(), testPlayer.getGoods()); - - // Count players amount. - Integer count = (Integer)playerDAO.runTransaction(sessionFactory, playerDAO.countPlayers()); - System.out.printf("PlayerDAO.countPlayers:\n => %d total players\n", count); - - // Print 3 players. - playerDAO.runTransaction(sessionFactory, playerDAO.printPlayers(3)); - - // 4. Getting further. - - // Player 1: id is "1", has only 100 coins. - // Player 2: id is "2", has 114514 coins, and 20 goods. - Player player1 = new Player("1", 100, 0); - Player player2 = new Player("2", 114514, 20); - - // Create two players "by hand", using the INSERT statement on the backend. - int addedCount = (Integer)playerDAO.runTransaction(sessionFactory, - playerDAO.createPlayers(Arrays.asList(player1, player2))); - System.out.printf("PlayerDAO.createPlayers:\n => %d total inserted players\n", addedCount); - - // Player 1 wants to buy 10 goods from player 2. - // It will cost 500 coins, but player 1 cannot afford it. - System.out.println("\nPlayerDAO.buyGoods:\n => this trade will fail"); - Integer updatedCount = (Integer)playerDAO.runTransaction(sessionFactory, - playerDAO.buyGoods(player2.getId(), player1.getId(), 10, 500)); - System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount); - - // So player 1 has to reduce the incoming quantity to two. - System.out.println("\nPlayerDAO.buyGoods:\n => this trade will success"); - updatedCount = (Integer)playerDAO.runTransaction(sessionFactory, - playerDAO.buyGoods(player2.getId(), player1.getId(), 2, 100)); - System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount); - } -} -``` - -## Step 3. Run the code - -The following content introduces how to run the code step by step. - -### Step 3.1 Table initialization - -When using MyBatis, you need to initialize the database tables manually. If you are using a local cluster, and MySQL client has been installed locally, you can run it directly in the `plain-java-mybatis` directory: - -```shell -make prepare -``` - -Or you can execute the following command: - -```shell -mysql --host 127.0.0.1 --port 4000 -u root < src/main/resources/dbinit.sql -``` - -If you are using a non-local cluster or MySQL client has not been installed, connect to your cluster and run the statement in the `src/main/resources/dbinit.sql` file. - -### Step 3.2 Modify parameters for TiDB Cloud - -If you are using a TiDB Serverless cluster, modify the `dataSource.url`, `dataSource.username`, `dataSource.password` in `mybatis-config.xml`. +Write config file `mybatis-config.xml`: ```xml - - @@ -648,96 +198,122 @@ If you are using a TiDB Serverless cluster, modify the `dataSource.url`, `dataSo - - - - - - - - + + + + - - - + - ``` -Suppose that the password you set is `123456`, and the connection parameters you get from the cluster details page are the following: +Please replace `${tidb_jdbc_url}`, `${tidb_user}`, `${tidb_password}`, etc., with the actual values of your TiDB cluster. Also, replace the value of `${mapper_location}` with the location of your mapper XML configuration file. If you have multiple mapper XML configuration files, you need to add multiple `` tags. Afterward, write the following function: -- Endpoint: `xxx.tidbcloud.com` -- Port: `4000` -- User: `2aEp24QWEDLqRFs.root` +```java +public SqlSessionFactory getSessionFactory() { + InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); + SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); +} +``` -In this case, you can modify the parameters in `dataSource` node as follows: +### Insert data + +Add a node in the mapper XML and add a function with the same name in the interface class configured in the `mapper.namespace` attribute of the XML configuration file: ```xml - + + + + + insert into player (id, coins, goods) + values (#{id,jdbcType=VARCHAR}, #{coins,jdbcType=INTEGER}, #{goods,jdbcType=INTEGER}) + + +``` - +For more information, refer to [Insert data](/develop/dev-guide-insert-data.md). - ... - - - - - - - - ... +### Query data - +Add a node in the mapper XML and add a function with the same name in the interface class configured in the `mapper.namespace` attribute of the XML configuration file. Specifically, if you use `resultMap` as the return type in MyBatis query functions, make sure to pay extra attention to the correctness of the `` node configuration in the file. + +```xml + + + + + + + + + + + + + ``` -### Step 3.3 Run +For more information, refer to [Query data](/develop/dev-guide-get-data-from-single-table.md). -To run the code, you can run `make prepare`, `make gen`, `make build` and `make run` respectively: +### Update data -```shell -make prepare -# this command executes : -# - `mysql --host 127.0.0.1 --port 4000 -u root < src/main/resources/dbinit.sql` -# - `mysql --host 127.0.0.1 --port 4000 -u root -e "TRUNCATE test.player"` - -make gen -# this command executes : -# - `rm -f src/main/java/com/pingcap/model/Player.java` -# - `rm -f src/main/java/com/pingcap/model/PlayerMapper.java` -# - `rm -f src/main/resources/mapper/PlayerMapper.xml` -# - `mvn mybatis-generator:generate` - -make build # this command executes `mvn clean package` -make run # this command executes `java -jar target/plain-java-mybatis-0.0.1-jar-with-dependencies.jar` +Add a node in the mapper XML and add a function with the same name in the interface class configured in the `mapper.namespace` attribute of the XML configuration file: + +```xml + + + + + update player + set coins = #{coins,jdbcType=INTEGER}, + goods = #{goods,jdbcType=INTEGER} + where id = #{id,jdbcType=VARCHAR} + + ``` -Or you can use the native commands: +For more information, refer to [Update data](/develop/dev-guide-update-data.md). -```shell -mysql --host 127.0.0.1 --port 4000 -u root < src/main/resources/dbinit.sql -mysql --host 127.0.0.1 --port 4000 -u root -e "TRUNCATE test.player" -rm -f src/main/java/com/pingcap/model/Player.java -rm -f src/main/java/com/pingcap/model/PlayerMapper.java -rm -f src/main/resources/mapper/PlayerMapper.xml -mvn mybatis-generator:generate -mvn clean package -java -jar target/plain-java-mybatis-0.0.1-jar-with-dependencies.jar +### Delete data + +Add a node in the mapper XML and add a function with the same name in the interface class configured in the `mapper.namespace` attribute of the XML configuration file: + +```xml + + + + + delete from player + where id = #{id,jdbcType=VARCHAR} + + ``` -Or run the `make` command directly, which is a combination of `make prepare`, `make gen`, `make build` and `make run`. +For more information, refer to [Delete data](/develop/dev-guide-delete-data.md). + +## Useful notes + +## Next steps + +- Learn more usage of `MySQL Connector/J` from [the documentation of MySQL Connector/J](https://dev.mysql.com/doc/connector-j/8.1/en/). +- Learn the best practices for TiDB application development with the chapters in the [Developer guide](/develop/dev-guide-overview.md), such as [Insert data](/develop/dev-guide-insert-data.md), [Update data](/develop/dev-guide-update-data.md), [Delete data](/develop/dev-guide-delete-data.md), [Single table reading](/develop/dev-guide-get-data-from-single-table.md), [Transactions](/develop/dev-guide-transaction-overview.md), and [SQL performance optimization](/develop/dev-guide-optimize-sql-overview.md). +- Learn through the professional [TiDB developer courses](https://www.pingcap.com/education/) and earn [TiDB certifications](https://www.pingcap.com/education/certification/) after passing the exam. +- Additionally, we offer courses tailored for Java developers: [Working with TiDB from Java](https://eng.edu.pingcap.com/catalog/info/id:212). -## Step 4. Expected output +## Need help? -[MyBatis Expected Output](https://github.com/pingcap-inc/tidb-example-java/blob/main/Expected-Output.md#plain-java-mybatis) \ No newline at end of file +Ask questions on the [Discord](https://discord.gg/vYU9h56kAX), or [create a support ticket](https://support.pingcap.com/).