diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b023252..881b08d 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 uses: ./.github/workflows/basic-ci.yml with: module: ${{ matrix.module.name }} 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');