Skip to content

Commit

Permalink
[Feat]: Add a demo of SpringJDBC (#44)
Browse files Browse the repository at this point in the history
* [Feat]: Add a demo of SpringJDBC

* [Fix]: Delete test failure caused by Oracle table build clause.

* [improve]: use a pre-deployed OceanBase container in ci

* [improve]: add init.sql, update test

* [improve]: update test cases, update README.md
  • Loading branch information
bruce-pang authored May 20, 2024
1 parent dd2d635 commit 117e59f
Show file tree
Hide file tree
Showing 7 changed files with 423 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
142 changes: 142 additions & 0 deletions java/spring-jdbc/README-CN.md
Original file line number Diff line number Diff line change
@@ -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
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
```
2.新建测试类,使用 Druid 连接池实例化 JdbcTemplate。

```java
public class OceanBaseSpringJdbcApplicationTest {
private static JdbcTemplate jdbcTemplate;
private String sql;

static {
Map<String, String> map = new HashMap<String, String>();
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<String, String> map = new HashMap<String, String>();
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<String> rowMapper = new RowMapper<String>() {
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString("name");
}
};
List<String> names = jdbcTemplate.query(sql, rowMapper, "New Staff");
System.out.println("names: " + names);
}
}
```

修改代码中的连接信息,之后你就可以直接使用 run.sh 运行示例代码。

```bash
sh run.sh
```
148 changes: 148 additions & 0 deletions java/spring-jdbc/README.md
Original file line number Diff line number Diff line change
@@ -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
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
```

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<String, String> map = new HashMap<String, String>();
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<String, String> map = new HashMap<String, String>();
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<String> rowMapper = new RowMapper<String>() {
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString("name");
}
};
List<String> 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
```
40 changes: 40 additions & 0 deletions java/spring-jdbc/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.oceanbase.samples</groupId>
<artifactId>spring-jdbc</artifactId>
<version>1.0-SNAPSHOT</version>

<name>oceanbase-spring-jdbc</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2 changes: 2 additions & 0 deletions java/spring-jdbc/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
mvn test
Loading

0 comments on commit 117e59f

Please sign in to comment.