Springboot多数据源配置
⽬前,业界流⾏的数据操作框架是 Mybatis,那 Druid 是什么呢? Druid 是 Java 的数据库连接池组件。Druid 能够提供强⼤的监控和扩展功能。⽐如可以监控 SQL ,在监控业务可以查询慢查询 SQL 列表等。Druid 核⼼主要包括三部分: 1. DruidDriver 代理 Driver,能够提供基于 Filter-Chain 模式的插件体系。 2. DruidDataSource ⾼效可管理的数据库连接池 3. SQLParser 当业务数据量达到了⼀定程
度,DBA 需要合理配置数据库资源。即配置主库的机器⾼配置,把核⼼⾼频的数据放在主库上;把次要的数据放在低配置的从库。开源节流嘛,把数据放在不同的数据库⾥,就需要通过不同的数据源进⾏操作数据。这⾥我们举个 springboot-mutil-datasource ⼯程案例: user
⽤户表在主库 master 上,地址表 city 在从库 slave上。
⼀、数据库准备
1、主库master
CREATE DATABASE master;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '⽤户编号',
`user_name` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '⽤户名称',
`description` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT =2CHARACTER SET= utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT user VALUES (1 ,'程序员','他有⼀个⼩⽹站 tom');
2、从库slave
CREATE DATABASE slave;
DROP TABLE IF EXISTS `city`;
CREATE TABLE `city`  (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '城市编号',
`province_id` int(10) UNSIGNED NOT NULL COMMENT '省份编号',
`city_name` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '城市名称',
`description` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT =2CHARACTER SET= utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT city VALUES (1 ,1,'北京市','tom的家在北京。');
⼆、⼯程代码配置详解
com.fig.ds 包下包含了多数据源的配置,同样可以有第三个数据源,按照前⼏个复制即可 resources/mapper 下⾯有两个模块,分别是 Mybatis 不同数据源需要扫描的 mapper xml ⽬录
2、l依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.carry.elk</groupId>
<artifactId>springboot-mutil-datasource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-mutil-datasource</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/><!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
&porting.outputEncoding>UTF-8</porting.outputEncoding>
<java.version>1.8</java.version>
<druid>1.0.31</druid>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId&batis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- Druid 数据连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、application.properties 配置两个数据源配置
## master 数据源配置
master.datasource.url=jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf8 master.datasource.username=root
master.datasource.password=123456
master.datasource.sql.jdbc.Driver
## slave 数据源配置
slave.datasource.url=jdbc:mysql://localhost:3306/slave?useUnicode=true&characterEncoding=utf8 slave.datasource.username=root
slave.datasource.password=123456
slave.datasource.sql.jdbc.Driver
#热部署
abled=true
4、主数据源MasterDataSourceConfig 配置
package com.fig.ds;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
batis.spring.SqlSessionFactoryBean;
batis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.annotation.Configuration;
import t.annotation.Primary;
import io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import com.alibaba.druid.pool.DruidDataSource;
@Configuration
// 扫描 Mapper 接⼝并容器管理
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDataSourceConfig {
// 精确到 master ⽬录,以便跟其他数据源隔离
static final String PACKAGE = "com.carry.springboot.dao.master";
static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
@Value("${master.datasource.url}")
private String url;
@Value("${master.datasource.username}")
private String user;
@Value("${master.datasource.password}")
private String password;
@Value("${master.datasource.driverClassName}")
private String driverClass;
@Bean(name = "masterDataSource")
@Primary
public DataSource masterDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager masterTransactionManager() {
return new DataSourceTransactionManager(masterDataSource());
}
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(masterDataSource);
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(MasterDataSourceConfig.MAPPER_LOCATION));
Object();
}
}
5、从数据源SlaveDataSourceConfig配置
package com.fig.ds;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
batis.spring.SqlSessionFactoryBean;
batis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.annotation.Configuration;
import io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import com.alibaba.druid.pool.DruidDataSource;
@Configuration
// 扫描 Mapper 接⼝并容器管理
@MapperScan(basePackages = SlaveDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "slaveSqlSessionFactory") public class SlaveDataSourceConfig {
// 精确到 slave ⽬录,以便跟其他数据源隔离
static final String PACKAGE = "com.carry.springboot.dao.slave";
static final String MAPPER_LOCATION = "classpath:mapper/slave/*.xml";
@Value("${slave.datasource.url}")
private String url;
@Value("${slave.datasource.username}")
private String user;
druid连接池配置详解
@Value("${slave.datasource.password}")
private String password;
@Value("${slave.datasource.driverClassName}")
private String driverClass;
@Bean(name = "slaveDataSource")
public DataSource slaveDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "slaveTransactionManager")
public DataSourceTransactionManager slaveTransactionManager() {
return new DataSourceTransactionManager(slaveDataSource());
}
@Bean(name = "slaveSqlSessionFactory")
public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource slaveDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(slaveDataSource);
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(SlaveDataSourceConfig.MAPPER_LOCATION));
Object();
}
}
6、业务层代码
package com.carry.springboot.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.carry.springboot.dao.master.UserDao;
import com.carry.springboot.dao.slave.CityDao;
import com.carry.springboot.domain.City;
import com.carry.springboot.domain.User;
import com.carry.springboot.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao; // 主数据源
@Autowired
private CityDao cityDao; // 从数据源
@Override
public User findByName(String userName) {
User user = userDao.findByName(userName);
City city = cityDao.findByName("北京市");
user.setCity(city);
return user;
}
}
三、测试