druid数据源手动创建
手动创建druid数据源,可以使用jdbc或者通过aspect进行多数据源的动态切换
通过md5加密创建唯一key,在key重复时不进行创建,
创建的数据源可以通过dataSourceKey进行bean获取,或者通过jdbctemplate对象进行操作
在druid页面中可以观测到注入的数据源
一、配置实体类-从数据库读取
public class Const { /** * 创建的bean类型 */ public static class BEAN_TYPE { //oracle 数据源 public static final String DB_ORACLE = "4"; //mysql 数据源 public static final String DB_MYSQL = "5"; } }
import lombok.Data; /** * 数据源配置 * * @author luwl * @date 2022/5/11 19:03 */ @Data public class DataSourceConfig { /** * 数据库地址 */ private String ip; /** * 数据库端口 */ private Integer port; /** * 数据库帐号 */ private String userName; /** * 数据库密码 */ private String passWord; /** * 使用的数据库 */ private String dataBase; /** * 数据库驱动 */ private String driver; /** * 数据库连接 */ private String url; /** * 数据库类型 */ private String dbType; /** * 标识符 */ private String dataSourceKey; /** * TODO: 每添加一种新的数据库,则需要添加新的默认配置 * * @return */ public void setDriver(String connectDriver) { if (null == connectDriver || "".equals(connectDriver)) { if (Const.BEAN_TYPE.DB_MYSQL.equals(this.dbType)) { this.driver = "com.mysql.jdbc.Driver"; } else if (Const.BEAN_TYPE.DB_ORACLE.equals(this.dbType)) { this.driver = "oracle.jdbc.OracleDriver"; } }else{ this.driver=connectDriver; } } /** * @return */ public void setUrl(String url) { if (null == url || "".equals(url)) { if (Const.BEAN_TYPE.DB_MYSQL.equals(this.dbType)) { //jdbc:mysql://192.168.99.101:3306/zxjc_v2.0?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&allowMultiQueries=true this.url = "jdbc:mysql://" + this.ip + ":" + this.port + "/" + this.dataBase + "?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&allowMultiQueries=true"; } else if (Const.BEAN_TYPE.DB_ORACLE.equals(this.dbType)) { //jdbc:oracle:thin:@//192.168.99.101:1521/helowin this.url = "jdbc:oracle:thin:@//" + this.ip + ":" + this.port + "/" + this.dataBase; } }else{ this.url=url; } } /** * 创建数据源标识 * * @return */ public String getDefaultDataSourceKey() { StringBuffer sb = new StringBuffer(); sb.append(this.ip + "_"); sb.append(this.port + "_"); sb.append(this.dataBase + "_"); sb.append(this.dbType + "_"); sb.append(this.userName); return Md5Util.getMd5(sb.toString()); } /** * 信息打印 * * @return */ public String printMessage() { StringBuffer sb = new StringBuffer(); sb.append(this.ip + "_"); sb.append(this.port + "_"); sb.append(this.dataBase + "_"); sb.append(this.dbType + "_"); sb.append(this.userName); return sb.toString(); } }
二、数据源工厂
SpringHelper: https://www.cnblogs.com/Sora-L/p/16750136.html
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; /** * 数据源创建工厂 * * @author luwl * @date 2022/5/11 16:18 */ @Slf4j public class DataSourceFactory { /** * 本地数据源集合 */ private static final List<String> myDataSource = Collections.synchronizedList(new ArrayList<>()); private DataSourceFactory() { } private static final DataSourceFactory ME = new DataSourceFactory(); public static DataSourceFactory me() { return ME; } private final int initialSize = 5; private final int maxActive = 20; private final int minIdle = 5; private final int maxWait = 60 * 1000; private final String validationQuery = "SELECT 1"; private final int validationQueryTimeout = 60 * 1000; private final boolean testWhileIdle = true; private final boolean testOnBorrow = false; private final boolean testOnReturn = false; private final boolean failFast = true; private final int timeBetweenEvictionRunsMillis = 6 * 1000; private final int timeBetweenConnectErrorMillis = 500; private final int minEvictableIdleTimeMillis = 60 * 1000; private final int maxEvictableIdleTimeMillis = 25200000; private final boolean poolPreparedStatements = true; private final boolean sharePreparedStatements = false; private final boolean useGlobalDataSourceStat = true; private final int maxPoolPreparedStatementPerConnectionSize = 20; /** * 创建数据源 如果数据源已存在不进行创建 * * @param dataSourceConfig */ public void createDataSource(DataSourceConfig dataSourceConfig) { //加入到缓存中 String dataSourceKey = dataSourceConfig.getDataSourceKey(); //获取默认数据源 DruidDataSource defaultDataSource = SpringHelper.getBean("dataSource"); if (myDataSource.size() == 0 && dataSourceConfig.getUrl().equals(defaultDataSource.getUrl())) { log.warn("当前数据库连接与默认数据源一致,不进行数据源创建"); dataSourceKey = "dataSource"; myDataSource.add(dataSourceKey); dataSourceConfig.setDataSourceKey(dataSourceKey); return; } else if (myDataSource.contains(dataSourceKey)) { log.warn("当前数据库连接已存在,不进行数据源创建"); return; } Properties prop = new Properties(); prop.put("initialSize", initialSize); prop.put("maxActive", maxActive); prop.put("minIdle", minIdle); prop.put("maxWait", maxWait); prop.put("poolPreparedStatements", poolPreparedStatements); prop.put("maxPoolPreparedStatementPerConnectionSize", maxPoolPreparedStatementPerConnectionSize); prop.put("validationQuery", validationQuery); prop.put("validationQueryTimeout", validationQueryTimeout); prop.put("testOnBorrow", testOnBorrow); prop.put("testOnReturn", testOnReturn); prop.put("testWhileIdle", testWhileIdle); prop.put("timeBetweenEvictionRunsMillis", timeBetweenEvictionRunsMillis); prop.put("minEvictableIdleTimeMillis", minEvictableIdleTimeMillis); prop.put("timeBetweenConnectErrorMillis", timeBetweenConnectErrorMillis); prop.put("maxEvictableIdleTimeMillis", maxEvictableIdleTimeMillis); prop.put("sharePreparedStatements", sharePreparedStatements); prop.put("useGlobalDataSourceStat", useGlobalDataSourceStat); prop.put("failFast", failFast); //创建数据源 DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); dataSource.setProxyFilters(defaultDataSource.getProxyFilters()); dataSource.setName(dataSourceConfig.getDataSourceKey()); dataSource.setUrl(dataSourceConfig.getUrl()); dataSource.setUsername(dataSourceConfig.getUserName()); dataSource.setPassword(dataSourceConfig.getPassWord()); dataSource.setDriverClassName(dataSourceConfig.getDriver()); //注入bean对象 SpringHelper.registerSingletonBean(dataSourceKey, dataSource); myDataSource.add(dataSourceKey); log.info("数据源创建成功:【key:{}】", dataSourceKey); } /** * 获取数据库连接对象 */ public Connection getDataSourceConnection(String dataSourceKey) { Connection connection = null; if (!myDataSource.contains(dataSourceKey)) { log.warn("当前数据源不存在,请创建数据源"); return connection; } try { DruidDataSource dataSource = SpringHelper.getBean(dataSourceKey); connection = dataSource.getConnection(); } catch (SQLException e) { log.error("获取数据库连接失败", e.getMessage()); } return connection; } /** * 获取数据库连接对象 */ public JdbcTemplate getJdbcTemplate(String dataSourceKey) { JdbcTemplate jdbcTemplate = null; if (!myDataSource.contains(dataSourceKey)) { log.warn("当前数据源不存在,请创建数据源"); return null; } DataSource dataSource = SpringHelper.getBean(dataSourceKey); jdbcTemplate = new JdbcTemplate(dataSource); return jdbcTemplate; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构