spring boot项目配置阿里数据源兼容多种数据库

一、博客背景

最近在做的一个项目需要用到阿里数据源和四种数据库,分别为mysql,oracle,db2,sql server数据库,项目中的阿里数据源需要兼容4套数据库,且只写一个总的配置文件,而不是mysql对应一套,oracle对应一套

二、代码展示

application.properties

#datasource数据源的配置信息
spring.profiles.active=datasource
##数据库配置
#数据库类型(1.oracle,2.sqlServer,3.mysql,4.db2)
java.db.database-type=3
database.ip=192.169.1.26
database.port=3306
database.name=javadb04
spring.datasource.druid.username=root
spring.datasource.druid.password=ENC(5M5nrpgKIQBkqEcldhbK6A==)

application-datasource.properties

#连接池配置
#数据库连接url
spring.datasource.druid.url=jdbc:mysql://:${database.ip}:${database.port}:${database.name}
#初始化连接大小
spring.datasource.druid.initial-size=5
#最大连接数
spring.datasource.druid.max-active=200
#最小空闲连接数
spring.datasource.druid.min-idle=50
#获取连接最大等待时间(毫秒)
spring.datasource.druid.max-wait=60000
#是否开启PSCache,mysql5.5及以上版本支持
spring.datasource.druid.pool-prepared-statements=true
#指定每个连接上PSCache的大小,开启PSCache时,此配置必须大于0
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#检测连接是否有效超时时间(毫秒)
spring.datasource.druid.validation-query-timeout=60000
#申请连接时执行validationQuery检测连接是否有效
spring.datasource.druid.test-on-borrow=false
#归还连接时执行validationQuery检测连接是否有效
spring.datasource.druid.test-on-return=false
#申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
spring.datasource.druid.test-while-idle=true
#Destroy线程会检测连接的间隔时间,testWhileIdle的判断依据
spring.datasource.druid.time-between-eviction-runs-millis=60000
#Destory线程中如果检测到当前连接的最后活跃时间和当前时间的差值大于,minEvictableIdleTimeMillis,则关闭当前连接
spring.datasource.druid.min-evictable-idle-time-millis=100000
#启用ConfigFilter
spring.datasource.druid.filter.config.enabled=true

java配置文件

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.montnets.db.enums.DataBaseEnum;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 数据源配置信息
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2020-12-12 16:24
 */
@Configuration
public class DataSourceConfig {

    private final MyDataSourceConfig myConfig;

    public DataSourceConfig(MyDataSourceConfig myConfig) {
        this.myConfig = myConfig;
    }

    @Bean
    public DruidDataSource dataSource(@Value("${java.db.database-type:3}")
                                          int dataBaseType) {
        DruidDataSource build = DataSourceBuilder.create().type(DruidDataSource.class).build();
        Properties properties = new Properties();
        Map<String, String> datasource = myConfig.getDatasource();
        DataBaseEnum dataBase = DataBaseEnum.getDataBase(dataBaseType);
        datasource.put("druid.driver-class-name", dataBase.getDriverClassName());
        datasource.put("druid.validation-query", dataBase.getValidationQuery());
        if (dataBase != DataBaseEnum.ORACLE) {
            datasource.put("druid.url", StrUtil.format(dataBase.getUrl(), myConfig.getIp(),
                    myConfig.getPort(), myConfig.getName()));
        }
        datasource.forEach(properties::put);
        build.configFromPropety(properties);
        return build;
    }


}


@Configuration
@ConfigurationProperties(prefix="spring")
class MyDataSourceConfig {
    private Map<String, String> datasource = new HashMap<>();
    @Value("${database.ip}")
    private String ip;
    @Value("${database.port}")
    private String port;
    @Value("${database.name}")
    private String name;

    public String getIp() {
        return ip;
    }

    public String getPort() {
        return port;
    }

    public String getName() {
        return name;
    }

    public Map<String, String> getDatasource() {
        return datasource;
    }
}

数据库枚举类型

/**
 * 数据库类型、
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2020-11-05 13:46
 */
public enum  DataBaseEnum {
    /**
     * ORACLE数据库
     */
    ORACLE(1, "oracle.jdbc.OracleDriver", "SELECT 1 FROM DUAL", "jdbc:oracle:thin:@{}:{}:{}"),
    /**
     * sqlServer数据库
     */
    SQL_SERVER(2, "com.microsoft.sqlserver.jdbc.SQLServerDriver", "SELECT 1", "jdbc:sqlserver://{}:{};DatabaseName={}"),
    /**
     * mysql数据库
     */
    MYSQL(3, "com.mysql.cj.jdbc.Driver", "SELECT 1 FROM DUAL", "jdbc:mysql://{}:{}/{}?serverTimezone=GMT%2B8&useUnicode=true&charaterEncoding=utf-8&useSSL=false"),
    /**
     * DB2数据库
     */
    DB2(4, "com.ibm.db2.jcc.DB2Driver", "SELECT 1 FROM SYSIBM.SYSDUMMY1", "jdbc:db2://{}:{}/{}");

    DataBaseEnum(int type, String driverClassName, String validationQuery, String url) {
        this.type = type;
        this.driverClassName = driverClassName;
        this.validationQuery = validationQuery;
        this.url = url;
    }

    public static DataBaseEnum getDataBase(int type) {
        for (DataBaseEnum dataBase : values()) {
            if (type == dataBase.type) {
                return dataBase;
            }
        }
        return MYSQL;
    }

    /**
     * 数据库类型
     */
    private int type;
    /**
     * 驱动类
     */
    private String driverClassName;
    /**
     * 校验连接sql
     */
    private String validationQuery;
    /**
     * 连接url
     */
    private String url;

    public int getType() {
        return type;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public String getValidationQuery() {
        return validationQuery;
    }

    public String getUrl() {
        return url;
    }
}

三、代码讲解

1.配置文件

首先我们来看配置文件。application.properties配置文件中配置了数据库连接的基本信息,和需要加载的另一个配置文件。application-datasource.properties则是配置了数据源相关的一些信息

代码之所以能够适配四套不同的数据库,主要还是在java代码层面上实现,java代码实现相关逻辑后,我们换数据库时,需要修改的仅仅是application.properties配置文件中配置的数据库连接的基本信息,如数据库类型,ip,用户名,端口等。

2.java代码

下面我们来看下java代码逻辑的实现。首先可以看到有一个数据库相关的枚举类,在这个枚举类中定义了四种数据库,我们自定义的数据库类型,数据库的驱动类的名字,检验是否连接的sql,和数据库分别对应各自的url的编写格式。

我们在看下配置类,需要注意的是DataSourceConfig和MyDataSourceConfig两个类是写在一个文件里,之所以写在同一个文件下,是因为MyDataSourceConfig类加载的配置文件仅仅是需要给DataSourceConfig使用,一开始是想将MyDataSourceConfig定义成传统意义内部类,

但是由于要spring的相关直接,直接将MyDataSourceConfig定义在DataSourceConfig中,在使用注解的时候会报错,所以直接将两个类写在同一个文件下,但是需要注意的是,仅仅只有一个类的修饰符是public的,想更多了解这种写法的同学,可以自行上网搜索。

MyDataSourceConfig:

MyDataSourceConfig类只要是拿来获取application-datasource.properties数据源相关信息,并将其封装到名字取为datasource的map中,以供DataSourceConfig使用,如何将配置文件的配置加载map中,查看我的另一篇博客:https://blog.csdn.net/bird_tp/article/details/111216892

DataSourceConfig:

在DataSourceConfig类中主要干的事就是通过基本配置文件中获取到的数据库类型,从而从枚举类中获取对应的驱动名,检验是否连接的sql,url的格式设置到properties中去,大家可能会疑问,平常我们设置数据源信息的时候不是把信息设置到自己定义的properties中去的,而是设置到DruidDataSource中的

,为啥在代码里就是设置到自定义的properties中呢,那是因为我们最后调用了configFromPropety方法,下面粘贴下该方法的一点源码,我们就可以明白原因了

从源码里可以看到其实,调用该方法还是设置到DruidDataSource中去了,之所以调用该方法,是为了省略判断,不然我们自己平常自己设置到DruidDataSource的时候,还需要一个一个的对相关key和vaule判断。

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值