diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c11d157..644679e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -29,6 +29,9 @@ jobs:
language: 'python'
- name: 'mysql-connector-python'
language: 'python'
+ - name: 'mybatisplus-java'
+ language: 'java'
+ with_oceanbase_container: false
uses: ./.github/workflows/basic-ci.yml
with:
module: ${{ matrix.module.name }}
diff --git a/java/mybatisplus-java/README-CN.md b/java/mybatisplus-java/README-CN.md
new file mode 100644
index 0000000..9b17b54
--- /dev/null
+++ b/java/mybatisplus-java/README-CN.md
@@ -0,0 +1,108 @@
+# MybatisPlus Java
+
+[English](README.md) | 简体中文
+
+本文介绍了如何通过 `mybatisplus-java` 启动和测试 OceanBase Docker
+容器,更多详细信息可以参见 https://github.com/baomidou/mybatis-plus
+以及 https://java.testcontainers.org/modules/databases/oceanbase 。
+
+## 快速开始
+
+将 OceanBase 驱动、TestContainers OceanBase、MybatisPlusStarter、SpringBootStarter Test 模块添加到 POM。
+
+```xml
+
+
+
+ com.oceanbase
+ oceanbase-client
+ 2.4.9
+
+
+ org.testcontainers
+ oceanbase
+ 1.19.7
+ test
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.6
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.testcontainers
+ testcontainers
+ 1.19.7
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ 1.19.7
+ test
+
+
+```
+
+以 [MybatisPlusJavaApplicationTests.java](src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplicationTests.java)
+代码为例。
+
+以下代码不仅实现了`OceanBaseCEContainer`的生命周期管理。 它将在执行任何测试用例之前启动容器实例,并在执行所有测试用例后停止容器,而且还在期间使用
+ScriptUtils.executeSqlScript 执行数据库初始化 SQL。
+
+```java
+
+@SpringBootTest
+@Testcontainers
+class MybatisPlusJavaApplicationTests {
+
+ @Container
+ public static OceanBaseCEContainer oceanBaseContainer = new OceanBaseCEContainer(DockerImageName.parse("oceanbase/oceanbase-ce:latest"))
+ .withEnv("MODE", "slim")
+ .withEnv("FASTBOOT", "true");
+ @Autowired
+ private PersonMapper personMapper;
+
+ @DynamicPropertySource
+ static void oceanBaseProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.datasource.url", oceanBaseContainer::getJdbcUrl);
+ registry.add("spring.datasource.username", oceanBaseContainer::getUsername);
+ registry.add("spring.datasource.password", oceanBaseContainer::getPassword);
+ registry.add("spring.datasource.driver-class-name", oceanBaseContainer::getDriverClassName);
+ }
+
+ @BeforeAll
+ static void setup(@Autowired DataSource dataSource) throws Exception {
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+ assertNotNull(jdbcTemplate.getDataSource());
+ ScriptUtils.executeSqlScript(jdbcTemplate.getDataSource().getConnection(), new ClassPathResource("init.sql"));
+ }
+}
+```
+
+您可以在测试用例中使用 MybatisPlus 操作 OceanBase 实例,如下所示:
+
+```java
+
+@Test
+void testSelectList() {
+ List persons = personMapper.selectList(null);
+ assertFalse(persons.isEmpty());
+}
+```
diff --git a/java/mybatisplus-java/README.md b/java/mybatisplus-java/README.md
new file mode 100644
index 0000000..5d4b068
--- /dev/null
+++ b/java/mybatisplus-java/README.md
@@ -0,0 +1,110 @@
+# MybatisPlus Java
+
+English | [简体中文](README-CN.md)
+
+This document introduces how to start and test the OceanBase Docker container using `mybatisplus-java`. For more
+details, please see https://github.com/baomidou/mybatis-plus
+and https://java.testcontainers.org/modules/databases/oceanbase.
+
+## Quick Start
+
+Add the OceanBase driver, TestContainers OceanBase, MybatisPlusStarter, and SpringBootStarter Test modules to your POM.
+
+```xml
+
+
+
+ com.oceanbase
+ oceanbase-client
+ 2.4.9
+
+
+ org.testcontainers
+ oceanbase
+ 1.19.7
+ test
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.6
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.testcontainers
+ testcontainers
+ 1.19.7
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ 1.19.7
+ test
+
+
+```
+
+Take the code
+in [MybatisPlusJavaApplicationTests.java](src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplicationTests.java)
+as an example.
+
+The following code not only implements lifecycle management for the `OceanBaseCEContainer`. It will start the container
+instance before executing any test cases and stop it after all test cases are completed, and also uses
+ScriptUtils.executeSqlScript to perform database initialization SQL during the period.
+
+```java
+
+@SpringBootTest
+@Testcontainers
+class MybatisPlusJavaApplicationTests {
+
+ @Container
+ public static OceanBaseCEContainer oceanBaseContainer = new OceanBaseCEContainer(DockerImageName.parse("oceanbase/oceanbase-ce:latest"))
+ .withEnv("MODE", "slim")
+ .withEnv("FASTBOOT", "true");
+ @Autowired
+ private PersonMapper personMapper;
+
+ @DynamicPropertySource
+ static void oceanBaseProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.datasource.url", oceanBaseContainer::getJdbcUrl);
+ registry.add("spring.datasource.username", oceanBaseContainer::getUsername);
+ registry.add("spring.datasource.password", oceanBaseContainer::getPassword);
+ registry.add("spring.datasource.driver-class-name", oceanBaseContainer::getDriverClassName);
+ }
+
+ @BeforeAll
+ static void setup(@Autowired DataSource dataSource) throws Exception {
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+ assertNotNull(jdbcTemplate.getDataSource());
+ ScriptUtils.executeSqlScript(jdbcTemplate.getDataSource().getConnection(), new ClassPathResource("init.sql"));
+ }
+}
+```
+
+You can use MybatisPlus to operate the OceanBase instance in your test cases as follows:
+
+```java
+
+@Test
+void testSelectList() {
+ List persons = personMapper.selectList(null);
+ assertFalse(persons.isEmpty());
+}
+```
diff --git a/java/mybatisplus-java/pom.xml b/java/mybatisplus-java/pom.xml
new file mode 100644
index 0000000..9e3998f
--- /dev/null
+++ b/java/mybatisplus-java/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.17
+
+
+ com.oceanbase.samples
+ mybatisplus-java
+ 0.0.1-SNAPSHOT
+ mybatisplus-java
+ mybatisplus-java
+
+
+ com.oceanbase
+ oceanbase-client
+ 2.4.9
+
+
+ org.testcontainers
+ oceanbase
+ 1.19.7
+ test
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.6
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.testcontainers
+ testcontainers
+ 1.19.7
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ 1.19.7
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/java/mybatisplus-java/run.sh b/java/mybatisplus-java/run.sh
new file mode 100644
index 0000000..0aa77a4
--- /dev/null
+++ b/java/mybatisplus-java/run.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+mvn test
diff --git a/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplication.java b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplication.java
new file mode 100644
index 0000000..bec5721
--- /dev/null
+++ b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplication.java
@@ -0,0 +1,13 @@
+package com.oceanbase.samples.mybatisplusjava;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MybatisPlusJavaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MybatisPlusJavaApplication.class, args);
+ }
+
+}
diff --git a/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplicationTests.java b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplicationTests.java
new file mode 100644
index 0000000..ac04328
--- /dev/null
+++ b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/MybatisPlusJavaApplicationTests.java
@@ -0,0 +1,54 @@
+package com.oceanbase.samples.mybatisplusjava;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.init.ScriptUtils;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.oceanbase.OceanBaseCEContainer;
+import org.testcontainers.utility.DockerImageName;
+
+import javax.sql.DataSource;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@SpringBootTest
+@Testcontainers
+class MybatisPlusJavaApplicationTests {
+
+ @Container
+ public static OceanBaseCEContainer oceanBaseContainer = new OceanBaseCEContainer(DockerImageName.parse("oceanbase/oceanbase-ce:latest"))
+ .withEnv("MODE", "slim")
+ .withEnv("FASTBOOT", "true");
+ @Autowired
+ private PersonMapper personMapper;
+
+ @DynamicPropertySource
+ static void oceanBaseProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.datasource.url", oceanBaseContainer::getJdbcUrl);
+ registry.add("spring.datasource.username", oceanBaseContainer::getUsername);
+ registry.add("spring.datasource.password", oceanBaseContainer::getPassword);
+ registry.add("spring.datasource.driver-class-name", oceanBaseContainer::getDriverClassName);
+ }
+
+ @BeforeAll
+ static void setup(@Autowired DataSource dataSource) throws Exception {
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+ assertNotNull(jdbcTemplate.getDataSource());
+ ScriptUtils.executeSqlScript(jdbcTemplate.getDataSource().getConnection(), new ClassPathResource("init.sql"));
+ }
+
+ @Test
+ void testSelectList() {
+ List persons = personMapper.selectList(null);
+ assertFalse(persons.isEmpty());
+ }
+}
diff --git a/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/Person.java b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/Person.java
new file mode 100644
index 0000000..0e71880
--- /dev/null
+++ b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/Person.java
@@ -0,0 +1,10 @@
+package com.oceanbase.samples.mybatisplusjava;
+
+import lombok.Data;
+
+@Data
+public class Person {
+ private Integer id;
+ private String name;
+ private Integer age;
+}
diff --git a/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/PersonMapper.java b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/PersonMapper.java
new file mode 100644
index 0000000..4bc3b26
--- /dev/null
+++ b/java/mybatisplus-java/src/test/java/com/oceanbase/samples/mybatisplusjava/PersonMapper.java
@@ -0,0 +1,8 @@
+package com.oceanbase.samples.mybatisplusjava;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PersonMapper extends BaseMapper {
+}
diff --git a/java/mybatisplus-java/src/test/resources/init.sql b/java/mybatisplus-java/src/test/resources/init.sql
new file mode 100644
index 0000000..360157d
--- /dev/null
+++ b/java/mybatisplus-java/src/test/resources/init.sql
@@ -0,0 +1,16 @@
+CREATE DATABASE IF NOT EXISTS test;
+USE test;
+
+CREATE TABLE IF NOT EXISTS person
+(
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(50),
+ age INT
+);
+
+INSERT INTO person (name, age)
+VALUES ('Alice', 30);
+INSERT INTO person (name, age)
+VALUES ('Bob', 25);
+INSERT INTO person (name, age)
+VALUES ('Charlie', 35);