为了更方便的切换开发环境或读写分离操作,在应用中需要配置多个数据源,根据环境动态的切换数据库配置地址。
配置jdbc.properties文件
这里用到了三个文件:
jdbc_dev.properties
jdbc_product.properties
jdbc_test.properties
分别对就开发环境、生产环境、测试环境的数据库链接信息。
大体内容如下:
#开发环境环境标记dev/product/test
#本地开始环境数据库链接地址
dev_driver=com.mysql.cj.jdbc.Driver
dev_url=jdbc:mysql://127.0.0.1:3306/learn?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
dev_jdbc.username=root
dev_jdbc.password=111111
#初始化连接大小
dev_initialSize=0
#连接池最大数量
dev_maxActive=20
#连接池最大空闲
dev_maxIdle=20
#连接池最小空闲
dev_minIdle=1
#获取连接最大等待时间
dev_maxWait=60000
applicationContext.xml文件配置
首先将所有数据源配置文件引入
<context:property-placeholder location="classpath:jdbc/jdbc_product.properties,classpath:jdbc/jdbc_test.properties,classpath:jdbc/jdbc_dev.properties" />
然后对应到多个dataSource中去,代码如下:
<!-- 开发环境数据源配置 -->
<bean id="dataSourceDev" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dev_driver}" />
<property name="url" value="${dev_url}" />
<property name="username" value="${dev_jdbc.username}" />
<property name="password" value="${dev_jdbc.password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${dev_initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxTotal" value="${dev_maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${dev_maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${dev_minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWaitMillis" value="${dev_maxWait}"></property>
</bean>
<!-- 正式环境数据源配置 -->
<bean id="dataSourceProduct" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${product_driver}" />
<property name="url" value="${product_url}" />
<property name="username" value="${product_jdbc.username}" />
<property name="password" value="${product_jdbc.password}" />
<property name="initialSize" value="${product_initialSize}"></property>
<property name="maxTotal" value="${product_maxActive}"></property>
<property name="maxIdle" value="${product_maxIdle}"></property>
<property name="minIdle" value="${product_minIdle}"></property>
<property name="maxWaitMillis" value="${product_maxWait}"></property>
</bean>
<!-- 测试环境数据源配置 -->
<bean id="dataSourceTest" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${test_driver}" />
<property name="url" value="${test_url}" />
<property name="username" value="${test_jdbc.username}" />
<property name="password" value="${test_jdbc.password}" />
<property name="initialSize" value="${test_initialSize}"></property>
<property name="maxTotal" value="${test_maxActive}"></property>
<property name="maxIdle" value="${test_maxIdle}"></property>
<property name="minIdle" value="${test_minIdle}"></property>
<property name="maxWaitMillis" value="${test_maxWait}"></property>
</bean>
<!-- 多数据源配置信息
这里引入的MultipleDataSource类为自定义类
-->
<bean id="multipleDataSource" class="com.springmvc.common.config.datasource.MultipleDataSource">
<property name="defaultTargetDataSource" ref="dataSourceDev" />
<property name="targetDataSources">
<map>
<entry key="dataSourceDev" value-ref="dataSourceDev" />
<entry key="dataSourceProduct" value-ref="dataSourceProduct" />
<entry key="dataSourceTest" value-ref="dataSourceTest" />
</map>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="multipleDataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mappings/**/*.xml"></property>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
</bean>
定义MultipleDataSource类
在类中需要继承AbstractRoutingDataSource类,重写determineCurrentLookupKey方法,代码如下:
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();
public static void setDataSourceKey(String dataSource){
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
在Service动态切换数据源地址
代码如下:
@Service
public class CourseService {
@Autowired
protected CourseDao courseDao;
/**
* 查询列表数据
*
* @param entity
* @return
*/
public List<Course> findList(Course entity) {
//动态切换数据源地址 MultipleDataSource.setDataSourceKey("dataSourceTest");
return courseDao.findList();
}
}