美文网首页学习笔记Java 杂谈
Spirngboot配置多个数据库

Spirngboot配置多个数据库

作者: 这里是廖同学 | 来源:发表于2019-08-12 20:06 被阅读14次

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数据库的数据来了 这样子就完美成功了!!!


要是途中大家遇到了什么报错形象 对比一下我的结构目录 看是不是你写错了

如果大家还有什么问题,欢迎大家在下面留言,我看到了会及时处理!

相关文章

网友评论

    本文标题:Spirngboot配置多个数据库

    本文链接:https://www.haomeiwen.com/subject/bmfpjctx.html