diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f457ae2..b023252 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,9 @@ jobs: - name: 'mybatis-plus' language: 'java' with_oceanbase_container: false + - name: 'mybatis' + language: 'java' + with_oceanbase_container: true uses: ./.github/workflows/basic-ci.yml with: module: ${{ matrix.module.name }} diff --git a/java/mybatis/README-CN.md b/java/mybatis/README-CN.md new file mode 100644 index 0000000..eef9434 --- /dev/null +++ b/java/mybatis/README-CN.md @@ -0,0 +1,251 @@ +# Spring Boot 连接 OceanBase 指南(使用 Spring Data JPA) + +[English](README.md) | 简体中文 + +本文介绍如何通过 MyBatis 连接 OceanBase 数据库。 +由于 OceanBase 支持 MySQL 模式与 Oracle 模式,因此可以使用 MySQL 驱动连接 OceanBase。 +## 快速开始 + +1.在 pom.xml 中首先加入 MySQL 以及 MyBatis 驱动,pom.xml 参考[OceanBase MyBatis 连接示例](https://www.oceanbase.com/docs/community-observer-cn-10000000000900919) 示例。 + +```xml + + + mysql + mysql-connector-java + 8.0.25 + + + org.mybatis + mybatis + 3.5.4 + + + junit + junit + 4.13.2 + test + + +``` + + 2.在 src/main/resources 文件夹新建 mybatis-config.xml ,并修改数据库连接信息,指定 mapper.xml 路径。 + + mybatis-config.xml +```xml + + + + + + + + + + + + + + + + + + + + +``` +3.新建 实体类,以及对应的 Mapper.xml 文件。 本次示例中,我们创建一个 User 实体类。 +```java +package com.oceanbase.samples.entity; + +import java.util.Objects; + +public class User { + private Integer id; + private String name; + + public User() { + } + + public User(Integer id, String name) { + this.id = id; + this.name = name; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id) && Objects.equals(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} +``` +4.新建 UserMapper 接口,用于与 UserMapper关联相应的增删改查操作 +```java +package com.oceanbase.samples.mapper; + +public interface UserMapper { +} +``` + +5.新建 UserMapper.xml ,并绑定 UserMapper 接口, 添加相应的增删改查操作。 +```xml + + + + + + + + + + delete from user where id = #{id}; + + + + insert into user (name) values (#{name}); + + + + update user set name = #{name} where id = #{id}; + + +``` + +6.测试用例,用于测试 UserMapper.xml 中的增删改查操作。 +```java +package com.oceanbase.samples; + + +import com.oceanbase.samples.entity.User; +import com.oceanbase.samples.util.SqlSessionUtil; +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.session.SqlSession; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.InputStreamReader; +import java.sql.Connection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + + +public class OceanBaseMyBatisTest +{ + + + @Before + public void setUp() throws Exception { + // 执行SQL脚本 + try { + Connection connection = SqlSessionUtil.openSession().getConnection(); + ScriptRunner runner = new ScriptRunner(connection); + runner.runScript(new InputStreamReader(Resources.getResourceAsStream("init.sql"))); + SqlSessionUtil.openSession().commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void test() { + insertTest(SqlSessionUtil.openSession()); + updateTest(SqlSessionUtil.openSession()); + selectTest(SqlSessionUtil.openSession()); + selectWithPagination(SqlSessionUtil.openSession(), 0, 2); + deleteTest(SqlSessionUtil.openSession()); + } + + + + public static void insertTest(SqlSession sqlSession) { + // Insert data + User user = new User(); + user.setName("Tom"); + int count = sqlSession.insert("com.oceanbase.samples.mapper.UserMapper.insert", user); + System.out.println("Insert count: " + count); + + } + + public static void updateTest(SqlSession sqlSession) { + // Update data + User user = new User(); + user.setId(1); + user.setName("Jerry"); + int count = sqlSession.update("com.oceanbase.samples.mapper.UserMapper.update", user); + System.out.println("Update count: " + count); + } + + public static void selectTest(SqlSession sqlSession) { + // Select data + List user = sqlSession.selectList("com.oceanbase.samples.mapper.UserMapper.selectUser", 1); + user.stream().filter(Objects::nonNull).forEach(System.out::println); + } + + + public static void selectWithPagination(SqlSession sqlSession, int offset, int pageSize) { + Map params = new HashMap<>(); + params.put("offset", offset); + params.put("pageSize", pageSize); + List users = sqlSession.selectList("com.oceanbase.samples.mapper.UserMapper.selectWithPagination", params); + users.stream().filter(Objects::nonNull).forEach(System.out::println); + } + + public static void deleteTest(SqlSession sqlSession) { + // Delete data + int count = sqlSession.delete("com.oceanbase.samples.mapper.UserMapper.delete", 3); + System.out.println("Delete count: " + count); + } + + @After + public void closeSession() { + SqlSessionUtil.openSession().close(); + } +} + +``` + + +修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。 + +```bash +sh run.sh +``` diff --git a/java/mybatis/README.md b/java/mybatis/README.md new file mode 100644 index 0000000..6c9c3b7 --- /dev/null +++ b/java/mybatis/README.md @@ -0,0 +1,251 @@ +# Guide to Connect Spring Boot to OceanBase (Using Spring Data JPA) + +English | [简体中文](README-CN.md) + +This article introduces how to connect to the OceanBase database through MyBatis. +Since OceanBase supports MySQL mode and Oracle mode, the MySQL driver can be used to connect to OceanBase. +## Quick Start + +1. First, add the MySQL and MyBatis drivers to the pom.xml file. Refer to the [OceanBase MyBatis Connection Example](https://www.oceanbase.com/docs/community-observer-cn-10000000000900919) for the pom.xml example. + +```xml + + + mysql + mysql-connector-java + 8.0.25 + + + org.mybatis + mybatis + 3.5.4 + + + junit + junit + 4.13.2 + test + + +``` + +2. Create a new mybatis-config.xml file in the src/main/resources folder, modify the database connection information, and specify the path for the mapper.xml. + + mybatis-config.xml +```xml + + + + + + + + + + + + + + + + + + + + +``` +3. Create a new entity class and the corresponding Mapper.xml file. In this example, we create a User entity class. +```java +package com.oceanbase.samples.entity; + +import java.util.Objects; + +public class User { + private Integer id; + private String name; + + public User() { + } + + public User(Integer id, String name) { + this.id = id; + this.name = name; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id) && Objects.equals(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} +``` +4. Create a new UserMapper interface, which will be associated with the UserMapper for the corresponding CRUD operations. +```java +package com.oceanbase.samples.mapper; + +public interface UserMapper { +} +``` + +5. Create a new UserMapper.xml file and bind it to the UserMapper interface, and add the corresponding CRUD operations. +```xml + + + + + + + + + + delete from user where id = #{id}; + + + + insert into user (name) values (#{name}); + + + + update user set name = #{name} where id = #{id}; + + +``` + +6. Test case, used to test the CRUD operations in UserMapper.xml. +```java +package com.oceanbase.samples; + + +import com.oceanbase.samples.entity.User; +import com.oceanbase.samples.util.SqlSessionUtil; +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.session.SqlSession; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.InputStreamReader; +import java.sql.Connection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + + +public class OceanBaseMyBatisTest +{ + + + @Before + public void setUp() throws Exception { + // 执行SQL脚本 + try { + Connection connection = SqlSessionUtil.openSession().getConnection(); + ScriptRunner runner = new ScriptRunner(connection); + runner.runScript(new InputStreamReader(Resources.getResourceAsStream("init.sql"))); + SqlSessionUtil.openSession().commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void test() { + insertTest(SqlSessionUtil.openSession()); + updateTest(SqlSessionUtil.openSession()); + selectTest(SqlSessionUtil.openSession()); + selectWithPagination(SqlSessionUtil.openSession(), 0, 2); + deleteTest(SqlSessionUtil.openSession()); + } + + + + public static void insertTest(SqlSession sqlSession) { + // Insert data + User user = new User(); + user.setName("Tom"); + int count = sqlSession.insert("com.oceanbase.samples.mapper.UserMapper.insert", user); + System.out.println("Insert count: " + count); + + } + + public static void updateTest(SqlSession sqlSession) { + // Update data + User user = new User(); + user.setId(1); + user.setName("Jerry"); + int count = sqlSession.update("com.oceanbase.samples.mapper.UserMapper.update", user); + System.out.println("Update count: " + count); + } + + public static void selectTest(SqlSession sqlSession) { + // Select data + List user = sqlSession.selectList("com.oceanbase.samples.mapper.UserMapper.selectUser", 1); + user.stream().filter(Objects::nonNull).forEach(System.out::println); + } + + + public static void selectWithPagination(SqlSession sqlSession, int offset, int pageSize) { + Map params = new HashMap<>(); + params.put("offset", offset); + params.put("pageSize", pageSize); + List users = sqlSession.selectList("com.oceanbase.samples.mapper.UserMapper.selectWithPagination", params); + users.stream().filter(Objects::nonNull).forEach(System.out::println); + } + + public static void deleteTest(SqlSession sqlSession) { + // Delete data + int count = sqlSession.delete("com.oceanbase.samples.mapper.UserMapper.delete", 3); + System.out.println("Delete count: " + count); + } + + @After + public void closeSession() { + SqlSessionUtil.openSession().close(); + } +} + +``` + + +修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。 + +```bash +sh run.sh +``` diff --git a/java/mybatis/pom.xml b/java/mybatis/pom.xml new file mode 100644 index 0000000..1575f2e --- /dev/null +++ b/java/mybatis/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + com.oceanbase.samples + mybatis + 1.0-SNAPSHOT + + oceanbase-mysql + + + UTF-8 + 1.8 + 1.8 + + + + + mysql + mysql-connector-java + 8.0.25 + + + org.mybatis + mybatis + 3.5.4 + + + junit + junit + 4.13.2 + test + + + + + + src/main/resources + + **/**.xml + **/**.sql + + + + + diff --git a/java/mybatis/run.sh b/java/mybatis/run.sh new file mode 100644 index 0000000..0aa77a4 --- /dev/null +++ b/java/mybatis/run.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +mvn test diff --git a/java/mybatis/src/test/java/com/oceanbase/samples/OceanBaseMyBatisTest.java b/java/mybatis/src/test/java/com/oceanbase/samples/OceanBaseMyBatisTest.java new file mode 100644 index 0000000..cedfba4 --- /dev/null +++ b/java/mybatis/src/test/java/com/oceanbase/samples/OceanBaseMyBatisTest.java @@ -0,0 +1,92 @@ +package com.oceanbase.samples; + + +import com.oceanbase.samples.entity.User; +import com.oceanbase.samples.util.SqlSessionUtil; +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.session.SqlSession; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.InputStreamReader; +import java.sql.Connection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + + +public class OceanBaseMyBatisTest +{ + + + @Before + public void setUp() throws Exception { + // 执行SQL脚本 + try { + Connection connection = SqlSessionUtil.openSession().getConnection(); + ScriptRunner runner = new ScriptRunner(connection); + runner.runScript(new InputStreamReader(Resources.getResourceAsStream("init.sql"))); + SqlSessionUtil.openSession().commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void test() { + insertTest(SqlSessionUtil.openSession()); + updateTest(SqlSessionUtil.openSession()); + selectTest(SqlSessionUtil.openSession()); + selectWithPagination(SqlSessionUtil.openSession(), 0, 2); + deleteTest(SqlSessionUtil.openSession()); + } + + + + public static void insertTest(SqlSession sqlSession) { + // Insert data + User user = new User(); + user.setName("Tom"); + int count = sqlSession.insert("com.oceanbase.samples.mapper.UserMapper.insert", user); + System.out.println("Insert count: " + count); + + } + + public static void updateTest(SqlSession sqlSession) { + // Update data + User user = new User(); + user.setId(1); + user.setName("Jerry"); + int count = sqlSession.update("com.oceanbase.samples.mapper.UserMapper.update", user); + System.out.println("Update count: " + count); + } + + public static void selectTest(SqlSession sqlSession) { + // Select data + List user = sqlSession.selectList("com.oceanbase.samples.mapper.UserMapper.selectUser", 1); + user.stream().filter(Objects::nonNull).forEach(System.out::println); + } + + + public static void selectWithPagination(SqlSession sqlSession, int offset, int pageSize) { + Map params = new HashMap<>(); + params.put("offset", offset); + params.put("pageSize", pageSize); + List users = sqlSession.selectList("com.oceanbase.samples.mapper.UserMapper.selectWithPagination", params); + users.stream().filter(Objects::nonNull).forEach(System.out::println); + } + + public static void deleteTest(SqlSession sqlSession) { + // Delete data + int count = sqlSession.delete("com.oceanbase.samples.mapper.UserMapper.delete", 3); + System.out.println("Delete count: " + count); + } + + @After + public void closeSession() { + SqlSessionUtil.openSession().close(); + } +} diff --git a/java/mybatis/src/test/java/com/oceanbase/samples/entity/User.java b/java/mybatis/src/test/java/com/oceanbase/samples/entity/User.java new file mode 100644 index 0000000..b0e6615 --- /dev/null +++ b/java/mybatis/src/test/java/com/oceanbase/samples/entity/User.java @@ -0,0 +1,49 @@ +package com.oceanbase.samples.entity; + +import java.util.Objects; + +public class User { + private Integer id; + private String name; + + public User() { + } + + public User(Integer id, String name) { + this.id = id; + this.name = name; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id) && Objects.equals(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/java/mybatis/src/test/java/com/oceanbase/samples/mapper/UserMapper.java b/java/mybatis/src/test/java/com/oceanbase/samples/mapper/UserMapper.java new file mode 100644 index 0000000..a8ac176 --- /dev/null +++ b/java/mybatis/src/test/java/com/oceanbase/samples/mapper/UserMapper.java @@ -0,0 +1,4 @@ +package com.oceanbase.samples.mapper; + +public interface UserMapper { +} diff --git a/java/mybatis/src/test/java/com/oceanbase/samples/util/SqlSessionUtil.java b/java/mybatis/src/test/java/com/oceanbase/samples/util/SqlSessionUtil.java new file mode 100644 index 0000000..2abfdf3 --- /dev/null +++ b/java/mybatis/src/test/java/com/oceanbase/samples/util/SqlSessionUtil.java @@ -0,0 +1,31 @@ +package com.oceanbase.samples.util; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; + +import java.io.IOException; + +/** + * SqlSessionUtil + */ +public class SqlSessionUtil { + + private SqlSessionUtil() { + } + + private static SqlSessionFactory sqlSessionFactory; + + static { + try { + sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static SqlSession openSession() { + return sqlSessionFactory.openSession(); + } +} diff --git a/java/mybatis/src/test/resources/UserMapper.xml b/java/mybatis/src/test/resources/UserMapper.xml new file mode 100644 index 0000000..88bc128 --- /dev/null +++ b/java/mybatis/src/test/resources/UserMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + delete from user where id = #{id}; + + + + insert into user (name) values (#{name}); + + + + update user set name = #{name} where id = #{id}; + + diff --git a/java/mybatis/src/test/resources/init.sql b/java/mybatis/src/test/resources/init.sql new file mode 100644 index 0000000..1956e4c --- /dev/null +++ b/java/mybatis/src/test/resources/init.sql @@ -0,0 +1,15 @@ +CREATE DATABASE IF NOT EXISTS test; +USE test; +DROP TABLE IF EXISTS user; +CREATE TABLE user +( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(50) +); + +INSERT INTO user (name) +VALUES ('Bruce'); +INSERT INTO user (name) +VALUES ('Jack'); +INSERT INTO user (name) +VALUES ('Tom'); diff --git a/java/mybatis/src/test/resources/mybatis-config.xml b/java/mybatis/src/test/resources/mybatis-config.xml new file mode 100644 index 0000000..0fc3c1c --- /dev/null +++ b/java/mybatis/src/test/resources/mybatis-config.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + +