diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0fdfe63..3c84e3e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -40,6 +40,9 @@ jobs:
- name: 'mybatis'
language: 'java'
with_oceanbase_container: true
+ - name: 'spring-jdbc'
+ language: 'java'
+ with_oceanbase_container: true
- name: 'springboot'
language: 'java'
with_oceanbase_container: true
diff --git a/java/spring-jdbc/README-CN.md b/java/spring-jdbc/README-CN.md
new file mode 100644
index 0000000..16fc932
--- /dev/null
+++ b/java/spring-jdbc/README-CN.md
@@ -0,0 +1,142 @@
+# SpringJDBC 连接 OceanBase 指南
+[English](README.md) | 简体中文
+
+本文介绍如何通过 SpringJDBC 连接 OceanBase 数据库。
+由于 OceanBase 支持 MySQL 模式与 Oracle 模式,因此可以使用 MySQL 驱动连接 OceanBase。
+### 快速开始
+1. 在 pom.xml 中首先加入 MySQL 驱动,pom.xml 参考[OceanBase Spring JDBC 连接示例](https://www.oceanbase.com/docs/community-observer-cn-10000000000900916) 示例。
+
+```xml
+
+ org.springframework
+ spring-jdbc
+ 5.0.9.RELEASE
+
+
+ mysql
+ mysql-connector-java
+ 8.0.25
+
+
+ com.alibaba
+ druid
+ 1.2.18
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+```
+2.新建测试类,使用 Druid 连接池实例化 JdbcTemplate。
+
+```java
+public class OceanBaseSpringJdbcApplicationTest {
+ private static JdbcTemplate jdbcTemplate;
+ private String sql;
+
+ static {
+ Map map = new HashMap();
+ map.put("url", "jdbc:mysql://localhost:2881/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC");
+ map.put("driverClassName", "com.mysql.cj.jdbc.Driver");
+ map.put("username", "root@test");
+ map.put("password", "");
+ try {
+ Class.forName(map.get("driverClassName"));
+ jdbcTemplate = new JdbcTemplate(DruidDataSourceFactory.createDataSource(map));
+ //防止异常语句,没有这两句,会出错(Prevent abnormal statements, without which errors will occur)
+ jdbcTemplate.execute("set transaction_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之后,系统变量 tx_isolation 被更改为 transaction_isolation (After MySQL 8.0, the system variable tx_isolation was changed to transaction_isolation)
+ // jdbcTemplate.execute("set tx_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之前的版本使用 tx_isolation (tx_isolation is used in versions before MySQL 8.0)
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+```
+3.编写测试方法,执行 SQL 语句。
+
+```java
+package com.oceanbase.samples;
+
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.datasource.init.ScriptUtils;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * OceanBaseSpringJdbcApplication 简单单元测试
+ * Unit test for simple OceanBaseSpringJdbcApplication.
+ */
+public class OceanBaseSpringJdbcApplicationTest
+{
+ private static JdbcTemplate jdbcTemplate;
+ private String sql;
+ static {
+ Map map = new HashMap();
+ map.put("url", "jdbc:mysql://localhost:2881/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC");
+ map.put("driverClassName", "com.mysql.cj.jdbc.Driver");
+ map.put("username", "root@test");
+ map.put("password", "");
+ try {
+ Class.forName(map.get("driverClassName"));
+ jdbcTemplate = new JdbcTemplate(DruidDataSourceFactory.createDataSource(map));
+ //防止异常语句,没有这两句,会出错(Prevent abnormal statements, without which errors will occur)
+ jdbcTemplate.execute("set transaction_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之后,系统变量 tx_isolation 被更改为 transaction_isolation (After MySQL 8.0, the system variable tx_isolation was changed to transaction_isolation)
+ // jdbcTemplate.execute("set tx_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之前的版本使用 tx_isolation (tx_isolation is used in versions before MySQL 8.0)
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Before
+ public void initializeDatabase() {
+ Resource initSchema = new ClassPathResource("init.sql");
+ try {
+ // Execute init.sql script to create and populate the database
+ ScriptUtils.executeSqlScript(jdbcTemplate.getDataSource().getConnection(), initSchema);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to execute init.sql script", e);
+ }
+ }
+
+
+ // insert
+ @Test
+ public void testInsert() {
+ String sql = "INSERT INTO staff (name) VALUES (?)";
+ int rowsAffected = jdbcTemplate.update(sql, "New Staff");
+ System.out.println("rowsAffected: " + rowsAffected);
+ }
+
+ // select
+ @Test
+ public void testSelect() {
+ String sql = "SELECT * FROM staff WHERE name = ?";
+ RowMapper rowMapper = new RowMapper() {
+ @Override
+ public String mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return rs.getString("name");
+ }
+ };
+ List names = jdbcTemplate.query(sql, rowMapper, "New Staff");
+ System.out.println("names: " + names);
+ }
+}
+```
+
+修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。
+
+ ```bash
+ sh run.sh
+ ```
diff --git a/java/spring-jdbc/README.md b/java/spring-jdbc/README.md
new file mode 100644
index 0000000..46813eb
--- /dev/null
+++ b/java/spring-jdbc/README.md
@@ -0,0 +1,148 @@
+# Guide Connecting SpringJDBC to OceanBase
+English | [简体中文](README-CN.md)
+
+This document introduces how to connect to the OceanBase database through SpringJDBC.
+Since OceanBase supports MySQL mode and Oracle mode, you can use the MySQL driver to connect to OceanBase.
+
+## Quick Start
+
+1. add the MySQL driver dependency to the pom.xml file, referring to the [OceanBase Spring JDBC connection example](https://www.oceanbase.com/docs/community-observer-cn-10000000000900916).
+
+```xml
+
+ org.springframework
+ spring-jdbc
+ 5.0.9.RELEASE
+
+
+ mysql
+ mysql-connector-java
+ 8.0.25
+
+
+ com.alibaba
+ druid
+ 1.2.18
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+```
+
+2. Create a new test class and instantiate JdbcTemplate using the Druid connection pool.
+
+```java
+public class OceanBaseSpringJdbcApplicationTest {
+ private static JdbcTemplate jdbcTemplate;
+ private String sql;
+
+ static {
+ Map map = new HashMap();
+ map.put("url", "jdbc:mysql://localhost:2881/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC");
+ map.put("driverClassName", "com.mysql.cj.jdbc.Driver");
+ map.put("username", "root@test");
+ map.put("password", "");
+ try {
+ Class.forName(map.get("driverClassName"));
+ jdbcTemplate = new JdbcTemplate(DruidDataSourceFactory.createDataSource(map));
+ //防止异常语句,没有这两句,会出错(Prevent abnormal statements, without which errors will occur)
+ jdbcTemplate.execute("set transaction_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之后,系统变量 tx_isolation 被更改为 transaction_isolation (After MySQL 8.0, the system variable tx_isolation was changed to transaction_isolation)
+ // jdbcTemplate.execute("set tx_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之前的版本使用 tx_isolation (tx_isolation is used in versions before MySQL 8.0)
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+```
+
+3. Write any tests method to execute the SQL statement.
+
+```java
+// MySQL Type Create Table
+package com.oceanbase.samples;
+
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.datasource.init.ScriptUtils;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * OceanBaseSpringJdbcApplication 简单单元测试
+ * Unit test for simple OceanBaseSpringJdbcApplication.
+ */
+public class OceanBaseSpringJdbcApplicationTest
+{
+ private static JdbcTemplate jdbcTemplate;
+ private String sql;
+ static {
+ Map map = new HashMap();
+ map.put("url", "jdbc:mysql://localhost:2881/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC");
+ map.put("driverClassName", "com.mysql.cj.jdbc.Driver");
+ map.put("username", "root@test");
+ map.put("password", "");
+ try {
+ Class.forName(map.get("driverClassName"));
+ jdbcTemplate = new JdbcTemplate(DruidDataSourceFactory.createDataSource(map));
+ //防止异常语句,没有这两句,会出错(Prevent abnormal statements, without which errors will occur)
+ jdbcTemplate.execute("set transaction_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之后,系统变量 tx_isolation 被更改为 transaction_isolation (After MySQL 8.0, the system variable tx_isolation was changed to transaction_isolation)
+ // jdbcTemplate.execute("set tx_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之前的版本使用 tx_isolation (tx_isolation is used in versions before MySQL 8.0)
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Before
+ public void initializeDatabase() {
+ Resource initSchema = new ClassPathResource("init.sql");
+ try {
+ // Execute init.sql script to create and populate the database
+ ScriptUtils.executeSqlScript(jdbcTemplate.getDataSource().getConnection(), initSchema);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to execute init.sql script", e);
+ }
+ }
+
+
+ // insert
+ @Test
+ public void testInsert() {
+ String sql = "INSERT INTO staff (name) VALUES (?)";
+ int rowsAffected = jdbcTemplate.update(sql, "New Staff");
+ System.out.println("rowsAffected: " + rowsAffected);
+ }
+
+ // select
+ @Test
+ public void testSelect() {
+ String sql = "SELECT * FROM staff WHERE name = ?";
+ RowMapper rowMapper = new RowMapper() {
+ @Override
+ public String mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return rs.getString("name");
+ }
+ };
+ List names = jdbcTemplate.query(sql, rowMapper, "New Staff");
+ System.out.println("names: " + names);
+ }
+}
+
+```
+
+Modify the connection info in code, and use `run.sh` to run the example code.
+
+```bash
+sh run.sh
+```
diff --git a/java/spring-jdbc/pom.xml b/java/spring-jdbc/pom.xml
new file mode 100644
index 0000000..d5a79c8
--- /dev/null
+++ b/java/spring-jdbc/pom.xml
@@ -0,0 +1,40 @@
+
+ 4.0.0
+
+ com.oceanbase.samples
+ spring-jdbc
+ 1.0-SNAPSHOT
+
+ oceanbase-spring-jdbc
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ org.springframework
+ spring-jdbc
+ 5.0.9.RELEASE
+
+
+ mysql
+ mysql-connector-java
+ 8.0.25
+
+
+ com.alibaba
+ druid
+ 1.2.18
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
diff --git a/java/spring-jdbc/run.sh b/java/spring-jdbc/run.sh
new file mode 100644
index 0000000..0aa77a4
--- /dev/null
+++ b/java/spring-jdbc/run.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+mvn test
diff --git a/java/spring-jdbc/src/test/java/com/oceanbase/samples/OceanBaseSpringJdbcApplicationTest.java b/java/spring-jdbc/src/test/java/com/oceanbase/samples/OceanBaseSpringJdbcApplicationTest.java
new file mode 100644
index 0000000..c33e872
--- /dev/null
+++ b/java/spring-jdbc/src/test/java/com/oceanbase/samples/OceanBaseSpringJdbcApplicationTest.java
@@ -0,0 +1,76 @@
+package com.oceanbase.samples;
+
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.datasource.init.ScriptUtils;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * OceanBaseSpringJdbcApplication 简单单元测试
+ * Unit test for simple OceanBaseSpringJdbcApplication.
+ */
+public class OceanBaseSpringJdbcApplicationTest
+{
+ private static JdbcTemplate jdbcTemplate;
+ private String sql;
+ static {
+ Map map = new HashMap();
+ map.put("url", "jdbc:mysql://localhost:2881/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC");
+ map.put("driverClassName", "com.mysql.cj.jdbc.Driver");
+ map.put("username", "root@test");
+ map.put("password", "");
+ try {
+ Class.forName(map.get("driverClassName"));
+ jdbcTemplate = new JdbcTemplate(DruidDataSourceFactory.createDataSource(map));
+ //防止异常语句,没有这两句,会出错(Prevent abnormal statements, without which errors will occur)
+ jdbcTemplate.execute("set transaction_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之后,系统变量 tx_isolation 被更改为 transaction_isolation (After MySQL 8.0, the system variable tx_isolation was changed to transaction_isolation)
+ // jdbcTemplate.execute("set tx_isolation = 'READ-COMMITTED';"); // MySQL 8.0 之前的版本使用 tx_isolation (tx_isolation is used in versions before MySQL 8.0)
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Before
+ public void initializeDatabase() {
+ Resource initSchema = new ClassPathResource("init.sql");
+ try {
+ // Execute init.sql script to create and populate the database
+ ScriptUtils.executeSqlScript(jdbcTemplate.getDataSource().getConnection(), initSchema);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to execute init.sql script", e);
+ }
+ }
+
+
+ // insert
+ @Test
+ public void testInsert() {
+ String sql = "INSERT INTO staff (name) VALUES (?)";
+ int rowsAffected = jdbcTemplate.update(sql, "New Staff");
+ System.out.println("rowsAffected: " + rowsAffected);
+ }
+
+ // select
+ @Test
+ public void testSelect() {
+ String sql = "SELECT * FROM staff WHERE name = ?";
+ RowMapper rowMapper = new RowMapper() {
+ @Override
+ public String mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return rs.getString("name");
+ }
+ };
+ List names = jdbcTemplate.query(sql, rowMapper, "New Staff");
+ System.out.println("names: " + names);
+ }
+}
diff --git a/java/spring-jdbc/src/test/resources/init.sql b/java/spring-jdbc/src/test/resources/init.sql
new file mode 100644
index 0000000..6b74a56
--- /dev/null
+++ b/java/spring-jdbc/src/test/resources/init.sql
@@ -0,0 +1,12 @@
+CREATE DATABASE IF NOT EXISTS test;
+USE test;
+
+CREATE TABLE IF NOT EXISTS staff
+(
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(50)
+ );
+
+INSERT INTO staff (name) VALUES ('Bruce');
+INSERT INTO staff (name) VALUES ('Jack');
+INSERT INTO staff (name) VALUES ('Tom');