美文网首页学习笔记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