• SpringBoot+MyBatis配置多数据源


    SpringBoot 可以支持多数据源,这是一个非常值得学习的功能,但是从现在主流的微服务的架构模式中,每个应用都具有唯一且准确的功能,多数据源的需求很难用到,考虑到实际情况远远比理论复杂的多,这里还是深入学习一个Mybatis的多数据源的配置,代码偏向于实战,提供Git地址,以供下载测试.https://gitee.com/zhoutao825638/Sprinboot_mybatis_ds.git

    数据库脚本

    我们首先声明记录一下数据库脚本创建了两个数据库,test1和test2 ,并且分别在不同的数据库中创建了student和lesson表.

    CREATE DATABASE `test1` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;  ;
    USE `test1`;
    CREATE TABLE `student`(
      `id` VARCHAR(12) PRIMARY KEY,
      `name` VARCHAR(36) NOT NULL ,
      `age` INTEGER  DEFAULT 0
    );
    
    -- 插入数据
    INSERT INTO test1.student (id, name, age) VALUES ('1', '张梦为', 1);
    INSERT INTO test1.student (id, name, age) VALUES ('2', '上官婉儿', 2);
    INSERT INTO test1.student (id, name, age) VALUES ('3', '唐因', 2);
    
    
    CREATE DATABASE `test2` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;  ;
    USE `test2`;
    CREATE TABLE `lesson`(
      `id` VARCHAR(12) PRIMARY KEY,
      `name` VARCHAR(36) NOT NULL ,
      `credit` FLOAT  DEFAULT 0,
      `teacher` VARCHAR(36) DEFAULT 0
    );
    -- 插入数据
    INSERT INTO test2.lesson (id, name, credit, teacher) VALUES ('1', '大学物理', 5, '张思瑞');
    INSERT INTO test2.lesson (id, name, credit, teacher) VALUES ('2', '高等数学', 5, '李佛');
    

    创建Spring 应用

    使用IDEA 可以非常简单的创建一个应用,这里我使用了Gradle构建项目,其依赖如下:

    lombok 是一个不错的插件,推荐使用,如果不使用lombok的话,下面的代码需要添加set/get方法

        compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
        compile group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '1.3.2'
        compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.47'
        compileOnly('org.projectlombok:lombok')
        testCompile('org.springframework.boot:spring-boot-starter-test')
        compile('org.springframework.boot:spring-boot-starter-web')
    

    配置完成之后,在应用的入口中,我们需要修改一下

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    

    这是因为SpringBoot会自动根据依赖来自动配置,但是我们的数据源配置被我们自己自定义配置了,此时SpringBoot 无法完成自动化配置,因此就会报错,所以此处我们需要排除DataSourceAutoConfiguration的自动配置.

    配置数据源

    这里我们配置来两个数据源 一个是test1,一个test2,修改application.properties文件

    
    -- 数据源 Frist
    spring.datasource.first.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
    spring.datasource.first.username=root
    spring.datasource.first.password=
    spring.datasource.first.driverClassName=com.mysql.jdbc.Driver
    
    -- 数据源 Second
    spring.datasource.second.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
    spring.datasource.second.username=root
    spring.datasource.second.password=
    spring.datasource.second.driverClassName=com.mysql.jdbc.Driver
    
    

    创建配置文件封装类

    为了更合理的使用配置文件,这里我们没有使用之前的@Value,而是自己封装一个PropertiesConfig类对象.如下

    @Data注解需要添加Lombok插件并开启,需要不想安装的话,请为下面的四个成员变量提供set/get方法即可

    数据源First配置文件封装

    package com.zhoutao123.springboot.muldatasources.config;
    
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    @Data
    @Component
    @ConfigurationProperties(prefix = "spring.datasource.first")
    public class FirstDataBaseProperties {
      String url;
      String username;
      String password;
      String driverClassName;
    }
    
    

    数据源Second配置文件封装

    package com.zhoutao123.springboot.muldatasources.config;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    
    @Data
    @Component
    @ConfigurationProperties(prefix = "spring.datasource.second")
    public class SecondDataBaseProperties {
      String url;
      String username;
      String password;
      String driverClassName;
    }
    
    

    完成数据源配置

    这里需要完成DataSource/SqlSessionFactory/SessionTemp等对象的注入,需要注意的是,不管配置多少个数据源,其中的一个数据源配置的Bean必须使用@Primary完成注解.

    下面是两个数据源的配置,其中First使用了@Primary注解

    MapperScan注解的basePackages 表示了其目录下的Mapper使用文件使用该数据源,如FirstDataSource中表示com.zhoutao123.springboot.muldatasources.mapper.first下的Maper文件将使用FirstDataSource.

    package com.zhoutao123.springboot.muldatasources.config;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Autowired;
    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;
    
    import javax.sql.DataSource;
    
    @Configuration
    @MapperScan(basePackages = "com.zhoutao123.springboot.muldatasources.mapper.first",sqlSessionTemplateRef ="firstSqlSessionTemplate")
    public class FirstDataSourceConfig {
    
      @Autowired
      private FirstDataBaseProperties prop;
    
      //    创建数据源
      @Bean(name = "firstDS")
      @ConfigurationProperties(prefix = "spring.datasource.first")
      @Primary
      public DataSource getFirstDataSource() {
        DataSource build =  DataSourceBuilder.create()
                .driverClassName(prop.driverClassName)
                .url(prop.url)
                .username(prop.username)
                .password(prop.password)
                .build();
        return build;
        }
    
    
      // 创建SessionFactory
      @Bean(name = "firstSqlSessionFactory")
      @Primary
      public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDS") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean  bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
      }
    
      // 创建事务管理器
    
      @Bean("firstTransactionManger")
      @Primary
      public DataSourceTransactionManager firstTransactionManger(@Qualifier("firstDS") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
      }
    
      // 创建SqlSessionTemplate
    
      @Bean(name = "firstSqlSessionTemplate")
      @Primary
      public SqlSessionTemplate firstSqlSessionTemplate(@Qualifier("firstSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
      }
    
    
      private Class getType(String type) {
        try {
          return Class.forName(type);
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
        return null;
      }
    
    
    }
    
    

    以及第二个数据源的配置

    package com.zhoutao123.springboot.muldatasources.config;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Autowired;
    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;
    
    import javax.sql.DataSource;
    
    @Configuration
    @MapperScan(basePackages = "com.zhoutao123.springboot.muldatasources.mapper.second",sqlSessionTemplateRef ="secondSqlSessionTemplate")
    public class SecondDataSourceConfig {
    
      @Autowired
      private SecondDataBaseProperties prop;
    
    //    创建数据源
      @Bean(name = "secondDS")
      @ConfigurationProperties(prefix = "spring.datasource.second")
      public DataSource getSecondDataSource() {
        DataSource build =  DataSourceBuilder.create()
                .driverClassName(prop.driverClassName)
                .url(prop.url)
                .username(prop.username)
                .password(prop.password)
                .build();
        return build;
      }
    
    
      // 创建SessionFactory
      @Bean(name = "secondSqlSessionFactory")
      public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDS") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean  bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
      }
    
      // 创建事务管理器
    
      @Bean("secondTransactionManger")
      public DataSourceTransactionManager secondTransactionManger(@Qualifier("secondDS") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
      }
    
      // 创建SqlSessionTemplate
    
      @Bean(name = "secondSqlSessionTemplate")
      public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
      }
    
      private Class getType(String type) {
        try {
          return Class.forName(type);
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
        return null;
      }
    }
    

    实现Mapper

    根据数据源配置的MappScan目录来创建测试Mapper,代码如下,注意包名,放在正确的位置上.

    返回模型

    这里写了两个数据库映射模型,用于接受数据库数据,比较简单.

    package com.zhoutao123.springboot.muldatasources.dao;
    
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    @Data
    @Accessors(chain = true)
    public class Lesson {
    
        private String id;
    
        private String name;
    
        private String teacher;
    
        private  float credit;
    }
    
    
    package com.zhoutao123.springboot.muldatasources.dao;
    
    
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    @Data
    @Accessors(chain = true)
    public class Student {
    
        private String id;
    
        private  String name;
    
        private String age;
    }
    
    

    创建映射Mapper

    package com.zhoutao123.springboot.muldatasources.mapper.first;
    
    import com.zhoutao123.springboot.muldatasources.dao.Student;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    
    @Mapper
    public interface StudentMapper {
    
    	// 查询全部的学生
        @Select("SELECT * FROM student;")
        List<Student> getAllStudent();
    
    }
    
    
    package com.zhoutao123.springboot.muldatasources.mapper.second;
    
    import com.zhoutao123.springboot.muldatasources.dao.Lesson;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    
    @Mapper
    public interface LessonMapper {
    
    	//	 查询全部的课程
        @Select("SELECT * FROM lesson;")
        List<Lesson> getAllLesson();
    
    }
    
    

    测试接口

    这里为了方便,写了一个测试接口和Application放在一起的,同时考虑到这边学习的主要目标是多数据源的配置,就没有Service层,Controller直接调用Mapper,真实项目不要这么写哈.

    package com.zhoutao123.springboot.muldatasources;
    
    import com.zhoutao123.springboot.muldatasources.config.FirstDataSourceConfig;
    import com.zhoutao123.springboot.muldatasources.config.SecondDataSourceConfig;
    import com.zhoutao123.springboot.muldatasources.dao.Lesson;
    import com.zhoutao123.springboot.muldatasources.dao.Student;
    import com.zhoutao123.springboot.muldatasources.mapper.first.StudentMapper;
    import com.zhoutao123.springboot.muldatasources.mapper.second.LessonMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.security.PublicKey;
    import java.util.List;
    
    // 排除数据源的自动配置
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    @RestController
    public class MuldatasourcesApplication {
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Autowired
        private LessonMapper lessonMapper;
    
        public static void main(String[] args) {
            SpringApplication.run(MuldatasourcesApplication.class, args);
        }
    
    
        @GetMapping("/student")
        public List<Student> studentList(){
            return studentMapper.getAllStudent();
        }
    
        @GetMapping("/lesson")
        public List<Lesson> lessonList(){
            return lessonMapper.getAllLesson();
        }
    }
    
    

    测试结果

    可以看到不同的数据库的数据被查询出来了,实现了多数据源的切换,此处的效果和数据库的读写分离有类似的效果,可以参考分析,学习.

  • 相关阅读:
    jQuery插件开发模式
    优化布局
    jquery easyui 选项卡
    easy ui 点击行展开与折叠
    考拉海购技术支持的前世今生
    跑的好好的 Java 进程,怎么突然就瘫痪了
    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架
    微服务治理实践:如何对单点异常进行自动摘除
    盘点阿里巴巴 15 款开发者工具
    千万创业者的自白:踩过坑才明白这些真相!
  • 原文地址:https://www.cnblogs.com/zhoutao825638/p/10382261.html
Copyright © 2020-2023  润新知