SpringBoot 配置多个数据库有什么用,相信大家看到这篇文章时可能你已经有用到的场景了,那我就不多说了,直接上代码!
以下我实现一个数据转移的问题(不要说使用native直接导出数据,然后在导入进去这种问题,要是字段不一样你怎么办???) 同时连接两个库
首先创建一个有数据的数据库
CREATE DATABASE second
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`gender` char(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', '张三', '16', '男');
INSERT INTO `tb_user` VALUES ('2', '李四', '18', '女');
INSERT INTO `tb_user` VALUES ('3', '小七', '22', '男');
INSERT INTO `tb_user` VALUES ('4', '王鑫', '24', '女');
在创建一个没有数据的数据库
CREATE DATABASE master
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`gender` char(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
需要的数据库和表我都提供给大家了 大家直接复制运行就行了
1、创建一个SpringBoot项目
添加pom.xml依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
这里我使用的是druid连接池和tk.mybatis的启动器
2、配置application.properties 文件
# master 数据源配置
master.datasource.url=jdbc:mysql://localhost:3306/master?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
master.datasource.username=root
master.datasource.password=020822
master.datasource.driverClassName=com.mysql.cj.jdbc.Driver
# second 数据源配置
second.datasource.url=jdbc:mysql://localhost:3306/second?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
second.datasource.username=root
second.datasource.password=020822
second.datasource.driverClassName=com.mysql.cj.jdbc.Driver
这里我使用mysql8.0(因为8.0比5.7的速度快了两倍 哈哈哈哈~~~~~~~~)
3、创建领域模型
package club.lw666.datasource.domain;
/**
* @program: datasource-demo
* @description: tb_user 模型
* @author: Slayer
* @create: 2019-08-12 18:51
**/
public class TbUser {
private Integer id;
private String name;
private Integer age;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "TbUser{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
4、配置数据源
package club.lw666.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import tk.mybatis.spring.annotation.MapperScan;
import javax.sql.DataSource;
/**
* @program: datasource-demo
* @description: 配置Second数据源的信息
* @author: Slayer
* @create: 2019-08-12 18:40
**/
@Configuration
@MapperScan(basePackages = SecondDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig {
// 这里一定要指定精准 否则后果不堪设想
static final String PACKAGE = "club.lw666.datasource.mapper.second";
static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml";
@Bean
@ConfigurationProperties(prefix = "second.datasource")
public DataSource secondDataSource() {
return new DruidDataSource();
}
/*注入事务*/
@Bean(name = "secondTransactionManager")
public DataSourceTransactionManager secondTransactionManager() {
return new DataSourceTransactionManager(secondDataSource());
}
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource secondDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(secondDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(SecondDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}
以上是有数据的配置
package club.lw666.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import tk.mybatis.spring.annotation.MapperScan;
import javax.sql.DataSource;
/**
* @program: datasource-demo
* @description: 配置Master数据源的信息
* @author: Slayer
* @create: 2019-08-12 18:40
**/
@Configuration
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
// 这里一定要指定精准 否则后果不堪设想
static final String PACKAGE = "club.lw666.datasource.mapper.master";
static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
@Bean
@Primary
@ConfigurationProperties(prefix = "master.datasource")
public DataSource masterDataSource() {
return new DruidDataSource();
}
/*注入事务*/
@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));
return sessionFactory.getObject();
}
}
这个是没有数据配置
注意点:通过以上两个配置,不知道大家有没有发现有什么不同的地方。那么我给大家讲解一下吧。
相信大家都看到一个这样子的注解 @Primary,这个注解表示 Bean 如果在多个同类 Bean 候选时,该 Bean 优先被考虑。多数据源配置的时候注意,必须要有一个主数据源,用 @Primary 标志该 Bean,而且只能有一个这样子的注解,否则Spring会报错找到多个相同的Bean
还有就是我配置扫描的Mapper类和Mapper.xml 在多数据源的情况下 一定一定要分解开 否则报错!!!
5、创建Mapper
因为我这里使用tk.mybatis 简化了mybatis的开发 所以我需要创建一个通用的Mapper 并且不能被Spring扫描到
package tk.mybatis;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* @program: datasource-demo
* @description: 通用的Mapper 不能被Spring扫描 否则会报错
* @author: Slayer
* @create: 2019-08-12 18:53
**/
public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
}
接下来创建两个不同数据库的mapper
masterTbUserMapper
package club.lw666.datasource.mapper.master;
import club.lw666.datasource.domain.TbUser;
import tk.mybatis.MyMapper;
/**
* @program: datasource-demo
* @description:
* @author: Slayer
* @create: 2019-08-12 18:52
**/
public interface MasterTbUserMapper extends MyMapper<TbUser> {
}
SecondTbUserMapper
package club.lw666.datasource.mapper.second;
import club.lw666.datasource.domain.TbUser;
import tk.mybatis.MyMapper;
/**
* @program: datasource-demo
* @description:
* @author: Slayer
* @create: 2019-08-12 18:53
**/
public interface SecondTbUserMapper extends MyMapper<TbUser> {
}
注意点:这里我继承了刚刚自己写的通用Mapper,这有就相当于了基本的CURD操作,还有就是这两个类不要写在同一个包下面,毕竟多数据源嘛!
然后就是mapper.xml
首先在resources目录下创建一个mapper目录 然后在mapper创建两个不同的数据源文件夹存放mapper.xml
首先master目录创建一个MasterTbUserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="club.lw666.datasource.mapper.master.MasterTbUserMapper">
</mapper>
second目录创建一个SecondTbUserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="club.lw666.datasource.mapper.second.SecondTbUserMapper">
</mapper>
完成以上的配置 就可以进行测试了
package club.lw666.datasource;
import club.lw666.datasource.domain.TbUser;
import club.lw666.datasource.mapper.master.MasterTbUserMapper;
import club.lw666.datasource.mapper.second.SecondTbUserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DatasourceDemoApplication.class)
public class DatasourceDemoApplicationTests {
@Autowired
private MasterTbUserMapper masterTbUserMapper;
@Autowired
private SecondTbUserMapper secondTbUserMapper;
@Test
public void contextLoads() {
List<TbUser> tbUsers = secondTbUserMapper.selectAll();
tbUsers.forEach(tbUser -> {
System.out.println(tbUser);
masterTbUserMapper.insert(tbUser);
});
}
}
这里我把有数据的数据库导入到了没有数据的数据库中了,里面还可以进行数据过滤 这里我就不做了
然后我这里打印了一下 咱们看一下控制台
这里显示成功了 但为了万无一失 咱们在看一下数据库
master数据库的数据来了 这样子就完美成功了!!!
要是途中大家遇到了什么报错形象 对比一下我的结构目录 看是不是你写错了
如果大家还有什么问题,欢迎大家在下面留言,我看到了会及时处理!
网友评论