diff --git a/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java index 26645b862..e29f9c324 100755 --- a/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java @@ -890,7 +890,7 @@ public class IoUtil extends NioUtil { * * @param closeable 被关闭的对象 */ - public static void close(final Closeable closeable) { + public static void close(final AutoCloseable closeable) { if (null != closeable) { try { closeable.close(); diff --git a/hutool-db/src/main/java/cn/hutool/db/DaoTemplate.java b/hutool-db/src/main/java/cn/hutool/db/DaoTemplate.java index 13ee3306b..af01a1ab3 100644 --- a/hutool-db/src/main/java/cn/hutool/db/DaoTemplate.java +++ b/hutool-db/src/main/java/cn/hutool/db/DaoTemplate.java @@ -2,7 +2,7 @@ package cn.hutool.db; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrUtil; -import cn.hutool.db.ds.DSFactory; +import cn.hutool.db.ds.DSUtil; import javax.sql.DataSource; import java.util.Arrays; @@ -31,7 +31,7 @@ public class DaoTemplate { */ protected Db db; - //--------------------------------------------------------------- Constructor start + // region ----- Constructor /** * 构造,此构造需要自定义SqlRunner,主键默认为id @@ -49,7 +49,7 @@ public class DaoTemplate { * @param primaryKeyField 主键字段名 */ public DaoTemplate(final String tableName, final String primaryKeyField) { - this(tableName, primaryKeyField, DSFactory.get()); + this(tableName, primaryKeyField, DSUtil.getDS()); } /** @@ -87,9 +87,9 @@ public class DaoTemplate { } this.db = db; } - //--------------------------------------------------------------- Constructor end + // endregion - //------------------------------------------------------------- Add start + // region ----- Add /** * 添加 @@ -123,9 +123,9 @@ public class DaoTemplate { public Long addForGeneratedKey(final Entity entity) throws DbRuntimeException { return db.insertForGeneratedKey(fixEntity(entity)); } - //------------------------------------------------------------- Add end + // endregion - //------------------------------------------------------------- Delete start + // region ----- Delete /** * 删除 @@ -172,9 +172,9 @@ public class DaoTemplate { } return db.del(fixEntity(where)); } - //------------------------------------------------------------- Delete end + // endregion - //------------------------------------------------------------- Update start + // region ----- Update /** * 按照条件更新 @@ -225,10 +225,9 @@ public class DaoTemplate { public int addOrUpdate(final Entity entity) throws DbRuntimeException { return null == entity.get(primaryKeyField) ? add(entity) : update(entity); } - //------------------------------------------------------------- Update end - - //------------------------------------------------------------- Get start + // endregion + //region ----- Get /** * 根据主键获取单个记录 * @@ -265,9 +264,9 @@ public class DaoTemplate { public Entity get(final Entity where) throws DbRuntimeException { return db.get(fixEntity(where)); } - //------------------------------------------------------------- Get end + // endregion - //------------------------------------------------------------- Find start + // region ----- Find and page /** * 根据某个字段值查询结果 @@ -367,7 +366,7 @@ public class DaoTemplate { public boolean exist(final Entity where) throws DbRuntimeException { return this.count(where) > 0; } - //------------------------------------------------------------- Find end + // endregion /** * 修正Entity对象,避免null和填充表名 diff --git a/hutool-db/src/main/java/cn/hutool/db/Db.java b/hutool-db/src/main/java/cn/hutool/db/Db.java index 9155001da..2bed30a34 100644 --- a/hutool-db/src/main/java/cn/hutool/db/Db.java +++ b/hutool-db/src/main/java/cn/hutool/db/Db.java @@ -3,7 +3,7 @@ package cn.hutool.db; import cn.hutool.core.lang.func.SerConsumer; import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.DialectFactory; -import cn.hutool.db.ds.DSFactory; +import cn.hutool.db.ds.DSUtil; import cn.hutool.db.transaction.TransactionLevel; import cn.hutool.log.StaticLog; @@ -28,7 +28,7 @@ public class Db extends AbstractDb { * @return Db */ public static Db of() { - return of(DSFactory.get()); + return of(DSUtil.getDS()); } /** @@ -39,7 +39,7 @@ public class Db extends AbstractDb { * @return Db */ public static Db of(final String group) { - return of(DSFactory.get(group)); + return of(DSUtil.getDS(group)); } /** diff --git a/hutool-db/src/main/java/cn/hutool/db/DbUtil.java b/hutool-db/src/main/java/cn/hutool/db/DbUtil.java index 2c29c8bc8..fb21a615c 100644 --- a/hutool-db/src/main/java/cn/hutool/db/DbUtil.java +++ b/hutool-db/src/main/java/cn/hutool/db/DbUtil.java @@ -2,16 +2,11 @@ package cn.hutool.db; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IoUtil; -import cn.hutool.db.ds.DSFactory; import cn.hutool.db.sql.SqlLog; import cn.hutool.log.Log; import cn.hutool.log.level.Level; import cn.hutool.setting.Setting; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.sql.DataSource; - /** * 数据库操作工具类 * @@ -38,54 +33,6 @@ public final class DbUtil { } } - /** - * 获得默认数据源 - * - * @return 默认数据源 - */ - public static DataSource getDs() { - return DSFactory.get(); - } - - /** - * 获取指定分组的数据源 - * - * @param group 分组 - * @return 数据源 - */ - public static DataSource getDs(final String group) { - return DSFactory.get(group); - } - - /** - * 获得JNDI数据源 - * - * @param jndiName JNDI名称 - * @return 数据源 - */ - public static DataSource getJndiDsWithLog(final String jndiName) { - try { - return getJndiDs(jndiName); - } catch (final DbRuntimeException e) { - log.error(e.getCause(), "Find JNDI datasource error!"); - } - return null; - } - - /** - * 获得JNDI数据源 - * - * @param jndiName JNDI名称 - * @return 数据源 - */ - public static DataSource getJndiDs(final String jndiName) { - try { - return (DataSource) new InitialContext().lookup(jndiName); - } catch (final NamingException e) { - throw new DbRuntimeException(e); - } - } - /** * 移除配置文件中的Show SQL相关配置项
* 此方法用于移除用户配置在分组下的配置项目 diff --git a/hutool-db/src/main/java/cn/hutool/db/Session.java b/hutool-db/src/main/java/cn/hutool/db/Session.java index 8d809b338..b52afad4b 100644 --- a/hutool-db/src/main/java/cn/hutool/db/Session.java +++ b/hutool-db/src/main/java/cn/hutool/db/Session.java @@ -4,7 +4,7 @@ import cn.hutool.core.lang.func.SerConsumer; import cn.hutool.core.text.StrUtil; import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.DialectFactory; -import cn.hutool.db.ds.DSFactory; +import cn.hutool.db.ds.DSUtil; import cn.hutool.log.Log; import cn.hutool.log.LogFactory; @@ -34,7 +34,7 @@ public class Session extends AbstractDb implements Closeable { * @since 3.2.3 */ public static Session of() { - return new Session(DSFactory.get()); + return new Session(DSUtil.getDS()); } /** @@ -45,7 +45,7 @@ public class Session extends AbstractDb implements Closeable { * @since 4.0.11 */ public static Session of(final String group) { - return new Session(DSFactory.get(group)); + return new Session(DSUtil.getDS(group)); } /** diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DriverUtil.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DriverUtil.java index 757eb78ae..0d612b4ac 100644 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/DriverUtil.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DriverUtil.java @@ -9,7 +9,7 @@ import javax.sql.DataSource; import cn.hutool.core.text.StrUtil; import cn.hutool.db.DbRuntimeException; import cn.hutool.db.DbUtil; -import cn.hutool.db.ds.DataSourceWrapper; +import cn.hutool.db.ds.DSWrapper; /** * 驱动相关工具类,包括自动获取驱动类名 @@ -36,8 +36,8 @@ public class DriverUtil { * @return 驱动 */ public static String identifyDriver(final DataSource ds) { - if(ds instanceof DataSourceWrapper) { - final String driver = ((DataSourceWrapper)ds).getDriver(); + if(ds instanceof DSWrapper) { + final String driver = ((DSWrapper)ds).getDriver(); if(StrUtil.isNotBlank(driver)) { return driver; } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java index 5ac0c7d96..0829da04b 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java @@ -21,9 +21,13 @@ import java.util.Map; * * @author looly */ -public abstract class AbstractDSFactory extends DSFactory { +public abstract class AbstractDSFactory implements DSFactory { private static final long serialVersionUID = -6407302276272379881L; + /** + * 数据源名 + */ + protected final String dataSourceName; /** * 数据库连接配置文件 */ @@ -31,7 +35,7 @@ public abstract class AbstractDSFactory extends DSFactory { /** * 数据源池 */ - private final Map dsMap; + private final Map dsMap; /** * 构造 @@ -42,18 +46,18 @@ public abstract class AbstractDSFactory extends DSFactory { * @param setting 数据库连接配置,如果为{@code null},则读取全局自定义或默认配置 */ public AbstractDSFactory(final String dataSourceName, final Class dataSourceClass, Setting setting) { - super(dataSourceName); //此参数的作用是在detectDSFactory方法自动检测所用连接池时,如果实现类不存在,调用此方法会自动抛出异常,从而切换到下一种连接池的检测。 Assert.notNull(dataSourceClass); + this.dataSourceName = dataSourceName; + if (null == setting) { setting = GlobalDbConfig.createDbSetting(); } - // 读取配置,用于SQL打印 DbUtil.setShowSqlGlobal(setting); - this.setting = setting; + this.dsMap = new SafeConcurrentHashMap<>(); } @@ -68,91 +72,38 @@ public abstract class AbstractDSFactory extends DSFactory { } @Override - synchronized public DataSource getDataSource(String group) { + public String getDataSourceName() { + return this.dataSourceName; + } + + @Override + public DataSource getDataSource(String group) { if (group == null) { group = StrUtil.EMPTY; } // 如果已经存在已有数据源(连接池)直接返回 - final DataSourceWrapper existedDataSource = dsMap.get(group); - if (existedDataSource != null) { - return existedDataSource; - } - - final DataSourceWrapper ds = createDataSource(group); - // 添加到数据源池中,以备下次使用 - dsMap.put(group, ds); - return ds; + return dsMap.computeIfAbsent(group, this::_createDataSource); } - /** - * 创建数据源 - * - * @param group 分组 - * @return {@link DataSourceWrapper} 数据源包装 - */ - private DataSourceWrapper createDataSource(String group) { - if (group == null) { - group = StrUtil.EMPTY; - } - - final Setting config = setting.getSetting(group); - if (MapUtil.isEmpty(config)) { - throw new DbRuntimeException("No config for group: [{}]", group); - } - - // 基本信息 - final String url = config.getAndRemove(KEY_ALIAS_URL); - if (StrUtil.isBlank(url)) { - throw new DbRuntimeException("No JDBC URL for group: [{}]", group); - } - - // 移除用户可能误加入的show sql配置项 - // issue#I3VW0R@Gitee - DbUtil.removeShowSqlParams(config); - - // 自动识别Driver - String driver = config.getAndRemove(KEY_ALIAS_DRIVER); - if (StrUtil.isBlank(driver)) { - driver = DriverUtil.identifyDriver(url); - } - final String user = config.getAndRemove(KEY_ALIAS_USER); - final String pass = config.getAndRemove(KEY_ALIAS_PASSWORD); - - return DataSourceWrapper.wrap(createDataSource(url, driver, user, pass, config), driver); - } - - /** - * 创建新的{@link DataSource}
- * - * @param jdbcUrl JDBC连接字符串 - * @param driver 数据库驱动类名 - * @param user 用户名 - * @param pass 密码 - * @param poolSetting 分组下的连接池配置文件 - * @return {@link DataSource} - */ - protected abstract DataSource createDataSource(String jdbcUrl, String driver, String user, String pass, Setting poolSetting); - @Override - public void close(String group) { + synchronized public void closeDataSource(String group) { if (group == null) { group = StrUtil.EMPTY; } - final DataSourceWrapper ds = dsMap.get(group); + final DSWrapper ds = dsMap.get(group); if (ds != null) { ds.close(); - //noinspection resource dsMap.remove(group); } } @Override - public void destroy() { + public void close() { if (MapUtil.isNotEmpty(dsMap)) { - final Collection values = dsMap.values(); - for (final DataSourceWrapper ds : values) { + final Collection values = dsMap.values(); + for (final DSWrapper ds : values) { ds.close(); } dsMap.clear(); @@ -193,4 +144,54 @@ public abstract class AbstractDSFactory extends DSFactory { return setting.equals(other.setting); } } + + /** + * 创建新的{@link DataSource}
+ * 子类通过实现此方法,创建一个对接连接池的数据源 + * + * @param jdbcUrl JDBC连接字符串 + * @param driver 数据库驱动类名 + * @param user 用户名 + * @param pass 密码 + * @param poolSetting 分组下的连接池配置文件 + * @return {@link DataSource} + */ + protected abstract DataSource createDataSource(String jdbcUrl, String driver, String user, String pass, Setting poolSetting); + + /** + * 创建数据源,对于不同连接池名称的的差异做兼容,如用户配置user和username都表示用户名 + * + * @param group 分组 + * @return {@link DSWrapper} 数据源包装 + */ + private DSWrapper _createDataSource(String group) { + if (group == null) { + group = StrUtil.EMPTY; + } + + final Setting config = setting.getSetting(group); + if (MapUtil.isEmpty(config)) { + throw new DbRuntimeException("No config for group: [{}]", group); + } + + // 基本信息 + final String url = config.getAndRemove(DSKeys.KEY_ALIAS_URL); + if (StrUtil.isBlank(url)) { + throw new DbRuntimeException("No JDBC URL for group: [{}]", group); + } + + // 移除用户可能误加入的show sql配置项 + // issue#I3VW0R@Gitee + DbUtil.removeShowSqlParams(config); + + // 自动识别Driver + String driver = config.getAndRemove(DSKeys.KEY_ALIAS_DRIVER); + if (StrUtil.isBlank(driver)) { + driver = DriverUtil.identifyDriver(url); + } + final String user = config.getAndRemove(DSKeys.KEY_ALIAS_USER); + final String pass = config.getAndRemove(DSKeys.KEY_ALIAS_PASSWORD); + + return DSWrapper.wrap(createDataSource(url, driver, user, pass, config), driver); + } } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java index 18a3a8656..c6e50fc75 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/DSFactory.java @@ -1,15 +1,6 @@ package cn.hutool.db.ds; import cn.hutool.core.text.StrUtil; -import cn.hutool.db.ds.bee.BeeDSFactory; -import cn.hutool.db.ds.c3p0.C3p0DSFactory; -import cn.hutool.db.ds.dbcp.DbcpDSFactory; -import cn.hutool.db.ds.druid.DruidDSFactory; -import cn.hutool.db.ds.hikari.HikariDSFactory; -import cn.hutool.db.ds.pooled.PooledDSFactory; -import cn.hutool.db.ds.tomcat.TomcatDSFactory; -import cn.hutool.log.Log; -import cn.hutool.log.LogFactory; import cn.hutool.setting.Setting; import javax.sql.DataSource; @@ -17,48 +8,40 @@ import java.io.Closeable; import java.io.Serializable; /** - * 抽象数据源工厂类
- * 通过实现{@link #getDataSource(String)} 方法实现数据源的获取
- * 如果{@link DataSource} 的实现是数据库连接池库,应该在getDataSource调用时创建数据源并缓存 + * 多数据源工厂方法接口,借助不同配置,同一个工厂可以连接多个相同或不同的数据库,但是连接池只能使用一种。
+ * 通过实现{@link #getDataSource(String)} 方法完成数据源的获取。
+ * 如果{@link DataSource} 的实现是数据库连接池库,应该在getDataSource调用时创建数据源并缓存,关系如下: + *
+ *                            DSFactory
+ *            _____________________|____________________
+ *            |              |             |           |
+ *     HikariDSFactory DruidDSFactory XXXDSFactory    ...
+ *       _____|____          |        _____|____
+ *       |        |          |        |        |
+ *     MySQL    SQLite    SQLServer  XXXDB   XXXDB2
+ * 
+ * + *

+ * 工厂创建请使用{@link DSUtil#createFactory(Setting)} + *

* * @author Looly - * */ -public abstract class DSFactory implements Closeable, Serializable{ - private static final long serialVersionUID = -8789780234095234765L; - - private static final Log log = LogFactory.get(); - - /** 某些数据库需要的特殊配置项需要的配置项 */ - public static final String[] KEY_CONN_PROPS = {"remarks", "useInformationSchema"}; - - /** 别名字段名:URL */ - public static final String[] KEY_ALIAS_URL = { "url", "jdbcUrl" }; - /** 别名字段名:驱动名 */ - public static final String[] KEY_ALIAS_DRIVER = { "driver", "driverClassName" }; - /** 别名字段名:用户名 */ - public static final String[] KEY_ALIAS_USER = { "user", "username" }; - /** 别名字段名:密码 */ - public static final String[] KEY_ALIAS_PASSWORD = { "pass", "password" }; - - /** 数据源名 */ - protected final String dataSourceName; +public interface DSFactory extends Closeable, Serializable { /** - * 构造 + * 获取自定义的数据源名称,用于识别连接池 * - * @param dataSourceName 数据源名称 + * @return 自定义的数据源名称 */ - public DSFactory(final String dataSourceName) { - this.dataSourceName = dataSourceName; - } + String getDataSourceName(); /** - * 获得默认数据源 + * 获得默认数据源,即""分组的数据源 * * @return 数据源 */ - public DataSource getDataSource() { + default DataSource getDataSource() { return getDataSource(StrUtil.EMPTY); } @@ -68,123 +51,19 @@ public abstract class DSFactory implements Closeable, Serializable{ * @param group 分组名 * @return 数据源 */ - public abstract DataSource getDataSource(String group); + DataSource getDataSource(String group); /** * 关闭默认数据源(空组) */ - @Override - public void close() { - close(StrUtil.EMPTY); + default void closeDataSource() { + closeDataSource(StrUtil.EMPTY); } /** - * 关闭对应数据源 + * 关闭(归还)对应数据源 * * @param group 分组 */ - public abstract void close(String group); - - /** - * 销毁工厂类,关闭所有数据源 - */ - public abstract void destroy(); - - // ------------------------------------------------------------------------- Static start - /** - * 获得数据源
- * 使用默认配置文件的无分组配置 - * - * @return 数据源 - */ - public static DataSource get() { - return get(null); - } - - /** - * 获得数据源 - * - * @param group 配置文件中对应的分组 - * @return 数据源 - */ - public static DataSource get(final String group) { - return GlobalDSFactory.get().getDataSource(group); - } - - /** - * 设置全局的数据源工厂
- * 在项目中存在多个连接池库的情况下,我们希望使用低优先级的库时使用此方法自定义之
- * 重新定义全局的数据源工厂此方法可在以下两种情况下调用: - * - *
-	 * 1. 在get方法调用前调用此方法来自定义全局的数据源工厂
-	 * 2. 替换已存在的全局数据源工厂,当已存在时会自动关闭
-	 * 
- * - * @param dsFactory 数据源工厂 - * @return 自定义的数据源工厂 - */ - public static DSFactory setCurrentDSFactory(final DSFactory dsFactory) { - return GlobalDSFactory.set(dsFactory); - } - - /** - * 创建数据源实现工厂
- * 此方法通过“试错”方式查找引入项目的连接池库,按照优先级寻找,一旦寻找到则创建对应的数据源工厂
- * 连接池优先级:Hikari > Druid > Tomcat > Dbcp > C3p0 > Hutool Pooled - * - * @param setting 数据库配置项 - * @return 日志实现类 - */ - public static DSFactory of(final Setting setting) { - final DSFactory dsFactory = doCreate(setting); - log.debug("Use [{}] DataSource As Default", dsFactory.dataSourceName); - return dsFactory; - } - - /** - * 创建数据源实现工厂
- * 此方法通过“试错”方式查找引入项目的连接池库,按照优先级寻找,一旦寻找到则创建对应的数据源工厂
- * 连接池优先级:Hikari > Druid > Tomcat > BeeCP > Dbcp > C3p0 > Hutool Pooled - * - * @param setting 数据库配置项 - * @return 日志实现类 - * @since 4.1.3 - */ - private static DSFactory doCreate(final Setting setting) { - try { - return new HikariDSFactory(setting); - } catch (final NoClassDefFoundError | NoSuchMethodError e) { - // ignore - } - try { - return new DruidDSFactory(setting); - } catch (final NoClassDefFoundError | NoSuchMethodError e) { - // ignore - } - try { - return new TomcatDSFactory(setting); - } catch (final NoClassDefFoundError | NoSuchMethodError e) { - //如果未引入包,此处会报org.apache.tomcat.jdbc.pool.PoolConfiguration未找到错误 - //因为org.apache.tomcat.jdbc.pool.DataSource实现了此接口,会首先检查接口的存在与否 - // ignore - } - try { - return new BeeDSFactory(setting); - } catch (final NoClassDefFoundError | NoSuchMethodError e) { - // ignore - } - try { - return new DbcpDSFactory(setting); - } catch (final NoClassDefFoundError | NoSuchMethodError e) { - // ignore - } - try { - return new C3p0DSFactory(setting); - } catch (final NoClassDefFoundError | NoSuchMethodError e) { - // ignore - } - return new PooledDSFactory(setting); - } - // ------------------------------------------------------------------------- Static end + void closeDataSource(String group); } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/DSKeys.java b/hutool-db/src/main/java/cn/hutool/db/ds/DSKeys.java new file mode 100644 index 000000000..4a18cb627 --- /dev/null +++ b/hutool-db/src/main/java/cn/hutool/db/ds/DSKeys.java @@ -0,0 +1,22 @@ +package cn.hutool.db.ds; + +/** + * 数据源配置的字段名 + * + * @since 6.0.0 + * @author Looly + */ +public interface DSKeys { + + /** 某些数据库需要的特殊配置项需要的配置项 */ + String[] KEY_CONN_PROPS = {"remarks", "useInformationSchema"}; + + /** 别名字段名:URL */ + String[] KEY_ALIAS_URL = { "url", "jdbcUrl" }; + /** 别名字段名:驱动名 */ + String[] KEY_ALIAS_DRIVER = { "driver", "driverClassName" }; + /** 别名字段名:用户名 */ + String[] KEY_ALIAS_USER = { "user", "username" }; + /** 别名字段名:密码 */ + String[] KEY_ALIAS_PASSWORD = { "pass", "password" }; +} diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/DSUtil.java b/hutool-db/src/main/java/cn/hutool/db/ds/DSUtil.java new file mode 100644 index 000000000..4ac9fffb7 --- /dev/null +++ b/hutool-db/src/main/java/cn/hutool/db/ds/DSUtil.java @@ -0,0 +1,151 @@ +package cn.hutool.db.ds; + +import cn.hutool.db.DbRuntimeException; +import cn.hutool.db.ds.bee.BeeDSFactory; +import cn.hutool.db.ds.c3p0.C3p0DSFactory; +import cn.hutool.db.ds.dbcp.DbcpDSFactory; +import cn.hutool.db.ds.druid.DruidDSFactory; +import cn.hutool.db.ds.hikari.HikariDSFactory; +import cn.hutool.db.ds.pooled.PooledDSFactory; +import cn.hutool.db.ds.tomcat.TomcatDSFactory; +import cn.hutool.log.StaticLog; +import cn.hutool.setting.Setting; + +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; + +/** + * {@link DataSource}和{@link DSFactory}相关工具类
+ * 主要提供数据源工厂的创建和数据源的获取 + * + * @author looly + * @since 6.0.0 + */ +public class DSUtil { + + /** + * 获得JNDI数据源 + * + * @param jndiName JNDI名称 + * @return 数据源 + */ + public static DataSource getJndiDSWithLog(final String jndiName) { + try { + return getJndiDS(jndiName); + } catch (final DbRuntimeException e) { + StaticLog.error(e.getCause(), "Find JNDI datasource error!"); + } + return null; + } + + /** + * 获得JNDI数据源 + * + * @param jndiName JNDI名称 + * @return 数据源 + */ + public static DataSource getJndiDS(final String jndiName) { + try { + return (DataSource) new InitialContext().lookup(jndiName); + } catch (final NamingException e) { + throw new DbRuntimeException(e); + } + } + + /** + * 获得数据源
+ * 使用默认配置文件的无分组配置 + * + * @return 数据源 + */ + public static DataSource getDS() { + return getDS(null); + } + + /** + * 获得数据源 + * + * @param group 配置文件中对应的分组 + * @return 数据源 + */ + public static DataSource getDS(final String group) { + return GlobalDSFactory.get().getDataSource(group); + } + + /** + * 设置全局的数据源工厂
+ * 在项目中存在多个连接池库的情况下,我们希望使用低优先级的库时使用此方法自定义之
+ * 重新定义全局的数据源工厂此方法可在以下两种情况下调用: + * + *
+	 * 1. 在get方法调用前调用此方法来自定义全局的数据源工厂
+	 * 2. 替换已存在的全局数据源工厂,当已存在时会自动关闭
+	 * 
+ * + * @param dsFactory 数据源工厂 + * @return 自定义的数据源工厂 + */ + public static DSFactory setGlobalDSFactory(final DSFactory dsFactory) { + return GlobalDSFactory.set(dsFactory); + } + + /** + * 创建数据源实现工厂
+ * 此方法通过“试错”方式查找引入项目的连接池库,按照优先级寻找,一旦寻找到则创建对应的数据源工厂
+ * 连接池优先级:Hikari > Druid > Tomcat > Dbcp > C3p0 > Hutool Pooled + * + * @param setting 数据库配置项 + * @return 日志实现类 + */ + public static DSFactory createFactory(final Setting setting) { + final DSFactory dsFactory = _createFactory(setting); + StaticLog.debug("Use [{}] DataSource As Default", dsFactory.getDataSourceName()); + return dsFactory; + } + + /** + * 创建数据源实现工厂
+ * 此方法通过“试错”方式查找引入项目的连接池库,按照优先级寻找,一旦寻找到则创建对应的数据源工厂
+ * 连接池优先级:Hikari > Druid > Tomcat > BeeCP > Dbcp > C3p0 > Hutool Pooled + * + * @param setting 数据库配置项 + * @return 日志实现类 + * @since 4.1.3 + */ + private static DSFactory _createFactory(final Setting setting) { + try { + return new HikariDSFactory(setting); + } catch (final NoClassDefFoundError | NoSuchMethodError e) { + // ignore + } + try { + return new DruidDSFactory(setting); + } catch (final NoClassDefFoundError | NoSuchMethodError e) { + // ignore + } + try { + return new TomcatDSFactory(setting); + } catch (final NoClassDefFoundError | NoSuchMethodError e) { + //如果未引入包,此处会报org.apache.tomcat.jdbc.pool.PoolConfiguration未找到错误 + //因为org.apache.tomcat.jdbc.pool.DataSource实现了此接口,会首先检查接口的存在与否 + // ignore + } + try { + return new BeeDSFactory(setting); + } catch (final NoClassDefFoundError | NoSuchMethodError e) { + // ignore + } + try { + return new DbcpDSFactory(setting); + } catch (final NoClassDefFoundError | NoSuchMethodError e) { + // ignore + } + try { + return new C3p0DSFactory(setting); + } catch (final NoClassDefFoundError | NoSuchMethodError e) { + // ignore + } + return new PooledDSFactory(setting); + } +} diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/DataSourceWrapper.java b/hutool-db/src/main/java/cn/hutool/db/ds/DSWrapper.java similarity index 87% rename from hutool-db/src/main/java/cn/hutool/db/ds/DataSourceWrapper.java rename to hutool-db/src/main/java/cn/hutool/db/ds/DSWrapper.java index 6a58ee5ef..4fff87eac 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/DataSourceWrapper.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/DSWrapper.java @@ -22,7 +22,7 @@ import java.util.logging.Logger; * @author looly * @since 4.3.2 */ -public class DataSourceWrapper implements Wrapper, DataSource, Closeable, Cloneable { +public class DSWrapper implements Wrapper, DataSource, Closeable, Cloneable { private final DataSource ds; private final String driver; @@ -34,8 +34,8 @@ public class DataSourceWrapper implements Wrapper, DataSource, Close * @param driver 数据库驱动类名 * @return DataSourceWrapper */ - public static DataSourceWrapper wrap(final DataSource ds, final String driver) { - return new DataSourceWrapper(ds, driver); + public static DSWrapper wrap(final DataSource ds, final String driver) { + return new DSWrapper(ds, driver); } /** @@ -44,7 +44,7 @@ public class DataSourceWrapper implements Wrapper, DataSource, Close * @param ds 原始的DataSource * @param driver 数据库驱动类名 */ - public DataSourceWrapper(final DataSource ds, final String driver) { + public DSWrapper(final DataSource ds, final String driver) { this.ds = ds; this.driver = driver; } @@ -121,9 +121,9 @@ public class DataSourceWrapper implements Wrapper, DataSource, Close } @Override - public DataSourceWrapper clone() { + public DSWrapper clone() { try { - return (DataSourceWrapper) super.clone(); + return (DSWrapper) super.clone(); } catch (final CloneNotSupportedException e) { throw new CloneRuntimeException(e); } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/GlobalDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/GlobalDSFactory.java index fa60de40c..7fb5d4b57 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/GlobalDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/GlobalDSFactory.java @@ -1,9 +1,11 @@ package cn.hutool.db.ds; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.RuntimeUtil; import cn.hutool.log.StaticLog; /** - * 全局的数据源工厂
+ * 全局单例数据源工厂
* 一般情况下,一个应用默认只使用一种数据库连接池,因此维护一个全局的数据源工厂类减少判断连接池类型造成的性能浪费 * * @author looly @@ -19,14 +21,11 @@ public class GlobalDSFactory { */ static { // JVM关闭时关闭所有连接池 - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - if (null != factory) { - factory.destroy(); - StaticLog.debug("DataSource: [{}] destroyed.", factory.dataSourceName); - factory = null; - } + RuntimeUtil.addShutdownHook(()->{ + if (null != factory) { + IoUtil.close(factory); + StaticLog.debug("DataSource: [{}] closed.", factory.getDataSourceName()); + factory = null; } }); } @@ -42,7 +41,7 @@ public class GlobalDSFactory { if (null == factory) { synchronized (lock) { if (null == factory) { - factory = DSFactory.of(null); + factory = DSUtil.createFactory(null); } } } @@ -69,10 +68,10 @@ public class GlobalDSFactory { return factory;// 数据源工厂不变时返回原数据源工厂 } // 自定义数据源工厂前关闭之前的数据源 - factory.destroy(); + IoUtil.close(factory); } - StaticLog.debug("Custom use [{}] DataSource.", customDSFactory.dataSourceName); + StaticLog.debug("Custom use [{}] DataSource.", customDSFactory.getDataSourceName()); factory = customDSFactory; } return factory; diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/bee/BeeDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/bee/BeeDSFactory.java index 33511dd8b..4842105ee 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/bee/BeeDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/bee/BeeDSFactory.java @@ -4,6 +4,7 @@ import cn.beecp.BeeDataSource; import cn.beecp.BeeDataSourceConfig; import cn.hutool.core.text.StrUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import javax.sql.DataSource; @@ -12,17 +13,27 @@ import javax.sql.DataSource; * BeeCP数据源工厂类 * * @author Looly - * */ public class BeeDSFactory extends AbstractDSFactory { private static final long serialVersionUID = 1L; + /** + * 连接池名称:BeeCP + */ public static final String DS_NAME = "BeeCP"; + /** + * 构造,使用默认配置文件 + */ public BeeDSFactory() { this(null); } + /** + * 构造,使用自定义配置文件 + * + * @param setting 配置文件 + */ public BeeDSFactory(final Setting setting) { super(DS_NAME, BeeDataSource.class, setting); } @@ -35,9 +46,9 @@ public class BeeDSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.getAndRemove(key); - if(StrUtil.isNotBlank(connValue)){ + if (StrUtil.isNotBlank(connValue)) { beeConfig.addConnectProperty(key, connValue); } } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/c3p0/C3p0DSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/c3p0/C3p0DSFactory.java index 148c56e63..c04bd6ddf 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/c3p0/C3p0DSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/c3p0/C3p0DSFactory.java @@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.db.DbRuntimeException; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import cn.hutool.setting.dialect.Props; import com.mchange.v2.c3p0.ComboPooledDataSource; @@ -12,7 +13,7 @@ import javax.sql.DataSource; import java.beans.PropertyVetoException; /** - * Druid数据源工厂类 + * C3P0数据源工厂类 * * @author Looly * @@ -20,6 +21,9 @@ import java.beans.PropertyVetoException; public class C3p0DSFactory extends AbstractDSFactory { private static final long serialVersionUID = -6090788225842047281L; + /** + * 数据源名称:C3P0 + */ public static final String DS_NAME = "C3P0"; /** @@ -30,7 +34,7 @@ public class C3p0DSFactory extends AbstractDSFactory { } /** - * 构造 + * 构造,使用自定义配置文件 * * @param setting 配置 */ @@ -45,7 +49,7 @@ public class C3p0DSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 final Props connProps = new Props(); String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.getAndRemove(key); if(StrUtil.isNotBlank(connValue)){ connProps.setProperty(key, connValue); diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/dbcp/DbcpDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/dbcp/DbcpDSFactory.java index a6aa80fa2..784ff7a5d 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/dbcp/DbcpDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/dbcp/DbcpDSFactory.java @@ -2,6 +2,7 @@ package cn.hutool.db.ds.dbcp; import cn.hutool.core.text.StrUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import org.apache.commons.dbcp2.BasicDataSource; @@ -16,12 +17,23 @@ import javax.sql.DataSource; public class DbcpDSFactory extends AbstractDSFactory { private static final long serialVersionUID = -9133501414334104548L; + /** + * 数据源名称:commons-dbcp2 + */ public static final String DS_NAME = "commons-dbcp2"; + /** + * 构造,使用默认配置文件 + */ public DbcpDSFactory() { this(null); } + /** + * 构造,使用自定义配置文件 + * + * @param setting 配置 + */ public DbcpDSFactory(final Setting setting) { super(DS_NAME, BasicDataSource.class, setting); } @@ -37,7 +49,7 @@ public class DbcpDSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.getAndRemove(key); if(StrUtil.isNotBlank(connValue)){ ds.addConnectionProperty(key, connValue); diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/druid/DruidDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/druid/DruidDSFactory.java index e9347a1d5..e087f249a 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/druid/DruidDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/druid/DruidDSFactory.java @@ -2,6 +2,7 @@ package cn.hutool.db.ds.druid; import cn.hutool.core.text.StrUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import cn.hutool.setting.dialect.Props; import com.alibaba.druid.pool.DruidDataSource; @@ -17,6 +18,9 @@ import javax.sql.DataSource; public class DruidDSFactory extends AbstractDSFactory { private static final long serialVersionUID = 4680621702534433222L; + /** + * 数据源名称:Druid + */ public static final String DS_NAME = "Druid"; /** @@ -27,9 +31,9 @@ public class DruidDSFactory extends AbstractDSFactory { } /** - * 构造 + * 构造,使用自定义配置文件 * - * @param setting 数据库配置 + * @param setting 配置 */ public DruidDSFactory(final Setting setting) { super(DS_NAME, DruidDataSource.class, setting); @@ -48,7 +52,7 @@ public class DruidDSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 // Druid中也可以通过 druid.connectProperties 属性设置 String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.getAndRemove(key); if(StrUtil.isNotBlank(connValue)){ ds.addConnectionProperty(key, connValue); diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/hikari/HikariDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/hikari/HikariDSFactory.java index dbb57fb3d..b0cf10a35 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/hikari/HikariDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/hikari/HikariDSFactory.java @@ -2,6 +2,7 @@ package cn.hutool.db.ds.hikari; import cn.hutool.core.text.StrUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import cn.hutool.setting.dialect.Props; import com.zaxxer.hikari.HikariConfig; @@ -18,12 +19,23 @@ import javax.sql.DataSource; public class HikariDSFactory extends AbstractDSFactory { private static final long serialVersionUID = -8834744983614749401L; + /** + * 数据源名称:HikariCP + */ public static final String DS_NAME = "HikariCP"; + /** + * 构造,使用默认配置文件 + */ public HikariDSFactory() { this(null); } + /** + * 构造,使用自定义配置文件 + * + * @param setting 配置 + */ public HikariDSFactory(final Setting setting) { super(DS_NAME, HikariDataSource.class, setting); } @@ -33,7 +45,7 @@ public class HikariDSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 final Props connProps = new Props(); String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.getAndRemove(key); if(StrUtil.isNotBlank(connValue)){ connProps.setProperty(key, connValue); diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/jndi/JndiDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/jndi/JndiDSFactory.java index 3550f08fc..0461ad7ed 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/jndi/JndiDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/jndi/JndiDSFactory.java @@ -1,20 +1,20 @@ package cn.hutool.db.ds.jndi; -import javax.sql.DataSource; - import cn.hutool.core.text.StrUtil; import cn.hutool.db.DbRuntimeException; -import cn.hutool.db.DbUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSUtil; import cn.hutool.setting.Setting; +import javax.sql.DataSource; + /** * JNDI数据源工厂类
- * Setting配置样例:
- * ---------------------
- * [group]
- * jndi = jdbc/TestDB
- * ---------------------
+ * Setting配置样例: + *
+ *     [group]
+ *     jndi = jdbc/TestDB
+ * 
* * @author Looly * @@ -22,12 +22,23 @@ import cn.hutool.setting.Setting; public class JndiDSFactory extends AbstractDSFactory { private static final long serialVersionUID = 1573625812927370432L; + /** + * 数据源名称:JNDI DataSource + */ public static final String DS_NAME = "JNDI DataSource"; + /** + * 构造,使用默认配置文件 + */ public JndiDSFactory() { this(null); } + /** + * 构造,使用自定义配置文件 + * + * @param setting 配置 + */ public JndiDSFactory(final Setting setting) { super(DS_NAME, null, setting); } @@ -38,6 +49,6 @@ public class JndiDSFactory extends AbstractDSFactory { if (StrUtil.isEmpty(jndiName)) { throw new DbRuntimeException("No setting name [jndi] for this group."); } - return DbUtil.getJndiDs(jndiName); + return DSUtil.getJndiDS(jndiName); } } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/package-info.java b/hutool-db/src/main/java/cn/hutool/db/ds/package-info.java index a41975bd5..eb65e5b01 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/package-info.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/package-info.java @@ -1,7 +1,8 @@ /** - * 数据源封装,对各类数据库连接池的封装 - * + * 数据源封装,对各类数据库连接池的封装
+ * 数据库连接池使用工厂方法模式,当有新增连接池时,实现{@link cn.hutool.db.ds.DSFactory}即可。 + * * @author looly * */ -package cn.hutool.db.ds; \ No newline at end of file +package cn.hutool.db.ds; diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/pooled/DbSetting.java b/hutool-db/src/main/java/cn/hutool/db/ds/pooled/DbSetting.java index 60a899d9b..e33cbd99a 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/pooled/DbSetting.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/pooled/DbSetting.java @@ -4,7 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.db.DbRuntimeException; import cn.hutool.db.dialect.DriverUtil; -import cn.hutool.db.ds.DSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; /** @@ -54,16 +54,16 @@ public class DbSetting { final DbConfig dbConfig = new DbConfig(); // 基本信息 - final String url = config.getAndRemove(DSFactory.KEY_ALIAS_URL); + final String url = config.getAndRemove(DSKeys.KEY_ALIAS_URL); if (StrUtil.isBlank(url)) { throw new DbRuntimeException("No JDBC URL for group: [{}]", group); } dbConfig.setUrl(url); // 自动识别Driver - final String driver = config.getAndRemove(DSFactory.KEY_ALIAS_DRIVER); + final String driver = config.getAndRemove(DSKeys.KEY_ALIAS_DRIVER); dbConfig.setDriver(StrUtil.isNotBlank(driver) ? driver : DriverUtil.identifyDriver(url)); - dbConfig.setUser(config.getAndRemove(DSFactory.KEY_ALIAS_USER)); - dbConfig.setPass(config.getAndRemove(DSFactory.KEY_ALIAS_PASSWORD)); + dbConfig.setUser(config.getAndRemove(DSKeys.KEY_ALIAS_USER)); + dbConfig.setPass(config.getAndRemove(DSKeys.KEY_ALIAS_PASSWORD)); // 连接池相关信息 dbConfig.setInitialSize(setting.getIntByGroup("initialSize", group, 0)); @@ -73,7 +73,7 @@ public class DbSetting { // remarks等特殊配置,since 5.3.8 String connValue; - for (final String key : DSFactory.KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = config.get(key); if(StrUtil.isNotBlank(connValue)){ dbConfig.addConnProps(key, connValue); diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/pooled/PooledDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/pooled/PooledDSFactory.java index 9ffc5dcc0..b37658a22 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/pooled/PooledDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/pooled/PooledDSFactory.java @@ -2,6 +2,7 @@ package cn.hutool.db.ds.pooled; import cn.hutool.core.text.StrUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import javax.sql.DataSource; @@ -15,12 +16,23 @@ import javax.sql.DataSource; public class PooledDSFactory extends AbstractDSFactory { private static final long serialVersionUID = 8093886210895248277L; + /** + * 数据源名称:Hutool-Pooled-DataSource + */ public static final String DS_NAME = "Hutool-Pooled-DataSource"; + /** + * 构造,使用默认配置文件 + */ public PooledDSFactory() { this(null); } + /** + * 构造,使用自定义配置文件 + * + * @param setting 配置 + */ public PooledDSFactory(final Setting setting) { super(DS_NAME, PooledDataSource.class, setting); } @@ -41,7 +53,7 @@ public class PooledDSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.get(key); if(StrUtil.isNotBlank(connValue)){ dbConfig.addConnProps(key, connValue); diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDSFactory.java index f596dfabe..3ebab1184 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDSFactory.java @@ -14,12 +14,23 @@ import javax.sql.DataSource; public class SimpleDSFactory extends AbstractDSFactory { private static final long serialVersionUID = 4738029988261034743L; + /** + * 数据源名称:Hutool-Simple-DataSource + */ public static final String DS_NAME = "Hutool-Simple-DataSource"; + /** + * 构造,使用默认配置文件 + */ public SimpleDSFactory() { this(null); } + /** + * 构造,使用自定义配置文件 + * + * @param setting 配置 + */ public SimpleDSFactory(final Setting setting) { super(DS_NAME, SimpleDataSource.class, setting); } diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDataSource.java b/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDataSource.java index 6e21137f7..dd029346e 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDataSource.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/simple/SimpleDataSource.java @@ -4,7 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.db.DbRuntimeException; import cn.hutool.db.dialect.DriverUtil; -import cn.hutool.db.ds.DSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import cn.hutool.setting.dialect.Props; @@ -34,25 +34,6 @@ public class SimpleDataSource extends AbstractDataSource { private Properties connProps; // -------------------------------------------------------------------- Fields end - /** - * 获得一个数据源 - * - * @param group 数据源分组 - * @return SimpleDataSource - */ - synchronized public static SimpleDataSource getDataSource(final String group) { - return new SimpleDataSource(group); - } - - /** - * 获得一个数据源,无分组 - * - * @return SimpleDataSource - */ - synchronized public static SimpleDataSource getDataSource() { - return new SimpleDataSource(); - } - // -------------------------------------------------------------------- Constructor start /** * 构造 @@ -86,10 +67,10 @@ public class SimpleDataSource extends AbstractDataSource { } init(// - config.getAndRemove(DSFactory.KEY_ALIAS_URL), // - config.getAndRemove(DSFactory.KEY_ALIAS_USER), // - config.getAndRemove(DSFactory.KEY_ALIAS_PASSWORD), // - config.getAndRemove(DSFactory.KEY_ALIAS_DRIVER)// + config.getAndRemove(DSKeys.KEY_ALIAS_URL), // + config.getAndRemove(DSKeys.KEY_ALIAS_USER), // + config.getAndRemove(DSKeys.KEY_ALIAS_PASSWORD), // + config.getAndRemove(DSKeys.KEY_ALIAS_DRIVER)// ); // 其它连接参数 diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/tomcat/TomcatDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/tomcat/TomcatDSFactory.java index 94975f446..0c0ad18ce 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/tomcat/TomcatDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/tomcat/TomcatDSFactory.java @@ -2,6 +2,7 @@ package cn.hutool.db.ds.tomcat; import cn.hutool.core.text.StrUtil; import cn.hutool.db.ds.AbstractDSFactory; +import cn.hutool.db.ds.DSKeys; import cn.hutool.setting.Setting; import cn.hutool.setting.dialect.Props; import org.apache.tomcat.jdbc.pool.DataSource; @@ -16,6 +17,9 @@ import org.apache.tomcat.jdbc.pool.PoolProperties; public class TomcatDSFactory extends AbstractDSFactory { private static final long serialVersionUID = 4925514193275150156L; + /** + * 数据源名称:Tomcat-Jdbc-Pool + */ public static final String DS_NAME = "Tomcat-Jdbc-Pool"; /** @@ -26,7 +30,7 @@ public class TomcatDSFactory extends AbstractDSFactory { } /** - * 构造 + * 构造,自定义配置 * * @param setting Setting数据库配置 */ @@ -45,7 +49,7 @@ public class TomcatDSFactory extends AbstractDSFactory { // remarks等特殊配置,since 5.3.8 final Props connProps = new Props(); String connValue; - for (final String key : KEY_CONN_PROPS) { + for (final String key : DSKeys.KEY_CONN_PROPS) { connValue = poolSetting.getAndRemove(key); if(StrUtil.isNotBlank(connValue)){ connProps.setProperty(key, connValue); diff --git a/hutool-db/src/test/java/cn/hutool/db/DsTest.java b/hutool-db/src/test/java/cn/hutool/db/DsTest.java index b0a8db000..d9ed488f4 100644 --- a/hutool-db/src/test/java/cn/hutool/db/DsTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/DsTest.java @@ -1,8 +1,8 @@ package cn.hutool.db; import cn.hutool.core.collection.CollUtil; -import cn.hutool.db.ds.DSFactory; -import cn.hutool.db.ds.DataSourceWrapper; +import cn.hutool.db.ds.DSUtil; +import cn.hutool.db.ds.DSWrapper; import cn.hutool.db.ds.bee.BeeDSFactory; import cn.hutool.db.ds.c3p0.C3p0DSFactory; import cn.hutool.db.ds.dbcp.DbcpDSFactory; @@ -27,7 +27,7 @@ public class DsTest { @Test public void defaultDsTest() { - final DataSource ds = DSFactory.get("test"); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); @@ -35,8 +35,8 @@ public class DsTest { @Test public void hikariDsTest() { - DSFactory.setCurrentDSFactory(new HikariDSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new HikariDSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); @@ -44,8 +44,8 @@ public class DsTest { @Test public void druidDsTest() { - DSFactory.setCurrentDSFactory(new DruidDSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new DruidDSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); @@ -54,8 +54,8 @@ public class DsTest { @Test public void tomcatDsTest() { - DSFactory.setCurrentDSFactory(new TomcatDSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new TomcatDSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); @@ -63,8 +63,8 @@ public class DsTest { @Test public void beeCPDsTest() { - DSFactory.setCurrentDSFactory(new BeeDSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new BeeDSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); @@ -72,8 +72,8 @@ public class DsTest { @Test public void dbcpDsTest() { - DSFactory.setCurrentDSFactory(new DbcpDSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new DbcpDSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); @@ -81,8 +81,8 @@ public class DsTest { @Test public void c3p0DsTest() { - DSFactory.setCurrentDSFactory(new C3p0DSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new C3p0DSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); @@ -91,16 +91,16 @@ public class DsTest { @Test public void c3p0DsuserAndPassTest() { // https://gitee.com/dromara/hutool/issues/I4T7XZ - DSFactory.setCurrentDSFactory(new C3p0DSFactory()); - final ComboPooledDataSource ds = (ComboPooledDataSource) ((DataSourceWrapper) DSFactory.get("mysql")).getRaw(); + DSUtil.setGlobalDSFactory(new C3p0DSFactory()); + final ComboPooledDataSource ds = (ComboPooledDataSource) ((DSWrapper) DSUtil.getDS("mysql")).getRaw(); Assert.assertEquals("root", ds.getUser()); Assert.assertEquals("123456", ds.getPassword()); } @Test public void hutoolPoolTest() { - DSFactory.setCurrentDSFactory(new PooledDSFactory()); - final DataSource ds = DSFactory.get("test"); + DSUtil.setGlobalDSFactory(new PooledDSFactory()); + final DataSource ds = DSUtil.getDS("test"); final Db db = Db.of(ds); final List all = db.findAll("user"); Assert.assertTrue(CollUtil.isNotEmpty(all)); diff --git a/hutool-db/src/test/java/cn/hutool/db/ds/DataSourceWrapperTest.java b/hutool-db/src/test/java/cn/hutool/db/ds/DataSourceWrapperTest.java index 14819d78f..09f3f8da1 100644 --- a/hutool-db/src/test/java/cn/hutool/db/ds/DataSourceWrapperTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/ds/DataSourceWrapperTest.java @@ -9,9 +9,9 @@ public class DataSourceWrapperTest { @Test public void cloneTest(){ final SimpleDataSource simpleDataSource = new SimpleDataSource("jdbc:sqlite:test.db", "", ""); - final DataSourceWrapper wrapper = new DataSourceWrapper(simpleDataSource, "test.driver"); + final DSWrapper wrapper = new DSWrapper(simpleDataSource, "test.driver"); - final DataSourceWrapper clone = wrapper.clone(); + final DSWrapper clone = wrapper.clone(); Assert.assertEquals("test.driver", clone.getDriver()); Assert.assertEquals(simpleDataSource, clone.getRaw()); } diff --git a/hutool-db/src/test/java/cn/hutool/db/meta/MetaUtilTest.java b/hutool-db/src/test/java/cn/hutool/db/meta/MetaUtilTest.java index c88ea9526..f4c4bfb04 100644 --- a/hutool-db/src/test/java/cn/hutool/db/meta/MetaUtilTest.java +++ b/hutool-db/src/test/java/cn/hutool/db/meta/MetaUtilTest.java @@ -3,7 +3,7 @@ package cn.hutool.db.meta; import cn.hutool.core.collection.SetUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.split.SplitUtil; -import cn.hutool.db.ds.DSFactory; +import cn.hutool.db.ds.DSUtil; import org.junit.Assert; import org.junit.Test; @@ -17,7 +17,7 @@ import java.util.List; * */ public class MetaUtilTest { - final DataSource ds = DSFactory.get("test"); + final DataSource ds = DSUtil.getDS("test"); @Test public void getTablesTest() {