diff --git a/develop/dev-guide-choose-driver-or-orm.md b/develop/dev-guide-choose-driver-or-orm.md index 02eb0216dcc61..55e8e49a6234d 100644 --- a/develop/dev-guide-choose-driver-or-orm.md +++ b/develop/dev-guide-choose-driver-or-orm.md @@ -163,7 +163,7 @@ implementation 'org.mybatis:mybatis:3.5.9' implementation 'mysql:mysql-connector-java:5.1.49' ``` -For an example of using MyBatis to build a TiDB application, see [Build a simple CRUD app with TiDB and Mybatis](/develop/dev-guide-sample-application-java-mybatis.md). +For an example of using MyBatis to build a TiDB application, see [Build a simple CRUD app with TiDB and MyBatis](/develop/dev-guide-sample-application-java-mybatis.md). diff --git a/develop/dev-guide-sample-application-golang-gorm.md b/develop/dev-guide-sample-application-golang-gorm.md index f57de289619b1..fb49a0e222ad9 100644 --- a/develop/dev-guide-sample-application-golang-gorm.md +++ b/develop/dev-guide-sample-application-golang-gorm.md @@ -44,8 +44,6 @@ See [Create a TiDB Serverless cluster](/develop/dev-guide-build-cluster-in-cloud git clone https://github.com/pingcap-inc/tidb-example-golang.git ``` -Compared with GORM, the go-sql-driver/mysql implementation might be not a best practice, because you need to write error handling logic, close `*sql.Rows` manually and cannot reuse code easily, which makes your code slightly redundant. - The following instructions take `v1.23.5` as an example. To adapt TiDB transactions, write a toolkit [util](https://github.com/pingcap-inc/tidb-example-golang/tree/main/util) according to the following code: @@ -54,49 +52,26 @@ To adapt TiDB transactions, write a toolkit [util](https://github.com/pingcap-in package util import ( - "context" - "database/sql" + "gorm.io/gorm" ) -type TiDBSqlTx struct { - *sql.Tx - conn *sql.Conn - pessimistic bool -} - -func TiDBSqlBegin(db *sql.DB, pessimistic bool) (*TiDBSqlTx, error) { - ctx := context.Background() - conn, err := db.Conn(ctx) - if err != nil { - return nil, err +// TiDBGormBegin start a TiDB and Gorm transaction as a block. If no error is returned, the transaction will be committed. Otherwise, the transaction will be rolled back. +func TiDBGormBegin(db *gorm.DB, pessimistic bool, fc func(tx *gorm.DB) error) (err error) { + session := db.Session(&gorm.Session{}) + if session.Error != nil { + return session.Error } + if pessimistic { - _, err = conn.ExecContext(ctx, "set @@tidb_txn_mode=?", "pessimistic") + session = session.Exec("set @@tidb_txn_mode=pessimistic") } else { - _, err = conn.ExecContext(ctx, "set @@tidb_txn_mode=?", "optimistic") - } - if err != nil { - return nil, err - } - tx, err := conn.BeginTx(ctx, nil) - if err != nil { - return nil, err + session = session.Exec("set @@tidb_txn_mode=optimistic") } - return &TiDBSqlTx{ - conn: conn, - Tx: tx, - pessimistic: pessimistic, - }, nil -} -func (tx *TiDBSqlTx) Commit() error { - defer tx.conn.Close() - return tx.Tx.Commit() -} - -func (tx *TiDBSqlTx) Rollback() error { - defer tx.conn.Close() - return tx.Tx.Rollback() + if session.Error != nil { + return session.Error + } + return session.Transaction(fc) } ``` diff --git a/develop/dev-guide-sample-application-golang-sql-driver.md b/develop/dev-guide-sample-application-golang-sql-driver.md index 7b89fb6907a19..705164f482db8 100644 --- a/develop/dev-guide-sample-application-golang-sql-driver.md +++ b/develop/dev-guide-sample-application-golang-sql-driver.md @@ -77,7 +77,7 @@ CREATE TABLE player ( ); ``` -`sqldriver.go` is the main body of the `sqldriver`. TiDB is highly compatible with the MySQL protocol, so you need to initialize a MySQL source instance `db, err := sql.Open("mysql", dsn)` to connect to TiDB. Then, you can use `dao.go` to read, edit, add, and delete data. +`sqldriver.go` is the main body of the `sqldriver`. Compared with GORM, the go-sql-driver/mysql implementation might be not a best practice, because you need to write error handling logic, close `*sql.Rows` manually and cannot reuse code easily, which makes your code slightly redundant. TiDB is highly compatible with the MySQL protocol, so you need to initialize a MySQL source instance `db, err := sql.Open("mysql", dsn)` to connect to TiDB. Then, you can use `dao.go` to read, edit, add, and delete data. ```go package main diff --git a/develop/dev-guide-sample-application-java-hibernate.md b/develop/dev-guide-sample-application-java-hibernate.md index ef346f9c3150d..b5557d4f91a1f 100644 --- a/develop/dev-guide-sample-application-java-hibernate.md +++ b/develop/dev-guide-sample-application-java-hibernate.md @@ -8,6 +8,8 @@ summary: Learn how to build a simple CRUD application with TiDB and Hibernate. # Build a Simple CRUD App with TiDB and Hibernate +[Hibernate](https://hibernate.org/) is a popular open-source Java ORM, and it supports TiDB dialect starting from `v6.0.0.Beta2`, which fits TiDB features well. + This document describes how to use TiDB and Hibernate to build a simple CRUD application. > **Note:** @@ -44,7 +46,7 @@ git clone https://github.com/pingcap-inc/tidb-example-java.git Compared with Hibernate, 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. -Hibernate is a popular open-source Java ORM, and it supports TiDB dialect starting from `v6.0.0.Beta2`, which fits TiDB features well. The following instructions take `v6.0.0.Beta2` as an example. +The following instructions take `v6.0.0.Beta2` as an example. Change to the `plain-java-hibernate` directory: @@ -335,11 +337,7 @@ public class HibernateExample The following content introduces how to run the code step by step. -### Step 3.1 Table initialization - -No need to initialize tables manually. - -### Step 3.2 Modify parameters for TiDB Cloud +### Step 3.1 Modify parameters for TiDB Cloud If you are using a TiDB Serverless cluster, modify the `hibernate.connection.url`, `hibernate.connection.username`, `hibernate.connection.password` in `hibernate.cfg.xml`. @@ -403,20 +401,20 @@ In this case, you can modify the parameters as follows: ``` -### Step 3.3 Run +### Step 3.2 Run To run the code, you can run `make build` and `make run` respectively: ```shell make build # this command executes `mvn clean package` -make run # this command executes `java -jar target/plain-java-jdbc-0.0.1-jar-with-dependencies.jar` +make run # this command executes `java -jar target/plain-java-hibernate-0.0.1-jar-with-dependencies.jar` ``` Or you can use the native commands: ```shell mvn clean package -java -jar target/plain-java-jdbc-0.0.1-jar-with-dependencies.jar +java -jar target/plain-java-hibernate-0.0.1-jar-with-dependencies.jar ``` Or run the `make` command directly, which is a combination of `make build` and `make run`. diff --git a/develop/dev-guide-sample-application-java-mybatis.md b/develop/dev-guide-sample-application-java-mybatis.md index 36290ccb29789..625cb2de4cde7 100644 --- a/develop/dev-guide-sample-application-java-mybatis.md +++ b/develop/dev-guide-sample-application-java-mybatis.md @@ -1,14 +1,16 @@ --- -title: Build a Simple CRUD App with TiDB and Mybatis -summary: Learn how to build a simple CRUD application with TiDB and Mybatis. +title: Build a Simple CRUD App with TiDB and MyBatis +summary: Learn how to build a simple CRUD application with TiDB and MyBatis. --- -# Build a Simple CRUD App with TiDB and Mybatis +# Build a Simple CRUD App with TiDB and MyBatis -This document describes how to use TiDB and Mybatis to build a simple CRUD application. +[MyBatis](https://mybatis.org/mybatis-3/index.html) is a popular open-source Java class persistence framework. + +This document describes how to use TiDB and MyBatis to build a simple CRUD application. > **Note:** > @@ -42,9 +44,9 @@ See [Create a TiDB Serverless cluster](/develop/dev-guide-build-cluster-in-cloud git clone https://github.com/pingcap-inc/tidb-example-java.git ``` -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. +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. -Mybatis is a popular open-source Java class persistence framework. The following uses [MyBatis Generator](https://mybatis.org/generator/quickstart.html) as a Maven plugin to generate the persistence layer code. +The following uses [MyBatis Generator](https://mybatis.org/generator/quickstart.html) as a Maven plugin to generate the persistence layer code. Change to the `plain-java-mybatis` directory: @@ -84,9 +86,9 @@ 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. +- `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. -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. +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. ```xml @@ -200,7 +202,7 @@ Once included in the Maven plugin, you can delete the old generated files and ma > > 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. -`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. +`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. ```java package com.pingcap.model; @@ -248,7 +250,7 @@ public class Player { } ``` -`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. +`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. ```java package com.pingcap.model; @@ -270,7 +272,7 @@ public interface PlayerMapper { } ``` -`PlayerMapper.xml` is a mapping XML file generated using Mybatis Generator. Mybatis uses this to automatically generate the implementation class of the `PlayerMapper` interface. +`PlayerMapper.xml` is a mapping XML file generated using MyBatis Generator. MyBatis uses this to automatically generate the implementation class of the `PlayerMapper` interface. ```xml @@ -348,7 +350,7 @@ public interface PlayerMapper { ``` -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`. +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`. ```sql USE test; @@ -362,7 +364,7 @@ CREATE TABLE player ( ); ``` -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. +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. Define the added interface in `PlayerMapperEx.java`: @@ -419,7 +421,7 @@ Define the mapping rules in `PlayerMapperEx.xml`: ``` -`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. +`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; @@ -613,7 +615,7 @@ 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: +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 @@ -738,4 +740,4 @@ Or run the `make` command directly, which is a combination of `make prepare`, `m ## Step 4. Expected output -[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 +[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 diff --git a/develop/dev-guide-sample-application-python-peewee.md b/develop/dev-guide-sample-application-python-peewee.md index 96f116188d14f..da13997e5dc88 100644 --- a/develop/dev-guide-sample-application-python-peewee.md +++ b/develop/dev-guide-sample-application-python-peewee.md @@ -168,7 +168,7 @@ trade_example() Compared with using drivers directly, peewee provides an abstraction for the specific details of different databases when you create a database connection. In addition, peewee encapsulates some operations such as session management and CRUD of basic objects, which greatly simplifies the code. -The `Player` class is a mapping of a table to attributes in the application. Each attribute of `Player` corresponds to a field in the `player` table. To provide SQLAlchemy with more information, the attribute is defined as `id = Column(String(36), primary_key=True)` to indicate the field type and its additional attributes. For example, `id = Column(String(36), primary_key=True)` indicates that the `id` attribute is `String` type, the corresponding field in database is `VARCHAR` type, the length is `36`, and it is a primary key. +The `Player` class is a mapping of a table to attributes in the application. Each attribute of `Player` corresponds to a field in the `player` table. To provide peewee with more information, the attribute is defined as `id = CharField(max_length=36, primary_key=True)` to indicate the field type and its additional attributes. For example, `id = CharField(max_length=36, primary_key=True)` indicates that the `id` attribute is `String` type, the corresponding field in database is `VARCHAR` type, the length is `36`, and it is a primary key. For more information about how to use peewee, refer to [peewee documentation](http://docs.peewee-orm.com/en/latest/). diff --git a/develop/dev-guide-third-party-support.md b/develop/dev-guide-third-party-support.md index 84365c51c39b8..b6f07edf42e59 100644 --- a/develop/dev-guide-third-party-support.md +++ b/develop/dev-guide-third-party-support.md @@ -187,7 +187,7 @@ If you encounter problems when connecting to TiDB using the tools listed in this v3.5.10 Full N/A - Build a Simple CRUD App with TiDB and Mybatis + Build a Simple CRUD App with TiDB and MyBatis Spring Data JPA