Springboot2.0多数据源实现方式:
- 静态配置方式实现
- 动态配置方式
- 注解方式实现
Springboot2.0多数据源使用大致分为两种:
- 分包方式使用
- 注解方式使用
在这里我们讲分包方式实现静态配置方式(Mysql数据库形式)
- 首先我们都知道,Spring一开始是以XML形式以及properties形式组成Spring容器的基本配置。
- Springboot则是将SpringXML以及properties的配置文件简化,但是在实现某些配置,则都是需要用到原配置中的类
在这里我们首先来看原XML配置文件,才能理解多数据源需要哪些
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 配置数据源 -->
<context:property-placeholder location="classpath:properties/db.properties" />
<!-- 加载日志配置文件 -->
<context:property-placeholder location="classpath:properties/log4j.properties" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${driver}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${dbName}"></property>
<property name="password" value="${dbPassword}"></property>
<!-- 每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
<!-- 初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="5" />
<!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60" />
<!-- 连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="10" />
<!-- 连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="5" />
<!-- JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
<property name="maxStatements" value="100" />
<!-- maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection" value="3" />
<!-- 定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个显著提高测试速度。注意:
测试的表必须在初始数据源的时候就存在。Default: null -->
<property name="preferredTestQuery" value="select 1" />
<!-- 定义在从数据库获取新连接失败后重复尝试的次数。Default: 30-->
<property name="acquireRetryAttempts" value="3" />
<!-- 两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay" value="1000" />
<!-- 当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出
SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->
<property name="checkoutTimeout" value="30000" />
</bean>
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 扫描mybatis核心配置文件 -->
<property name="configLocation" value="classpath:spring/mybatis.xml"/>
<!-- 扫描java bean,自动使用别名 -->
<property name="typeAliasesPackage" value="com.czlj.pojo"/>
<!-- 扫描 Mybatis 的SQL配置文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!-- 扫描Dao接口包 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.czlj.dao"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
在这里我们能看到mybatis数据源的实现大概需要下列bean:
- DataSource
- SqlSessionFactory
- MapperScannerConfigurer
- TransactionManager
这时候我们开始配置Springboot数据源
##datasource01
ext01.spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf8
ext01.spring.datasource.username=root
ext01.spring.datasource.password=123456
ext01.spring.datasource.driver-class-name=com.mysql.jdbc.Driver
##datasource02
ext02.spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf8
ext02.spring.datasource.username=root
ext02.spring.datasource.password=123456
ext02.spring.datasource.driver-class-name=com.mysql.jdbc.Driver
这里我们配置了两个DataSource的基本参数。这里我们需要注意在每个datasource后面的jdbc-url,username,username,driver-class-name都是不能改变的,也需要注意不能使用原来方式配置 例:
##Springboot2.0方式原配置jdbc
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=
使用原来方式配置的话,Springboot会默认使用一个数据源,这样就不能实现多数据源了,而且使用原方式的话,这里需要注意,原方式的url与自定义方式的jdbc-url是不一样的,如果使用原方式的url进行多数据源配置会报找不到url的driver配置信息,在Springboot1.5时driver-class-name也是不一样的,Springboot1.5方式是driverclassname配置。
然后我们开始配置数据源的bean
需要讲解以下注解:
* @Bean注解 //将此方法当作bean的形式注入Spring
* @ConfigurationProperties //此注解为找application.properties配置文件中前缀为ext01.spring.datasource的配置信息
* @Primary //此注解意思为当寻找Datasource时将此bean为第一候选,也就是默认在没指定使用哪个
* Datasource时,将此bean设置为主使用,在这里使用此注解是因为Springboot2.0及1.5需要配置一个主从才能执行多数据源,不然就会报错
* @Qualifier //此数据在有多个匹配的bean时,指定具体使用哪个bean,不然在多个具备使用条件的bean的情况下会,报异常
下列类配置为主配置:
package com.nyhs.datasource;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//此注解将此类以配置的形式注入到Springboot中
@Configuration
//此注解原意为扫包
//在这里使用此注解相当于配置XML中的MapperScannerConfigurer
//需要注意basePackages,这里才是根本决定分包,分数据源
@MapperScan(basePackages = "com.nyhs.test01.dao", sqlSessionFactoryRef = "Test01SqlSessionFactory")
public class DataSource01 {
/**
* datasource 配置
* @Bean注解 //将此方法当作bean的形式注入Spring
* @ConfigurationProperties //此注解为找application.properties配置文件中前缀为
* ext01.spring.datasource的配置信息
* @Primary //此注解意思为当寻找Datasource时将此bean为第一候选,也就是默认在没指定使用哪个
* Datasource时,将此bean设置为主使用,在这里使用此注解是因为Springboot2.0及1.5需要配置一
* 个主从才能执行多数据源,不然就会报错
* @return
*/
@Bean(name = "Test01DataSource")
@ConfigurationProperties(prefix = "ext01.spring.datasource")
@Primary
public DataSource getDataSource() {
return DataSourceBuilder.create().build();
}
/**
* sqlsessionfactory 配置
*
* @return
*/
@Bean(name = "Test01SqlSessionFactory")
@Primary
public SqlSessionFactory getSqlSessionFactory(@Qualifier("Test01DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
/**
* DataSourceTransactionManager 事务管理器配置
* @return
*/
@Bean(name = "Test01DataSourceTransactionManager")
@Primary
public DataSourceTransactionManager getDataSourceTransactionManager(
@Qualifier("Test01DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
在这里我们需要注意每一个Datasouce都有一个专门的事务管理器,也就是说,当有多个数据源时,也有多个数据事务管理器
从配置:
package com.nyhs.datasource;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
//需要注意这里的basePackages路径不一样,这样才能进行分包处理多个数据源
@MapperScan(basePackages = "com.nyhs.test02.dao", sqlSessionFactoryRef = "Test02SqlSessionFactory")
public class DataSource02 {
@Bean(name = "Test02DataSource")
@ConfigurationProperties(prefix = "ext02.spring.datasource")
public DataSource getDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "Test02SqlSessionFactory")
public SqlSessionFactory getSqlSessionFactory(@Qualifier("Test02DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "Test02DataSourceTransactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager(
@Qualifier("Test02DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
主配置进行数据处理路径为:com.nyhs.test01.dao
从配置进行数据处理路径为: com.nyhs.test02.dao
这里我们需要注意使用事务时的问题
@Transactional//如果不指定数据源的情况下,会无法进行对应的事务管理。所以我们需要指定事务管理器的使用。参数值为对应事务管理器的beanID
package com.nyhs.test01.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.nyhs.test01.dao.Test01UserDao;
import com.nyhs.test01.service.Test01UserService;
/**
* TEST01数据源的业务层
* @author 412958751
*
*/
@Service
public class Test01UserServiceImpl implements Test01UserService {
@Autowired
private Test01UserDao test01UserDao;
@Override
@Transactional(transactionManager="Test01DataSourceTransactionManager")
public int insertUser(String name, int age) {
return test01UserDao.insertUser(name, age);
}
}
这样我们就配置好了事务以及多数据源的使用。动态数据源后续更新。。。。