多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问题,之前有小伙伴在我的知识星球上提问,他的数据根据条件的不同,可能保存在四十多个不同的数据库中,怎么办?这种场景下使用多数据源其实就有些费事了,我给的建议是使用 MyCat,然后分表策略使用 sharding-by-intfile 。

当然如果一些简单的需求,还是可以使用多数据源的,Spring Boot 中,JdbcTemplate、MyBatis 以及 Jpa 都可以配置多数据源,本文就先和大伙聊一聊 JdbcTemplate 中多数据源的配置(关于JdbcTemplate的用法,如果还有小伙伴不了解,可以参考我的 Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate)。

创建工程

首先是创建工程,和前文一样,创建工程时,也是选择 Web、Jdbc 以及 MySQL 驱动,如下图:

创建成功之后,一定接下来手动添加 Druid 依赖,由于这里一会需要开发者自己配置 DataSoruce,所以这里必须要使用 druid-spring-boot-starter 依赖,而不是传统的那个 druid 依赖,因为 druid-spring-boot-starter 依赖提供了 DruidDataSourceBuilder 类,这个可以用来构建一个 DataSource 实例,而传统的 Druid 则没有该类。完整的依赖如下:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.28</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>

配置数据源

接下来,在 application.properties 中配置数据源,不同于上文,这里的数据源需要配置两个,如下:

spring.datasource.one.url=jdbc:mysql:///test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.one.username=root
spring.datasource.one.password=root
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.two.url=jdbc:mysql:///test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.two.username=root
spring.datasource.two.password=root
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource

这里通过 one 和 two 对数据源进行了区分,但是加了 one 和 two 之后,这里的配置就没法被 SpringBoot 自动加载了(因为前面的 key 变了),需要我们自己去加载 DataSource 了,此时,需要自己配置一个 DataSourceConfig,用来提供两个 DataSource Bean,如下:

@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}

这里提供了两个 Bean,其中 @ConfigurationProperties 是 Spring Boot 提供的类型安全的属性绑定,以第一个Bean为例, @ConfigurationProperties(prefix = "spring.datasource.one") 表示使用 spring.datasource.one 前缀的数据库配置去创建一个 DataSource,这样配置之后,我们就有了两个不同的 DataSource,接下来再用这两个不同的 DataSource 去创建两个不同的 JdbcTemplate。

配置 JdbcTemplate 实例

创建 JdbcTemplateConfig 类,用来提供两个不同的 JdbcTemplate 实例,如下:

@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dsOne) {
return new JdbcTemplate(dsOne);
}
@Bean
JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dsTwo) {
return new JdbcTemplate(dsTwo);
}
}

每一个 JdbcTemplate 的创建都需要一个 DataSource,由于 Spring 容器中现在存在两个 DataSource,默认使用类型查找,会报错,因此加上 @Qualifier 注解,表示按照名称查找。这里创建了两个 JdbcTemplate 实例,分别对应了两个 DataSource。

接下来直接去使用这个 JdbcTemplate 就可以了。

测试使用

关于 JdbcTemplate 的详细用法大伙可以参考我的上篇文章,这里我主要演示数据源的差异,在 Controller 中注入两个不同的 JdbcTemplate ,这两个 JdbcTemplate 分别对应了不同的数据源,如下:

@RestController
public class HelloController {
@Autowired
@Qualifier("jdbcTemplateOne")
JdbcTemplate jdbcTemplateOne;
@Resource(name = "jdbcTemplateTwo")
JdbcTemplate jdbcTemplateTwo; @GetMapping("/user")
public List<User> getAllUser() {
List<User> list = jdbcTemplateOne.query("select * from t_user", new BeanPropertyRowMapper<>(User.class));
return list;
}
@GetMapping("/user2")
public List<User> getAllUser2() {
List<User> list = jdbcTemplateTwo.query("select * from t_user", new BeanPropertyRowMapper<>(User.class));
return list;
}
}

和 DataSource 一样,Spring 容器中的 JdbcTemplate 也是有两个,因此不能通过 byType 的方式注入进来,这里给大伙提供了两种注入思路,一种是使用 @Resource 注解,直接通过 byName 的方式注入进来,另外一种就是 @Autowired 注解加上 @Qualifier 注解,两者联合起来,实际上也是 byName。将 JdbcTemplate 注入进来之后,jdbcTemplateOne 和 jdbcTemplateTwo 此时就代表操作不同的数据源,使用不同的 JdbcTemplate 操作不同的数据源,实现了多数据源配置。

好了,这个问题就先说到这里,感兴趣的小伙伴也可以参考相关案例:https://github.com/lenve/javaboy-code-samples

关注公众号【江南一点雨】,专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!

Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源的更多相关文章

  1. Spring Boot2 系列教程(三十)Spring Boot 整合 Ehcache

    用惯了 Redis ,很多人已经忘记了还有另一个缓存方案 Ehcache ,是的,在 Redis 一统江湖的时代,Ehcache 渐渐有点没落了,不过,我们还是有必要了解下 Ehcache ,在有的场 ...

  2. Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源

    本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题.在 Spring Boot 整合JbdcTemplate 多数据源. ...

  3. Spring Boot2 系列教程(二十六)Spring Boot 整合 Redis

    在 Redis 出现之前,我们的缓存框架各种各样,有了 Redis ,缓存方案基本上都统一了,关于 Redis,松哥之前有一个系列教程,尚不了解 Redis 的小伙伴可以参考这个教程: Redis 教 ...

  4. Spring Boot2 系列教程(二十八)Spring Boot 整合 Session 共享

    这篇文章是松哥的原创,但是在第一次发布的时候,忘了标记原创,结果被好多号转发,导致我后来整理的时候自己没法标记原创了.写了几百篇原创技术干货了,有一两篇忘记标记原创进而造成的一点点小小损失也能接受,不 ...

  5. Spring Boot2 系列教程(二十四)Spring Boot 整合 Jpa

    Spring Boot 中的数据持久化方案前面给大伙介绍了两种了,一个是 JdbcTemplate,还有一个 MyBatis,JdbcTemplate 配置简单,使用也简单,但是功能也非常有限,MyB ...

  6. Spring Boot2 系列教程(二)创建 Spring Boot 项目的三种方式

    我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 43W+,如下图: 2017 年由于种种原因,就没有 ...

  7. Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源

    关于多数据源的配置,前面和大伙介绍过 JdbcTemplate 多数据源配置,那个比较简单,本文来和大伙说说 MyBatis 多数据源的配置. 其实关于多数据源,我的态度还是和之前一样,复杂的就直接上 ...

  8. Spring Boot2 系列教程(二十九)Spring Boot 整合 Redis

    经过 Spring Boot 的整合封装与自动化配置,在 Spring Boot 中整合Redis 已经变得非常容易了,开发者只需要引入 Spring Data Redis 依赖,然后简单配下 red ...

  9. Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

随机推荐

  1. RMAN备份归档日志ORA-19575

    RMAN备份归档日志ORA-19575 一.问题描述 1)环境oracle 10g; 2)报错现象RMAN进行备份归档报错失败ORA-19575 二.问题处理 1)根据客户说明的现象,百度了一波(详见 ...

  2. __pycache__

    最近在使用python写一个串口模块的时候,偶然发现运行脚本之后,在工程文件夹下面出现了这样一个文件夹__pycache__,所以就特意到网上查了一下这个文件夹是怎么回事. 我们先在源文件中添加一些内 ...

  3. Go语言入门教程(十)之函数

    Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...

  4. spring5 源码深度解析----- AOP目标方法和增强方法的执行(100%理解AOP)

    上一篇博文中我们讲了代理类的生成,这一篇主要讲解剩下的部分,当代理类调用时,目标方法和代理方法是如何执行的,我们还是接着上篇的ReflectiveMethodInvocation类Proceed方法来 ...

  5. .NET成人礼 | 还记得20年前一起拖过的控件吗?

    本文是MVP Ediwang写的回忆一个80后的拖控件的感悟,与君共勉: 每一代人都有记忆里的味道.煤球炉.黑白电视机是属于父母的记忆.而“拖控件”式编程,启蒙了无数像我这样的80后(嗯,89也算80 ...

  6. Rust到底值不值得学--Rust对比、特色和理念

    前言 其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了. 当然这只是一个玩笑,可别把这个问题当真. 然而对于IT从业者来说,这可不是一个玩笑.几乎每一次的技术发 ...

  7. C# 读取控制台的Console.Write

    一个程序去调用另一个xxx.exe的时候,需要记录下这个exe里面的console.write的输出 public static string InvokeExcute(string Command) ...

  8. Android中内存泄露与如何有效避免OOM总结

    一.关于OOM与内存泄露的概念 我们在Android开发过程中经常会遇到OOM的错误,这是因为我们在APP中没有考虑dalvik虚拟机内存消耗的问题. 1.什么是OOM OOM:即OutOfMemoe ...

  9. spring和springmvc的基础知识点

    1.spring中使用@Service("userservice")如何在其他地方引用这个service? (1)getBean("userservice") ...

  10. 一次Commons-HttpClient的BindException排查

    线上有个老应用,在流量增长的时候,HttpClient抛出了BindException.部分的StackTrace信息如下: java.net.BindException: Address alrea ...