From 8ba94a0e7334c118581ec50c53cdbf35a0d823fe Mon Sep 17 00:00:00 2001 From: songyinyin Date: Tue, 10 Jun 2025 15:52:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20OceanBase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/noear/wood/DbContextMetaData.java | 63 +++++++++++++++++-- .../wood/dialect/DbOceanBaseMySQLDialect.java | 10 +++ .../dialect/DbOceanBaseOracleDialect.java | 10 +++ .../main/java/org/noear/wood/wrap/DbType.java | 2 + 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 wood/src/main/java/org/noear/wood/dialect/DbOceanBaseMySQLDialect.java create mode 100644 wood/src/main/java/org/noear/wood/dialect/DbOceanBaseOracleDialect.java diff --git a/wood/src/main/java/org/noear/wood/DbContextMetaData.java b/wood/src/main/java/org/noear/wood/DbContextMetaData.java index 840da5f..b4685a0 100644 --- a/wood/src/main/java/org/noear/wood/DbContextMetaData.java +++ b/wood/src/main/java/org/noear/wood/DbContextMetaData.java @@ -1,8 +1,22 @@ package org.noear.wood; -import org.noear.wood.dialect.*; +import org.noear.wood.dialect.DbClickHouseDialect; +import org.noear.wood.dialect.DbDb2Dialect; +import org.noear.wood.dialect.DbDialect; +import org.noear.wood.dialect.DbDuckDbDialect; +import org.noear.wood.dialect.DbH2Dialect; +import org.noear.wood.dialect.DbMySQLDialect; +import org.noear.wood.dialect.DbOceanBaseMySQLDialect; +import org.noear.wood.dialect.DbOceanBaseOracleDialect; +import org.noear.wood.dialect.DbOracleDialect; +import org.noear.wood.dialect.DbPhoenixDialect; +import org.noear.wood.dialect.DbPostgreSQLDialect; +import org.noear.wood.dialect.DbPrestoDialect; +import org.noear.wood.dialect.DbSQLServerDialect; +import org.noear.wood.dialect.DbSQLiteDialect; import org.noear.wood.ext.Act1Ex; -import org.noear.wood.wrap.*; +import org.noear.wood.wrap.DbType; +import org.noear.wood.wrap.TableWrap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,9 +25,13 @@ import java.io.Closeable; import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.locks.ReentrantLock; public class DbContextMetaData implements Closeable { @@ -258,7 +276,7 @@ public class DbContextMetaData implements Closeable { if (dialect == null) { //1. - setDatabaseType(url); + setDatabaseType(conn, url); //2. setSchema(conn, metaData); @@ -266,7 +284,7 @@ public class DbContextMetaData implements Closeable { }); } - private void setDatabaseType(String jdbcUrl) { + private void setDatabaseType(Connection conn, String jdbcUrl) { if (jdbcUrl != null) { String pn = jdbcUrl.toLowerCase().replace(" ", ""); @@ -306,6 +324,13 @@ public class DbContextMetaData implements Closeable { } else if (pn.startsWith("jdbc:duckdb:")) { type = DbType.DuckDb; dialect = new DbDuckDbDialect(); + } else if (pn.startsWith("jdbc:oceanbase:")) { + type = DbType.OceanBase; + if (isOceanBaseUseMysqlMode(conn)) { + dialect = new DbOceanBaseMySQLDialect(); + } else { + dialect = new DbOceanBaseOracleDialect(); + } } else { //做为默认 dialect = new DbMySQLDialect(); @@ -421,6 +446,34 @@ public class DbContextMetaData implements Closeable { } } + /** + * 判断是否为 MySQL 模式 + * + * @return true MySQL, false Oracle + */ + private boolean isOceanBaseUseMysqlMode(Connection connection) { + String sql = "show global variables where variable_name = 'ob_compatibility_mode'"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + String value = resultSet.getString(2); + if (Objects.nonNull(value)) { + return value.toUpperCase().contains("MYSQL"); + } else { + throw new RuntimeException("Execute SQL[" + sql + "] return null value"); + } + } else { + throw new RuntimeException("Execute SQL[" + sql + "] no result"); + } + } + } catch (SQLException sqlException) { + if (log.isDebugEnabled()) { + log.debug("Failed to execute sql :{}, and guesses OceanBase is MySQL Mode!", sql); + } + } + return true; + } + @Override public void close() throws IOException { if (dataSource != null && dataSource instanceof Closeable) { diff --git a/wood/src/main/java/org/noear/wood/dialect/DbOceanBaseMySQLDialect.java b/wood/src/main/java/org/noear/wood/dialect/DbOceanBaseMySQLDialect.java new file mode 100644 index 0000000..47b3a13 --- /dev/null +++ b/wood/src/main/java/org/noear/wood/dialect/DbOceanBaseMySQLDialect.java @@ -0,0 +1,10 @@ +package org.noear.wood.dialect; + +/** + * OceanBase MySQL 模式 + * + * @author songyinyin + * @since 2025/6/10 14:40 + */ +public class DbOceanBaseMySQLDialect extends DbMySQLDialect { +} diff --git a/wood/src/main/java/org/noear/wood/dialect/DbOceanBaseOracleDialect.java b/wood/src/main/java/org/noear/wood/dialect/DbOceanBaseOracleDialect.java new file mode 100644 index 0000000..5d5306c --- /dev/null +++ b/wood/src/main/java/org/noear/wood/dialect/DbOceanBaseOracleDialect.java @@ -0,0 +1,10 @@ +package org.noear.wood.dialect; + +/** + * OceanBase oracle 模式 + * + * @author songyinyin + * @since 2025/6/10 14:40 + */ +public class DbOceanBaseOracleDialect extends DbOracleDialect { +} diff --git a/wood/src/main/java/org/noear/wood/wrap/DbType.java b/wood/src/main/java/org/noear/wood/wrap/DbType.java index 018c48d..c049a6b 100644 --- a/wood/src/main/java/org/noear/wood/wrap/DbType.java +++ b/wood/src/main/java/org/noear/wood/wrap/DbType.java @@ -20,6 +20,8 @@ public enum DbType { Presto, DuckDb, + + OceanBase, /* Unknown(DatabaseType.Unknown, "Unknown", "Unknown", 0), OracleThinServiceName(DatabaseType.Oracle, "oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@//${host}:${port}/${name}", 1521), -- Gitee