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

数据库脚本

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

  1. CREATE DATABASE `test1` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; ;
  2. USE `test1`;
  3. CREATE TABLE `student`(
  4. `id` VARCHAR(12) PRIMARY KEY,
  5. `name` VARCHAR(36) NOT NULL ,
  6. `age` INTEGER DEFAULT 0
  7. );
  8. -- 插入数据
  9. INSERT INTO test1.student (id, name, age) VALUES ('1', '张梦为', 1);
  10. INSERT INTO test1.student (id, name, age) VALUES ('2', '上官婉儿', 2);
  11. INSERT INTO test1.student (id, name, age) VALUES ('3', '唐因', 2);
  12. CREATE DATABASE `test2` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; ;
  13. USE `test2`;
  14. CREATE TABLE `lesson`(
  15. `id` VARCHAR(12) PRIMARY KEY,
  16. `name` VARCHAR(36) NOT NULL ,
  17. `credit` FLOAT DEFAULT 0,
  18. `teacher` VARCHAR(36) DEFAULT 0
  19. );
  20. -- 插入数据
  21. INSERT INTO test2.lesson (id, name, credit, teacher) VALUES ('1', '大学物理', 5, '张思瑞');
  22. INSERT INTO test2.lesson (id, name, credit, teacher) VALUES ('2', '高等数学', 5, '李佛');

创建Spring 应用

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

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

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

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

  1. @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

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

配置数据源

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


  1. -- 数据源 Frist
  2. spring.datasource.first.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
  3. spring.datasource.first.username=root
  4. spring.datasource.first.password=
  5. spring.datasource.first.driverClassName=com.mysql.jdbc.Driver
  6. -- 数据源 Second
  7. spring.datasource.second.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
  8. spring.datasource.second.username=root
  9. spring.datasource.second.password=
  10. spring.datasource.second.driverClassName=com.mysql.jdbc.Driver

创建配置文件封装类

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

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

数据源First配置文件封装

  1. package com.zhoutao123.springboot.muldatasources.config;
  2. import lombok.Data;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.stereotype.Component;
  5. @Data
  6. @Component
  7. @ConfigurationProperties(prefix = "spring.datasource.first")
  8. public class FirstDataBaseProperties {
  9. String url;
  10. String username;
  11. String password;
  12. String driverClassName;
  13. }

数据源Second配置文件封装

  1. package com.zhoutao123.springboot.muldatasources.config;
  2. import lombok.Data;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.stereotype.Component;
  5. @Data
  6. @Component
  7. @ConfigurationProperties(prefix = "spring.datasource.second")
  8. public class SecondDataBaseProperties {
  9. String url;
  10. String username;
  11. String password;
  12. String driverClassName;
  13. }

完成数据源配置

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

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

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

  1. package com.zhoutao123.springboot.muldatasources.config;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.mybatis.spring.SqlSessionTemplate;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.beans.factory.annotation.Qualifier;
  8. import org.springframework.boot.context.properties.ConfigurationProperties;
  9. import org.springframework.boot.jdbc.DataSourceBuilder;
  10. import org.springframework.context.annotation.Bean;
  11. import org.springframework.context.annotation.Configuration;
  12. import org.springframework.context.annotation.Primary;
  13. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  14. import javax.sql.DataSource;
  15. @Configuration
  16. @MapperScan(basePackages = "com.zhoutao123.springboot.muldatasources.mapper.first",sqlSessionTemplateRef ="firstSqlSessionTemplate")
  17. public class FirstDataSourceConfig {
  18. @Autowired
  19. private FirstDataBaseProperties prop;
  20. // 创建数据源
  21. @Bean(name = "firstDS")
  22. @ConfigurationProperties(prefix = "spring.datasource.first")
  23. @Primary
  24. public DataSource getFirstDataSource() {
  25. DataSource build = DataSourceBuilder.create()
  26. .driverClassName(prop.driverClassName)
  27. .url(prop.url)
  28. .username(prop.username)
  29. .password(prop.password)
  30. .build();
  31. return build;
  32. }
  33. // 创建SessionFactory
  34. @Bean(name = "firstSqlSessionFactory")
  35. @Primary
  36. public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDS") DataSource dataSource) throws Exception {
  37. SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
  38. bean.setDataSource(dataSource);
  39. return bean.getObject();
  40. }
  41. // 创建事务管理器
  42. @Bean("firstTransactionManger")
  43. @Primary
  44. public DataSourceTransactionManager firstTransactionManger(@Qualifier("firstDS") DataSource dataSource){
  45. return new DataSourceTransactionManager(dataSource);
  46. }
  47. // 创建SqlSessionTemplate
  48. @Bean(name = "firstSqlSessionTemplate")
  49. @Primary
  50. public SqlSessionTemplate firstSqlSessionTemplate(@Qualifier("firstSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
  51. return new SqlSessionTemplate(sqlSessionFactory);
  52. }
  53. private Class getType(String type) {
  54. try {
  55. return Class.forName(type);
  56. } catch (ClassNotFoundException e) {
  57. e.printStackTrace();
  58. }
  59. return null;
  60. }
  61. }

以及第二个数据源的配置

  1. package com.zhoutao123.springboot.muldatasources.config;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.mybatis.spring.SqlSessionTemplate;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.beans.factory.annotation.Qualifier;
  8. import org.springframework.boot.context.properties.ConfigurationProperties;
  9. import org.springframework.boot.jdbc.DataSourceBuilder;
  10. import org.springframework.context.annotation.Bean;
  11. import org.springframework.context.annotation.Configuration;
  12. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  13. import javax.sql.DataSource;
  14. @Configuration
  15. @MapperScan(basePackages = "com.zhoutao123.springboot.muldatasources.mapper.second",sqlSessionTemplateRef ="secondSqlSessionTemplate")
  16. public class SecondDataSourceConfig {
  17. @Autowired
  18. private SecondDataBaseProperties prop;
  19. // 创建数据源
  20. @Bean(name = "secondDS")
  21. @ConfigurationProperties(prefix = "spring.datasource.second")
  22. public DataSource getSecondDataSource() {
  23. DataSource build = DataSourceBuilder.create()
  24. .driverClassName(prop.driverClassName)
  25. .url(prop.url)
  26. .username(prop.username)
  27. .password(prop.password)
  28. .build();
  29. return build;
  30. }
  31. // 创建SessionFactory
  32. @Bean(name = "secondSqlSessionFactory")
  33. public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDS") DataSource dataSource) throws Exception {
  34. SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
  35. bean.setDataSource(dataSource);
  36. return bean.getObject();
  37. }
  38. // 创建事务管理器
  39. @Bean("secondTransactionManger")
  40. public DataSourceTransactionManager secondTransactionManger(@Qualifier("secondDS") DataSource dataSource){
  41. return new DataSourceTransactionManager(dataSource);
  42. }
  43. // 创建SqlSessionTemplate
  44. @Bean(name = "secondSqlSessionTemplate")
  45. public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
  46. return new SqlSessionTemplate(sqlSessionFactory);
  47. }
  48. private Class getType(String type) {
  49. try {
  50. return Class.forName(type);
  51. } catch (ClassNotFoundException e) {
  52. e.printStackTrace();
  53. }
  54. return null;
  55. }
  56. }

实现Mapper

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

返回模型

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

  1. package com.zhoutao123.springboot.muldatasources.dao;
  2. import lombok.Data;
  3. import lombok.experimental.Accessors;
  4. @Data
  5. @Accessors(chain = true)
  6. public class Lesson {
  7. private String id;
  8. private String name;
  9. private String teacher;
  10. private float credit;
  11. }
  1. package com.zhoutao123.springboot.muldatasources.dao;
  2. import lombok.Data;
  3. import lombok.experimental.Accessors;
  4. @Data
  5. @Accessors(chain = true)
  6. public class Student {
  7. private String id;
  8. private String name;
  9. private String age;
  10. }

创建映射Mapper

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

测试接口

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

  1. package com.zhoutao123.springboot.muldatasources;
  2. import com.zhoutao123.springboot.muldatasources.config.FirstDataSourceConfig;
  3. import com.zhoutao123.springboot.muldatasources.config.SecondDataSourceConfig;
  4. import com.zhoutao123.springboot.muldatasources.dao.Lesson;
  5. import com.zhoutao123.springboot.muldatasources.dao.Student;
  6. import com.zhoutao123.springboot.muldatasources.mapper.first.StudentMapper;
  7. import com.zhoutao123.springboot.muldatasources.mapper.second.LessonMapper;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.boot.SpringApplication;
  10. import org.springframework.boot.autoconfigure.SpringBootApplication;
  11. import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  12. import org.springframework.context.annotation.ComponentScan;
  13. import org.springframework.web.bind.annotation.GetMapping;
  14. import org.springframework.web.bind.annotation.RestController;
  15. import java.security.PublicKey;
  16. import java.util.List;
  17. // 排除数据源的自动配置
  18. @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
  19. @RestController
  20. public class MuldatasourcesApplication {
  21. @Autowired
  22. private StudentMapper studentMapper;
  23. @Autowired
  24. private LessonMapper lessonMapper;
  25. public static void main(String[] args) {
  26. SpringApplication.run(MuldatasourcesApplication.class, args);
  27. }
  28. @GetMapping("/student")
  29. public List<Student> studentList(){
  30. return studentMapper.getAllStudent();
  31. }
  32. @GetMapping("/lesson")
  33. public List<Lesson> lessonList(){
  34. return lessonMapper.getAllLesson();
  35. }
  36. }

测试结果

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

SpringBoot+MyBatis配置多数据源的更多相关文章

  1. springboot + mybatis配置多数据源示例

    转:http://www.jb51.net/article/107223.htm 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1)Datab ...

  2. SpringBoot MyBatis 配置多数据源 (静态多个)

    转载地址:https://www.jianshu.com/p/118ca1d5ecf9?utm_campaign=haruki&utm_content=note&utm_medium= ...

  3. SpringBoot集成Mybatis配置动态数据源

    很多人在项目里边都会用到多个数据源,下面记录一次SpringBoot集成Mybatis配置多数据源的过程. pom.xml <?xml version="1.0" encod ...

  4. springboot入门系列(四):SpringBoot和Mybatis配置多数据源连接多个数据库

    SpringBoot和Mybatis配置多数据源连接多个数据库 目前业界操作数据库的框架一般是 Mybatis,但在很多业务场景下,我们需要在一个工程里配置多个数据源来实现业务逻辑.在SpringBo ...

  5. springboot和mybatis 配置多数据源

    主数据源(由于代码没有办法复制的原因,下面图片和文字不一致) package com.zhianchen.mysqlremark.toword.config;import com.zaxxer.hik ...

  6. Spring Boot + Mybatis 配置多数据源

    Spring Boot + Mybatis 配置多数据源 Mybatis拦截器,字段名大写转小写 package com.sgcc.tysj.s.common.mybatis; import java ...

  7. spring+myBatis 配置多数据源,切换数据源

    注:本文来源于  tianzhiwuqis <spring+myBatis 配置多数据源,切换数据源> 一个项目里一般情况下只会使用到一个数据库,但有的需求是要显示其他数据库的内容,像这样 ...

  8. SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页

    SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页 **SpringBoot+Mybatis使用Pagehelper分页插件自动分页,非常好用,不用在自己去计算和组装了. ...

  9. springboot+mybatis集成多数据源MySQL/Oracle/SqlServer

    日常开发中可能时常会遇到一些这样的需求,业务数据库和第三方数据库,两个或多个数据库属于不同数据库厂商,这时候就需要通过配置来实现对数据库实现多源处理.大致说一下我的业务场景,框架本身是配置的sprin ...

随机推荐

  1. 介绍几款 Python 类型检查工具

    近日,微软在 Github 上开源了一个 Python 静态类型检查工具:pyright ,引起了社区内的多方关注. 微软在开源项目上的参与力度是越来越大了,不说收购 Github 这种大的战略野心, ...

  2. 为什么range不是迭代器?range到底是什么类型?

    迭代器是 23 种设计模式中最常用的一种(之一),在 Python 中随处可见它的身影,我们经常用到它,但是却不一定意识到它的存在.在关于迭代器的系列文章中(链接见文末),我至少提到了 23 种生成迭 ...

  3. Data Lake Analytics的Geospatial分析函数

    0. 简介 为满足部分客户在云上做Geometry数据的分析需求,阿里云Data Lake Analytics(以下简称:DLA)支持多种格式的地理空间数据处理函数,符合Open Geospatial ...

  4. Java辅助类持续汇总~

    /** * 01 * 描述:List<String>集合去除重复数据 * [时间 2019年3月5日下午3:54:09 作者 陶攀峰] */ public static List<S ...

  5. Java核心技术第四章——3.对象构造

    重载: 如果多个方法(包含构造方法)有相同的名字.不同的参数,便产生重载.编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配挑选出相对应的方法. 如果 ...

  6. 我的第一个MyBatis

    (1)步骤:1.新建实体类对象---根据数据库字段来设计,有多少字段设多少变量,变量名要字段名一致.   2.新建配置文件config.xml---主要用来获取数据源,里面内容大致需要填写:数据库驱动 ...

  7. 你连Nginx怎么转发给你请求都说不清楚,还好意思说自己不是CRUD工程师?

    目录 一.Nginx工作原理二.Nginx进程模型三.Nginx处理HTTP请求流程 Nginx 工作原理 Nginx由内核和模块组成,Nginx本身做的工作实际很少,当它接到一个HTTP请求时,它仅 ...

  8. CAS、原子操作类的应用与浅析及Java8对其的优化

    前几天刷朋友圈的时候,看到一段话:如果现在我是傻逼,那么我现在不管怎么努力,也还是傻逼,因为我现在的傻逼是由以前决定的,现在努力,是为了让以后的自己不再傻逼.话糙理不糙,如果妄想现在努力一下,马上就不 ...

  9. 使用 Moq 测试.NET Core 应用 -- Mock 行为

    第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 关于方法Mock的介绍: https://www.cnbl ...

  10. IDEA代码格式化快捷键(新)

    快捷键:Ctrl+Alt+L 效果: 之前: 之后: