From 301968cbbc69679c5e3580b869871d993f0d37e0 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 23:27:42 +0800 Subject: [PATCH] add DriverIdentifier --- .../hutool/core/text/CharSequenceUtil.java | 4 +- .../core/text/CharSequenceUtilTest.java | 7 + .../hutool/db/dialect/DialectFactory.java | 103 +---------- .../hutool/db/driver/DriverIdentifier.java | 164 ++++++++++++++++++ .../db/{dialect => driver}/DriverUtil.java | 14 +- .../db/driver/matcher/Db2DriverMatcher.java | 54 ++++++ .../db/driver/matcher/DriverMatcher.java | 38 ++++ .../db/driver/matcher/MysqlDriverMatcher.java | 53 ++++++ .../matcher/StartsWithDriverMatcher.java | 51 ++++++ .../db/driver/matcher/package-info.java} | 22 +-- .../hutool/db/driver/package-info.java | 16 ++ .../hutool/db/ds/AbstractDSFactory.java | 2 +- .../dromara/hutool/db/ds/pooled/DbConfig.java | 2 +- .../hutool/db/ds/pooled/DbSetting.java | 2 +- .../hutool/db/ds/simple/SimpleDataSource.java | 2 +- .../hutool/db/dialect/DialectFactoryTest.java | 61 ------- .../hutool/db/driver/DriverUtilTest.java | 64 +++++++ 17 files changed, 469 insertions(+), 190 deletions(-) create mode 100644 hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverIdentifier.java rename hutool-db/src/main/java/org/dromara/hutool/db/{dialect => driver}/DriverUtil.java (87%) create mode 100644 hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/Db2DriverMatcher.java create mode 100644 hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/DriverMatcher.java create mode 100644 hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/MysqlDriverMatcher.java create mode 100644 hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/StartsWithDriverMatcher.java rename hutool-db/src/{test/java/org/dromara/hutool/db/dialect/DriverUtilTest.java => main/java/org/dromara/hutool/db/driver/matcher/package-info.java} (50%) create mode 100644 hutool-db/src/main/java/org/dromara/hutool/db/driver/package-info.java delete mode 100644 hutool-db/src/test/java/org/dromara/hutool/db/dialect/DialectFactoryTest.java create mode 100644 hutool-db/src/test/java/org/dromara/hutool/db/driver/DriverUtilTest.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/CharSequenceUtil.java index c5575fc49..9f8850540 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/CharSequenceUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/CharSequenceUtil.java @@ -3201,7 +3201,9 @@ public class CharSequenceUtil extends StrValidator { } /** - * 截断字符串,使用其按照指定编码为字节后不超过maxBytes长度 + * 截断字符串,使用其按照指定编码为字节后不超过maxBytes长度
+ * 此方法用于截取总bytes数不超过指定长度,如果字符出没有超出原样输出,如果超出了,则截取掉超出部分,并可选添加..., + * 但是添加“...”后总长度也不超过限制长度。 * * @param str 原始字符串 * @param charset 指定编码 diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/text/CharSequenceUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/text/CharSequenceUtilTest.java index adb8b9ced..cd4755223 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/text/CharSequenceUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/text/CharSequenceUtilTest.java @@ -321,6 +321,13 @@ public class CharSequenceUtilTest { Assertions.assertEquals(str, ret); } + @Test + public void limitByteLengthUtf8Test2() { + final String str = "这是This一"; + final String ret = StrUtil.limitByteLengthUtf8(str, 12, true); + Assertions.assertEquals("这是Thi...", ret); + } + @Test public void limitByteLengthTest() { final String str = "This is English"; diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java index 6ee86f174..ab5324090 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java @@ -12,10 +12,9 @@ package org.dromara.hutool.db.dialect; -import org.dromara.hutool.core.classloader.ClassLoaderUtil; import org.dromara.hutool.core.map.SafeConcurrentHashMap; -import org.dromara.hutool.core.regex.ReUtil; import org.dromara.hutool.core.text.StrUtil; +import org.dromara.hutool.db.driver.DriverUtil; import org.dromara.hutool.db.dialect.impl.AnsiSqlDialect; import org.dromara.hutool.db.dialect.impl.H2Dialect; import org.dromara.hutool.db.dialect.impl.MysqlDialect; @@ -84,106 +83,6 @@ public class DialectFactory implements DriverNamePool { return new AnsiSqlDialect(); } - /** - * 通过JDBC URL等信息识别JDBC驱动名 - * - * @param nameContainsProductInfo 包含数据库标识的字符串 - * @return 驱动 - */ - public static String identifyDriver(final String nameContainsProductInfo) { - return identifyDriver(nameContainsProductInfo, null); - } - - /** - * 通过JDBC URL等信息识别JDBC驱动名 - * - * @param nameContainsProductInfo 包含数据库标识的字符串 - * @param classLoader 类加载器,{@code null}表示默认上下文的类加载器 - * @return 驱动 - */ - public static String identifyDriver(String nameContainsProductInfo, final ClassLoader classLoader) { - if (StrUtil.isBlank(nameContainsProductInfo)) { - return null; - } - // 全部转为小写,忽略大小写 - nameContainsProductInfo = StrUtil.cleanBlank(nameContainsProductInfo.toLowerCase()); - - // 首先判断是否为标准的JDBC URL,截取jdbc:xxxx:中间部分 - final String name = ReUtil.getGroup1("jdbc:(.*?):", nameContainsProductInfo); - if (StrUtil.isNotBlank(name)) { - nameContainsProductInfo = name; - } - - String driver = null; - if (nameContainsProductInfo.contains("mysql") || nameContainsProductInfo.contains("cobar")) { - driver = ClassLoaderUtil.isPresent(DRIVER_MYSQL_V6, classLoader) ? DRIVER_MYSQL_V6 : DRIVER_MYSQL; - } else if (nameContainsProductInfo.contains("mariadb")) { - // Mariadb - driver = DRIVER_MARIADB; - } else if (nameContainsProductInfo.contains("oracle")) { - driver = ClassLoaderUtil.isPresent(DRIVER_ORACLE, classLoader) ? DRIVER_ORACLE : DRIVER_ORACLE_OLD; - } else if (nameContainsProductInfo.contains("postgresql")) { - driver = DRIVER_POSTGRESQL; - } else if (nameContainsProductInfo.contains("sqlite")) { - driver = DRIVER_SQLLITE3; - } else if (nameContainsProductInfo.contains("sqlserver") || nameContainsProductInfo.contains("microsoft")) { - driver = DRIVER_SQLSERVER; - } else if (nameContainsProductInfo.contains("hive2")) { - driver = DRIVER_HIVE2; - } else if (nameContainsProductInfo.contains("hive")) { - driver = DRIVER_HIVE; - } else if (nameContainsProductInfo.contains("h2")) { - driver = DRIVER_H2; - } else if (nameContainsProductInfo.contains("derby")) { - // 嵌入式Derby数据库 - driver = DRIVER_DERBY; - } else if (nameContainsProductInfo.contains("hsqldb")) { - // HSQLDB - driver = DRIVER_HSQLDB; - } else if (nameContainsProductInfo.contains("dm")) { - // 达梦7 - driver = DRIVER_DM7; - } else if (nameContainsProductInfo.contains("kingbase8")) { - // 人大金仓8 - driver = DRIVER_KINGBASE8; - } else if (nameContainsProductInfo.contains("ignite")) { - // Ignite thin - driver = DRIVER_IGNITE_THIN; - } else if (nameContainsProductInfo.contains("clickhouse")) { - // ClickHouse - driver = DRIVER_CLICK_HOUSE; - } else if (nameContainsProductInfo.contains("highgo")) { - // 瀚高 - driver = DRIVER_HIGHGO; - } else if (nameContainsProductInfo.contains("db2")) { - // DB2 - driver = DRIVER_DB2; - } else if (nameContainsProductInfo.contains("xugu")) { - // 虚谷 - driver = DRIVER_XUGU; - } else if (nameContainsProductInfo.contains("phoenix")) { - // Apache Phoenix - driver = DRIVER_PHOENIX; - } else if (nameContainsProductInfo.contains("zenith")) { - // 华为高斯 - driver = DRIVER_GAUSS; - } else if (nameContainsProductInfo.contains("gbase")) { - // 南大通用数据库 - driver = DRIVER_GBASE; - } else if (nameContainsProductInfo.contains("oscar")) { - // 神州数据库 - driver = DRIVER_OSCAR; - } else if (nameContainsProductInfo.contains("sybase")) { - // Sybase - driver = DRIVER_SYBASE; - } else if (nameContainsProductInfo.contains("opengauss")) { - // OpenGauss - driver = DRIVER_OPENGAUSS; - } - - return driver; - } - /** * 获取共享方言 * diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverIdentifier.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverIdentifier.java new file mode 100644 index 000000000..278ce3064 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverIdentifier.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.driver; + +import org.dromara.hutool.core.collection.ListUtil; +import org.dromara.hutool.core.text.StrUtil; +import org.dromara.hutool.db.driver.matcher.Db2DriverMatcher; +import org.dromara.hutool.db.driver.matcher.DriverMatcher; +import org.dromara.hutool.db.driver.matcher.MysqlDriverMatcher; +import org.dromara.hutool.db.driver.matcher.StartsWithDriverMatcher; + +import java.util.List; + +/** + * 驱动识别器
+ * 通过给定的规则列表,逐个查找,直到匹配到{@link DriverMatcher}后,获取其驱动名
+ * 部分驱动参考Druid实现 + * + * @author looly + * @since 6.0.0 + */ +public class DriverIdentifier { + + /** + * 单例驱动识别器 + */ + public static DriverIdentifier INSTANCE = new DriverIdentifier(null); + + private final List matcherList; + + /** + * 构造 + * + * @param classLoader 类加载器 + */ + public DriverIdentifier(final ClassLoader classLoader) { + this.matcherList = ListUtil.of( + // Mysql + new MysqlDriverMatcher(classLoader), + // Mariadb + new StartsWithDriverMatcher("org.mariadb.jdbc.Driver", "jdbc:mariadb:"), + // Oracle + new StartsWithDriverMatcher("oracle.jdbc.OracleDriver", "jdbc:oracle:", "JDBC:oracle:"), + new StartsWithDriverMatcher("com.alibaba.jdbc.AlibabaDriver", "jdbc:alibaba:oracle:"), + // PostgreSQL + new StartsWithDriverMatcher("org.postgresql.Driver", "jdbc:postgresql:"), + // SQLServer + new StartsWithDriverMatcher("com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver:"), + new StartsWithDriverMatcher("com.microsoft.jdbc.sqlserver.SQLServerDriver", "jdbc:microsoft:"), + // SQLite3 + new StartsWithDriverMatcher("org.sqlite.JDBC", "jdbc:sqlite:"), + // H2 + new StartsWithDriverMatcher("org.h2.Driver", "jdbc:h2:"), + // Hive + new StartsWithDriverMatcher("org.apache.hadoop.hive.jdbc.HiveDriver", "jdbc:hive:"), + new StartsWithDriverMatcher("org.apache.hive.jdbc.HiveDriver", "jdbc:hive2:"), + // Apache Derby + new StartsWithDriverMatcher("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:"), + // log4jdbc + new StartsWithDriverMatcher("net.sf.log4jdbc.DriverSpy", "jdbc:log4jdbc:"), + // tidb + new StartsWithDriverMatcher("io.tidb.bigdata.jdbc.TiDBDriver", "jdbc:tidb:"), + // oceanbase + new StartsWithDriverMatcher("com.oceanbase.jdbc.Driver", "jdbc:oceanbase:"), + // SyBase JConnect,见:https://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc39001.0700/html/prjdbc0700/X28208.htm + new StartsWithDriverMatcher("com.sybase.jdbc4.jdbc.SybDriver", "jdbc:sybase:Tds:"), + new StartsWithDriverMatcher("net.sourceforge.jtds.jdbc.Driver", "jdbc:jtds:"), + new StartsWithDriverMatcher("com.alibaba.druid.mock.MockDriver", "jdbc:fake:", "jdbc:mock:"), + new StartsWithDriverMatcher("com.edb.Driver", "jdbc:edb:"), + new StartsWithDriverMatcher("com.aliyun.odps.jdbc.OdpsDriver", "jdbc:odps:"), + // HSQLDB + new StartsWithDriverMatcher("org.hsqldb.jdbcDriver", "jdbc:hsqldb:"), + new Db2DriverMatcher(), + new StartsWithDriverMatcher("com.ingres.jdbc.IngresDriver", "jdbc:ingres:"), + new StartsWithDriverMatcher("com.mckoi.JDBCDriver", "jdbc:mckoi:"), + new StartsWithDriverMatcher("COM.cloudscape.core.JDBCDriver", "jdbc:cloudscape:"), + new StartsWithDriverMatcher("com.informix.jdbc.IfxDriver", "jdbc:informix-sqli:"), + new StartsWithDriverMatcher("com.timesten.jdbc.TimesTenDriver", "jdbc:timesten:"), + new StartsWithDriverMatcher("com.ibm.as400.access.AS400JDBCDriver", "jdbc:as400:"), + new StartsWithDriverMatcher("com.attunity.jdbc.NvDriver", "jdbc:attconnect:"), + new StartsWithDriverMatcher("com.jnetdirect.jsql.JSQLDriver", "jdbc:JSQLConnect:"), + new StartsWithDriverMatcher("com.newatlanta.jturbo.driver.Driver", "jdbc:JTurbo:"), + new StartsWithDriverMatcher("interbase.interclient.Driver", "jdbc:interbase:"), + new StartsWithDriverMatcher("com.pointbase.jdbc.jdbcUniversalDriver", "jdbc:pointbase:"), + new StartsWithDriverMatcher("ca.edbc.jdbc.EdbcDriver", "jdbc:edbc:"), + new StartsWithDriverMatcher("com.mimer.jdbc.Driver", "jdbc:mimer:multi1:"), + // Apache Ignite + new StartsWithDriverMatcher("org.apache.ignite.IgniteJdbcThinDriver", "jdbc:ignite:thin:"), + // 达梦7 + new StartsWithDriverMatcher("dm.jdbc.driver.DmDriver", "jdbc:dm:"), + // 人大金仓 + new StartsWithDriverMatcher("com.kingbase.Driver", "jdbc:kingbase:"), + // 人大金仓8 + new StartsWithDriverMatcher("com.kingbase8.Driver", "jdbc:kingbase8:"), + // 南大通用 + new StartsWithDriverMatcher("com.gbase.jdbc.Driver", "jdbc:gbase:"), + // 虚谷 + new StartsWithDriverMatcher("com.xugu.cloudjdbc.Driver", "jdbc:xugu:"), + // 神通 + new StartsWithDriverMatcher("com.oscar.Driver", "jdbc:oscar:"), + // Apache Phoenix轻客户端 + new StartsWithDriverMatcher("org.apache.phoenix.queryserver.client.Driver", "jdbc:phoenix:thin:"), + // Apache Phoenix重客户端(在轻客户端后检测) + new StartsWithDriverMatcher("org.apache.phoenix.jdbc.PhoenixDriver", "jdbc:phoenix:"), + new StartsWithDriverMatcher("org.apache.kylin.jdbc.Driver", "jdbc:kylin:"), + new StartsWithDriverMatcher("com.alibaba.xdriver.elastic.jdbc.ElasticDriver", "jdbc:elastic:"), + new StartsWithDriverMatcher("com.clickhouse.jdbc.ClickHouseDriver", "jdbc:clickhouse:"), + new StartsWithDriverMatcher("com.facebook.presto.jdbc.PrestoDriver", "jdbc:presto:"), + new StartsWithDriverMatcher("io.trino.jdbc.TrinoDriver", "jdbc:trino:"), + // 浪潮K-DB + new StartsWithDriverMatcher("com.inspur.jdbc.KdDriver", "jdbc:inspur:"), + new StartsWithDriverMatcher("com.aliyun.polardb.Driver", "jdbc:polardb"), + // 瀚高 + new StartsWithDriverMatcher("com.highgo.jdbc.Driver", "jdbc:highgo:"), + new StartsWithDriverMatcher("com.pivotal.jdbc.GreenplumDriver", "jdbc:pivotal:greenplum:"), + // 华为OpenGauss + new StartsWithDriverMatcher("com.huawei.gauss.jdbc.ZenithDriver", "jdbc:zenith:"), + new StartsWithDriverMatcher("org.opengauss.Driver", "jdbc:opengauss:") + ); + } + + /** + * 通过JDBC URL等信息识别JDBC驱动名 + * + * @param jdbcUrl JDBC URL + * @return 驱动类名,未识别到返回{@code null} + */ + public String identifyDriver(final String jdbcUrl) { + if (StrUtil.isBlank(jdbcUrl)) { + return null; + } + + for (final DriverMatcher driverMatcher : this.matcherList) { + if (driverMatcher.isMatch(jdbcUrl)) { + return driverMatcher.getClassName(); + } + } + + return null; + } + + /** + * 自定义增加{@link DriverMatcher} + * + * @param matcher {@link DriverMatcher} + * @return this + */ + public DriverIdentifier addMatcher(final DriverMatcher matcher) { + if (null != matcher) { + this.matcherList.add(matcher); + } + return this; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverUtil.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverUtil.java similarity index 87% rename from hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverUtil.java rename to hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverUtil.java index 4b9f7f321..a06334ddd 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverUtil.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/DriverUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 looly(loolly@aliyun.com) + * Copyright (c) 2023. looly(loolly@aliyun.com) * Hutool is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: @@ -10,7 +10,7 @@ * See the Mulan PSL v2 for more details. */ -package org.dromara.hutool.db.dialect; +package org.dromara.hutool.db.driver; import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.text.StrUtil; @@ -34,10 +34,10 @@ public class DriverUtil { * * @param nameContainsProductInfo 包含数据库标识的字符串 * @return 驱动 - * @see DialectFactory#identifyDriver(String) + * @see DriverIdentifier#identifyDriver(String) */ public static String identifyDriver(final String nameContainsProductInfo) { - return DialectFactory.identifyDriver(nameContainsProductInfo); + return DriverIdentifier.INSTANCE.identifyDriver(nameContainsProductInfo); } /** @@ -47,9 +47,9 @@ public class DriverUtil { * @return 驱动 */ public static String identifyDriver(final DataSource ds) { - if(ds instanceof DSWrapper) { - final String driver = ((DSWrapper)ds).getDriver(); - if(StrUtil.isNotBlank(driver)) { + if (ds instanceof DSWrapper) { + final String driver = ((DSWrapper) ds).getDriver(); + if (StrUtil.isNotBlank(driver)) { return driver; } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/Db2DriverMatcher.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/Db2DriverMatcher.java new file mode 100644 index 000000000..11c19d657 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/Db2DriverMatcher.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.driver.matcher; + +import org.dromara.hutool.core.text.StrUtil; + +/** + * db2驱动匹配器,来自Druid的JdbcUtils + * + * @author druid + */ +public class Db2DriverMatcher implements DriverMatcher { + + private static final String DB2_DRIVER = "com.ibm.db2.jcc.DB2Driver"; // Type4 + private static final String DB2_DRIVER2 = "COM.ibm.db2.jdbc.app.DB2Driver"; // Type2 + private static final String DB2_DRIVER3 = "COM.ibm.db2.jdbc.net.DB2Driver"; // Type3 + + private String jdbcUrl; + + @Override + public boolean isMatch(final String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + return jdbcUrl.startsWith("jdbc:db2:"); + } + + @Override + public String getClassName() { + // Type2 COM.ibm.db2.jdbc.app.DB2Driver, url = jdbc:db2:databasename + // Type3 COM.ibm.db2.jdbc.net.DB2Driver, url = jdbc:db2:ServerIP:6789:databasename + // Type4 8.1+ com.ibm.db2.jcc.DB2Driver, url = jdbc:db2://ServerIP:50000/databasename + final String jdbcUrl = this.jdbcUrl; + final String prefix = "jdbc:db2:"; + if (StrUtil.isEmpty(jdbcUrl) || jdbcUrl.startsWith(prefix + "//")) { // Type4 + return DB2_DRIVER; // "com.ibm.db2.jcc.DB2Driver"; + } else { + final String suffix = jdbcUrl.substring(prefix.length()); + if (suffix.indexOf(':') > 0) { // Type3 + return DB2_DRIVER3; // COM.ibm.db2.jdbc.net.DB2Driver + } else { // Type2 + return DB2_DRIVER2; // COM.ibm.db2.jdbc.app.DB2Driver + } + } + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/DriverMatcher.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/DriverMatcher.java new file mode 100644 index 000000000..b3f9eb5de --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/DriverMatcher.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.driver.matcher; + +/** + * 驱动匹配接口,通过实现此接口,可以:
+ * 通过{@link #isMatch(String)} 判断JDBC URL 是否匹配驱动的要求
+ * 通过{@link #getClassName()} 获取对应的驱动类名称 + * + * @author looly + */ +public interface DriverMatcher { + + /** + * 自定义规则是否匹配 JDBC URL + * + * @param jdbcUrl JDBC URL + * @return 是否匹配 + */ + boolean isMatch(final String jdbcUrl); + + /** + * 获取对应的驱动类名称 + * + * @return 对应的驱动类名称 + */ + String getClassName(); +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/MysqlDriverMatcher.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/MysqlDriverMatcher.java new file mode 100644 index 000000000..b6a71de8c --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/MysqlDriverMatcher.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.driver.matcher; + +import org.dromara.hutool.core.classloader.ClassLoaderUtil; + +/** + * Mysql匹配器 + * + * @author looly + */ +public class MysqlDriverMatcher implements DriverMatcher { + + private final ClassLoader classLoader; + private Boolean isVersion6; + + /** + * 构造 + * + * @param classLoader 类加载器 + */ + public MysqlDriverMatcher(final ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public boolean isMatch(final String jdbcUrl) { + return jdbcUrl.startsWith("jdbc:mysql:") + // 阿里的Mysql分布式集群 + || jdbcUrl.startsWith("jdbc:cobar:") + // log4jdbc for Mysql + || jdbcUrl.startsWith("jdbc:log4jdbc:mysql:"); + } + + @Override + public String getClassName() { + final String driverNameV6 = "com.mysql.cj.jdbc.Driver"; + if (isVersion6 == null) { + isVersion6 = ClassLoaderUtil.isPresent(driverNameV6, classLoader); + } + return isVersion6 ? driverNameV6 : "com.mysql.jdbc.Driver"; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/StartsWithDriverMatcher.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/StartsWithDriverMatcher.java new file mode 100644 index 000000000..c13468cf9 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/StartsWithDriverMatcher.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.driver.matcher; + +/** + * 判断jdbc url的起始字符串匹配对应的驱动类名 + * + * @author looly + * @since 6.0.0 + */ +public class StartsWithDriverMatcher implements DriverMatcher { + + private final String className; + private final String[] startsWithStrs; + + /** + * 构造 + * + * @param className 驱动类名 + * @param startsWithStrs 开头字符串标记列表,或关系 + */ + public StartsWithDriverMatcher(final String className, final String... startsWithStrs) { + this.className = className; + this.startsWithStrs = startsWithStrs; + } + + @Override + public boolean isMatch(final String jdbcUrl) { + for (final String startsWithStr : startsWithStrs) { + if (jdbcUrl.startsWith(startsWithStr)) { + return true; + } + } + return false; + } + + @Override + public String getClassName() { + return className; + } +} diff --git a/hutool-db/src/test/java/org/dromara/hutool/db/dialect/DriverUtilTest.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/package-info.java similarity index 50% rename from hutool-db/src/test/java/org/dromara/hutool/db/dialect/DriverUtilTest.java rename to hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/package-info.java index ac9cfde55..c3031eb7c 100644 --- a/hutool-db/src/test/java/org/dromara/hutool/db/dialect/DriverUtilTest.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/matcher/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 looly(loolly@aliyun.com) + * Copyright (c) 2023. looly(loolly@aliyun.com) * Hutool is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: @@ -10,17 +10,9 @@ * See the Mulan PSL v2 for more details. */ -package org.dromara.hutool.db.dialect; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class DriverUtilTest { - - @Test - public void identifyDriverTest(){ - final String url = "jdbc:h2:file:./db/test;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL"; - final String driver = DriverUtil.identifyDriver(url); // driver 返回 mysql 的 driver - Assertions.assertEquals("org.h2.Driver", driver); - } -} +/** + * 驱动匹配器封装及基本实现 + * + * @author looly + */ +package org.dromara.hutool.db.driver.matcher; diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/driver/package-info.java b/hutool-db/src/main/java/org/dromara/hutool/db/driver/package-info.java new file mode 100644 index 000000000..85b64dca3 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/driver/package-info.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * 驱动和驱动类名称相关封装 + */ +package org.dromara.hutool.db.driver; diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/ds/AbstractDSFactory.java b/hutool-db/src/main/java/org/dromara/hutool/db/ds/AbstractDSFactory.java index 49bee974d..933fa16b9 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/ds/AbstractDSFactory.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/ds/AbstractDSFactory.java @@ -19,7 +19,7 @@ import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.db.DbRuntimeException; import org.dromara.hutool.db.DbUtil; import org.dromara.hutool.db.GlobalDbConfig; -import org.dromara.hutool.db.dialect.DriverUtil; +import org.dromara.hutool.db.driver.DriverUtil; import org.dromara.hutool.setting.Setting; import javax.sql.DataSource; diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbConfig.java b/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbConfig.java index 4422976a2..fd85fe873 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbConfig.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbConfig.java @@ -13,7 +13,7 @@ package org.dromara.hutool.db.ds.pooled; import org.dromara.hutool.db.DbRuntimeException; -import org.dromara.hutool.db.dialect.DriverUtil; +import org.dromara.hutool.db.driver.DriverUtil; import java.util.Properties; diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbSetting.java b/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbSetting.java index 310acb7a5..366ffc757 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbSetting.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/ds/pooled/DbSetting.java @@ -15,7 +15,7 @@ package org.dromara.hutool.db.ds.pooled; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.db.DbRuntimeException; -import org.dromara.hutool.db.dialect.DriverUtil; +import org.dromara.hutool.db.driver.DriverUtil; import org.dromara.hutool.db.ds.DSKeys; import org.dromara.hutool.setting.Setting; diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/ds/simple/SimpleDataSource.java b/hutool-db/src/main/java/org/dromara/hutool/db/ds/simple/SimpleDataSource.java index 803ecdc9c..2f4ed5dda 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/ds/simple/SimpleDataSource.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/ds/simple/SimpleDataSource.java @@ -15,7 +15,7 @@ package org.dromara.hutool.db.ds.simple; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.db.DbRuntimeException; -import org.dromara.hutool.db.dialect.DriverUtil; +import org.dromara.hutool.db.driver.DriverUtil; import org.dromara.hutool.db.ds.DSKeys; import org.dromara.hutool.setting.Setting; import org.dromara.hutool.setting.props.Props; diff --git a/hutool-db/src/test/java/org/dromara/hutool/db/dialect/DialectFactoryTest.java b/hutool-db/src/test/java/org/dromara/hutool/db/dialect/DialectFactoryTest.java deleted file mode 100644 index eafeb47a3..000000000 --- a/hutool-db/src/test/java/org/dromara/hutool/db/dialect/DialectFactoryTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2023 looly(loolly@aliyun.com) - * Hutool is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * https://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - -package org.dromara.hutool.db.dialect; - -import org.dromara.hutool.core.util.RandomUtil; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; - -import static org.dromara.hutool.db.dialect.DriverNamePool.*; - -public class DialectFactoryTest { - - @Test - public void identifyDriverTest(){ - final Map map = new HashMap<>(25); - map.put("mysql",DRIVER_MYSQL_V6); - map.put("cobar",DRIVER_MYSQL_V6); - map.put("oracle",DRIVER_ORACLE); - map.put("postgresql",DRIVER_POSTGRESQL); - map.put("sqlite",DRIVER_SQLLITE3); - map.put("sqlserver",DRIVER_SQLSERVER); - map.put("microsoft",DRIVER_SQLSERVER); - map.put("h2",DRIVER_H2); - map.put("derby",DRIVER_DERBY); - map.put("hsqldb",DRIVER_HSQLDB); - map.put("dm",DRIVER_DM7); - map.put("kingbase8",DRIVER_KINGBASE8); - map.put("ignite",DRIVER_IGNITE_THIN); - map.put("clickhouse",DRIVER_CLICK_HOUSE); - map.put("highgo",DRIVER_HIGHGO); - map.put("db2",DRIVER_DB2); - map.put("xugu",DRIVER_XUGU); - map.put("phoenix",DRIVER_PHOENIX); - map.put("zenith",DRIVER_GAUSS); - map.put("gbase",DRIVER_GBASE); - map.put("oscar",DRIVER_OSCAR); - map.put("sybase",DRIVER_SYBASE); - map.put("mariadb",DRIVER_MARIADB); - - // 单元测试歧义 - //map.put("hive2",DRIVER_HIVE2); - //map.put("hive",DRIVER_HIVE); - - map.forEach((k,v) -> Assertions.assertEquals(v, - DialectFactory.identifyDriver(k+ RandomUtil.randomStringLower(2),null) )); - - } -} diff --git a/hutool-db/src/test/java/org/dromara/hutool/db/driver/DriverUtilTest.java b/hutool-db/src/test/java/org/dromara/hutool/db/driver/DriverUtilTest.java new file mode 100644 index 000000000..1d38d567f --- /dev/null +++ b/hutool-db/src/test/java/org/dromara/hutool/db/driver/DriverUtilTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.driver; + +import org.dromara.hutool.core.util.RandomUtil; +import org.dromara.hutool.db.driver.DriverUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +public class DriverUtilTest { + + @Test + public void identifyH2DriverTest(){ + final String url = "jdbc:h2:file:./db/test;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL"; + final String driver = DriverUtil.identifyDriver(url); // driver 返回 mysql 的 driver + Assertions.assertEquals("org.h2.Driver", driver); + } + + @Test + public void identifyDriverTest() { + final Map map = new HashMap<>(25); + map.put("jdbc:mysql:", "com.mysql.cj.jdbc.Driver"); + map.put("jdbc:cobar:", "com.mysql.cj.jdbc.Driver"); + map.put("jdbc:oracle:", "oracle.jdbc.OracleDriver"); + map.put("jdbc:postgresql:", "org.postgresql.Driver"); + map.put("jdbc:sqlite:", "org.sqlite.JDBC"); + map.put("jdbc:sqlserver:", "com.microsoft.sqlserver.jdbc.SQLServerDriver"); + map.put("jdbc:microsoft:", "com.microsoft.jdbc.sqlserver.SQLServerDriver"); + map.put("jdbc:h2:", "org.h2.Driver"); + map.put("jdbc:derby:", "org.apache.derby.jdbc.EmbeddedDriver"); + map.put("jdbc:hsqldb:", "org.hsqldb.jdbcDriver"); + map.put("jdbc:dm:", "dm.jdbc.driver.DmDriver"); + map.put("jdbc:kingbase8:", "com.kingbase8.Driver"); + map.put("jdbc:ignite:thin:", "org.apache.ignite.IgniteJdbcThinDriver"); + map.put("jdbc:clickhouse:", "com.clickhouse.jdbc.ClickHouseDriver"); + map.put("jdbc:highgo:", "com.highgo.jdbc.Driver"); + map.put("jdbc:db2:", "COM.ibm.db2.jdbc.app.DB2Driver"); + map.put("jdbc:xugu:", "com.xugu.cloudjdbc.Driver"); + map.put("jdbc:phoenix:", "org.apache.phoenix.jdbc.PhoenixDriver"); + map.put("jdbc:zenith:", "com.huawei.gauss.jdbc.ZenithDriver"); + map.put("jdbc:gbase:", "com.gbase.jdbc.Driver"); + map.put("jdbc:oscar:", "com.oscar.Driver"); + map.put("jdbc:sybase:Tds:", "com.sybase.jdbc4.jdbc.SybDriver"); + map.put("jdbc:mariadb:", "org.mariadb.jdbc.Driver"); + map.put("jdbc:hive2:", "org.apache.hive.jdbc.HiveDriver"); + map.put("jdbc:hive:", "org.apache.hadoop.hive.jdbc.HiveDriver"); + + map.forEach((k, v) -> Assertions.assertEquals(v, + DriverUtil.identifyDriver(k + RandomUtil.randomStringLower(2)))); + } +}