Spring Boot 整合多数据源,这才叫优雅

网站建设3年前发布
57 00

什么是多数据源?最常见的单一应用中最多涉及到一个数据库,即是一个数据源(Datasource)。那么顾名思义,多数据源就是在一个单一应用中涉及到了两个及以上的数据库了。,其实在配置数据源的时候就已经很明确这个定义了,如以下代码:,url、username、password这三个属性已经唯一确定了一个数据库了,DataSource则是依赖这三个创建出来的。则多数据源即是配置多个DataSource(暂且这么理解)。,正如前言介绍到的一个场景,相信大多数做过医疗系统的都会和HIS打交道,为了简化护士以及医生的操作流程,必须要将必要的信息从HIS系统对接过来,据我了解的大致有两种方案如下:,HIS提供视图,比如医护视图、患者视图等,而此时其他系统只需要定时的从HIS视图中读取数据同步到自己数据库中即可。,当然多数据源的使用场景还是有很多的,以上只是简单的一个场景。,本文使用阿里的数据库连接池druid,添加依赖如下:,阿里的数据库连接池非常强大,比如数据监控、数据库加密等等内容,本文仅仅演示与Spring Boot整合的过程,一些其他的功能后续可以自己研究添加。,Druid连接池的starter的自动配置类是DruidDataSourceAutoConfigure,类上标注如下一行注解:,@EnableConfigurationProperties这个注解使得配置文件中的配置生效并且映射到指定类的属性。,”DruidStatProperties中指定的前缀是spring.datasource.druid,这个配置主要是用来设置连接池的一些参数。,DataSourceProperties中指定的前缀是spring.datasource,这个主要是用来设置数据库的url、username、password等信息。,因此我们只需要在全局配置文件中指定数据库的一些配置以及连接池的一些配置信息即可,前缀分别是spring.datasource.druid、spring.datasource,以下是个人随便配置的(application.properties):,在全局配置文件application.properties文件中配置以上的信息即可注入一个数据源到Spring Boot中。其实这仅仅是一种方式,下面介绍另外一种方式。,”在自动配置类中DruidDataSourceAutoConfigure中有如下一段代码:,@ConditionalOnMissingBean和@Bean这两个注解的结合,意味着我们可以覆盖,只需要提前在IOC中注入一个DataSource类型的Bean即可。,”因此我们在自定义的配置类中定义如下配置即可:,以上介绍了两种数据源的配置方式,第一种比较简单,第二种适合扩展,按需选择。,Spring Boot 整合Mybatis其实很简单,简单的几步就搞定,首先添加依赖:,第二步找到自动配置类MybatisAutoConfiguration,有如下一行代码:,老套路了,全局配置文件中配置前缀为mybatis的配置将会映射到该类中的属性。,”可配置的东西很多,比如XML文件的位置、类型处理器等等,如下简单的配置:,如果需要通过包扫描的方式注入Mapper,则需要在配置类上加入一个注解:@MapperScan,其中的value属性指定需要扫描的包。,直接在全局配置文件配置各种属性是一种比较简单的方式,其实的任何组件的整合都有不少于两种的配置方式,下面来介绍下配置类如何配置。,”MybatisAutoConfiguration自动配置类有如下一断代码:,@ConditionalOnMissingBean和@Bean真是老搭档了,意味着我们又可以覆盖,只需要在IOC容器中注入SqlSessionFactory(Mybatis六剑客之一生产者)。,在自定义配置类中注入即可,如下:,以上介绍了配置Mybatis的两种方式,其实在大多数场景中使用第一种已经够用了,至于为什么介绍第二种呢?当然是为了多数据源的整合而做准备了。,”在MybatisAutoConfiguration中有一行很重要的代码,如下:,@ConditionalOnSingleCandidate这个注解的意思是当IOC容器中只有一个候选Bean的实例才会生效。,这行代码标注在Mybatis的自动配置类中有何含义呢?下面介绍,哈哈哈~,上文留下的问题:为什么的Mybatis自动配置上标注如下一行代码:,以上这行代码的言外之意:当IOC容器中只有一个数据源DataSource,这个自动配置类才会生效。,”哦?照这样搞,多数据源是不能用Mybatis吗?,可能大家会有一个误解,认为多数据源就是多个的DataSource并存的,当然这样说也不是不正确。,多数据源的情况下并不是多个数据源并存的,Spring提供了AbstractRoutingDataSource这样一个抽象类,使得能够在多数据源的情况下任意切换,相当于一个动态路由的作用,作者称之为动态数据源。因此Mybatis只需要配置这个动态数据源即可。,什么是动态数据源?,动态数据源简单的说就是能够自由切换的数据源,类似于一个动态路由的感觉,Spring 提供了一个抽象类AbstractRoutingDataSource,这个抽象类中哟一个属性,如下:,targetDataSources是一个Map结构,所有需要切换的数据源都存放在其中,根据指定的KEY进行切换。当然还有一个默认的数据源。,AbstractRoutingDataSource这个抽象类中有一个抽象方法需要子类实现,如下:,determineCurrentLookupKey()这个方法的返回值决定了需要切换的数据源的KEY,就是根据这个KEY从targetDataSources取值(数据源)。,数据源切换如何保证线程隔离?,数据源属于一个公共的资源,在多线程的情况下如何保证线程隔离呢?不能我这边切换了影响其他线程的执行。,说到线程隔离,自然会想到ThreadLocal了,将切换数据源的KEY(用于从targetDataSources中取值)存储在ThreadLocal中,执行结束之后清除即可。,”单独封装了一个DataSourceHolder,内部使用ThreadLocal隔离线程,代码如下:,如何构造一个动态数据源?,上文说过只需继承一个抽象类AbstractRoutingDataSource,重写其中的一个方法determineCurrentLookupKey()即可。代码如下:,上述代码很简单,分析如下:,定义一个注解,为了操作方便且低耦合,不能每次需要切换的数据源的时候都要手动调一下接口吧,可以定义一个切换数据源的注解,如下:,注解中只有一个value属性,指定了需要切换数据源的KEY。,有注解还不行,当然还要有切面,代码如下:,这个ASPECT很容易理解,beforeOpt()在方法之前执行,取值@SwitchSource中value属性设置到ThreadLocal中;afterOpt()方法在方法执行之后执行,清除掉ThreadLocal中的KEY,保证了如果不切换数据源,则用默认的数据源。,如何与Mybatis整合?,单一数据源与Mybatis整合上文已经详细讲解了,数据源DataSource作为参数构建了SqlSessionFactory,同样的思想,只需要把这个数据源换成动态数据源即可。注入的代码如下:,与Mybatis整合很简单,只需要把数据源替换成自定义的动态数据源DynamicDataSource。,”那么动态数据源如何注入到IOC容器中呢?看上文自定义的DynamicDataSource构造方法,肯定需要两个数据源了,因此必须先注入两个或者多个数据源到IOC容器中,如下:,以上构建的两个数据源,一个是默认的数据源,一个是需要切换到的数据源(targetDataSources),这样就组成了动态数据源了。数据源的一些信息,比如url,username需要自己在全局配置文件中根据指定的前缀配置即可,代码不再贴出。,”动态数据源的注入代码如下:,这里还有一个问题:IOC中存在多个数据源了,那么事务管理器怎么办呢?它也懵逼了,到底选择哪个数据源呢?因此事务管理器肯定还是要重新配置的。,”事务管理器此时管理的数据源将是动态数据源DynamicDataSource,配置如下:,至此,Mybatis与多数据源的整合就完成了。,演示,使用也是很简单,在需要切换数据源的方法上方标注@SwitchSource切换到指定的数据源即可,如下:,这样只要执行到这方法将会切换到HIS的数据源,方法执行结束之后将会清除,执行默认的数据源。,本篇文章讲了Spring Boot与单数据源、Mybatis、多数据源之间的整合,希望这篇文章能够帮助读者理解多数据源的整合,虽说用的不多,但是在有些领域仍然是比较重要的。

© 版权声明

相关文章