All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jchanghong.db.ds.AbstractDSFactory Maven / Gradle / Ivy

The newest version!
package com.jchanghong.db.ds;

import com.jchanghong.core.collection.CollectionUtil;
import com.jchanghong.core.io.resource.NoResourceException;
import com.jchanghong.core.lang.Assert;
import com.jchanghong.core.util.StrUtil;
import com.jchanghong.db.DbRuntimeException;
import com.jchanghong.db.DbUtil;
import com.jchanghong.db.dialect.DriverUtil;
import com.jchanghong.setting.Setting;

import javax.sql.DataSource;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 抽象数据源工厂
* 此工厂抽象类用于实现数据源的缓存,当用户多次调用{@link #getDataSource(String)} 时,工厂只需创建一次即可。
* 数据源是与配置文件中的分组相关的,每个分组的数据源相互独立,也就是每个分组的数据源是单例存在的。 * * @author looly * */ public abstract class AbstractDSFactory extends DSFactory { private static final long serialVersionUID = -6407302276272379881L; /** 数据库配置文件可选路径1 */ private static final String DEFAULT_DB_SETTING_PATH = "config/db.setting"; /** 数据库配置文件可选路径2 */ private static final String DEFAULT_DB_SETTING_PATH2 = "db.setting"; /** 数据库连接配置文件 */ private final Setting setting; /** 数据源池 */ private final Map dsMap; /** * 构造 * * @param dataSourceName 数据源名称 * @param dataSourceClass 数据库连接池实现类,用于检测所提供的DataSource类是否存在,当传入的DataSource类不存在时抛出ClassNotFoundException
* 此参数的作用是在detectDSFactory方法自动检测所用连接池时,如果实现类不存在,调用此方法会自动抛出异常,从而切换到下一种连接池的检测。 * @param setting 数据库连接配置 */ public AbstractDSFactory(String dataSourceName, Class dataSourceClass, Setting setting) { super(dataSourceName); //此参数的作用是在detectDSFactory方法自动检测所用连接池时,如果实现类不存在,调用此方法会自动抛出异常,从而切换到下一种连接池的检测。 Assert.notNull(dataSourceClass); if (null == setting) { try { setting = new Setting(DEFAULT_DB_SETTING_PATH, true); } catch (NoResourceException e) { // 尝试ClassPath下直接读取配置文件 try { setting = new Setting(DEFAULT_DB_SETTING_PATH2, true); } catch (NoResourceException e2) { throw new NoResourceException("Default db setting [{}] or [{}] in classpath not found !", DEFAULT_DB_SETTING_PATH, DEFAULT_DB_SETTING_PATH2); } } } // 读取配置,用于SQL打印 DbUtil.setShowSqlGlobal(setting); this.setting = setting; this.dsMap = new ConcurrentHashMap<>(); } /** * 获取配置,用于自定义添加配置项 * * @return Setting * @since 4.0.3 */ public Setting getSetting() { return this.setting; } @Override synchronized 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; } /** * 创建数据源 * * @param group 分组 * @return {@link DataSourceWrapper} 数据源包装 */ private DataSourceWrapper createDataSource(String group) { if (group == null) { group = StrUtil.EMPTY; } final Setting config = setting.getSetting(group); if (CollectionUtil.isEmpty(config)) { throw new DbRuntimeException("No config for group: [{}]", group); } // 基本信息 final String url = config.getAndRemoveStr(KEY_ALIAS_URL); if (StrUtil.isBlank(url)) { throw new DbRuntimeException("No JDBC URL for group: [{}]", group); } // 自动识别Driver String driver = config.getAndRemoveStr(KEY_ALIAS_DRIVER); if (StrUtil.isBlank(driver)) { driver = DriverUtil.identifyDriver(url); } final String user = config.getAndRemoveStr(KEY_ALIAS_USER); final String pass = config.getAndRemoveStr(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) { if (group == null) { group = StrUtil.EMPTY; } DataSourceWrapper ds = dsMap.get(group); if (ds != null) { ds.close(); dsMap.remove(group); } } @Override public void destroy() { if (CollectionUtil.isNotEmpty(dsMap)) { Collection values = dsMap.values(); for (DataSourceWrapper ds : values) { ds.close(); } dsMap.clear(); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((dataSourceName == null) ? 0 : dataSourceName.hashCode()); result = prime * result + ((setting == null) ? 0 : setting.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } AbstractDSFactory other = (AbstractDSFactory) obj; if (dataSourceName == null) { if (other.dataSourceName != null) { return false; } } else if (!dataSourceName.equals(other.dataSourceName)) { return false; } if (setting == null) { return other.setting == null; } else { return setting.equals(other.setting); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy