druid 手动指定数据源_springboot多数据源配置

摘要:项目中用到多个数据库时,比如一个外网库,一个内网库,从而我们需要配置多个数据源,接下来介绍一下SpringBoot多数据源配置,上篇介绍了单数据源使用jdbctemplate访问数据库,springboot使用jdbctemplate访问数据库

abcefbfef381013ac3f2fcee5589506f.png

用到的注解介绍

@ConfigurationProperties

读取Spring的配置文件

@Resource

默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来注入。

它有两个属性是比较重要的:

name: Spring 将 name 的属性值解析为 bean 的名称, 使用 byName 的自动注入策略

type: Spring 将 type的属性值解析为 bean 的类型,使用 byType 的自动注入策略

注: 如果既不指定 name 属性又不指定 type 属性,Spring这时通过反射机制使用 byName 自动注入策略

@Resource的装配顺序

  • 如果同时指定了 name 属性和 type 属性,那么 Spring 将从容器中找唯一匹配的 bean 进行装配,找不到则抛出异常
  • 如果指定了 name 属性值,则从容器中查找名称匹配的 bean 进行装配,找不到则抛出异常
  • 如果指定了 type 属性值,则从容器中查找类型匹配的唯一的 bean 进行装配,找不到或者找到多个都会抛出异常
  • 如果都不指定,则会自动按照 byName 方式进行装配, 如果没有匹配,则回退一个原始类型进行匹配,如果匹配则自动装配

@Autowired

默认是按照类型进行装配注入,默认情况下,它要求依赖对象必须存在,如果允许 null 值,可以设置它 required 为false。

如果我们想要按名称进行装配的话,可以添加一个 @Qualifier 注解解决。

@Primary

在众多相同的bean中,优先使用用@Primary注解的bean.

@Qualifier

搭配@Autowired使用,可以让Spring可以按照Bean名称进入注入

3e79871b491244b8ae66926e745fa8dc.png

多数据源配置:

application.properties中添加多个数据源的配置信息,这边测试我就加了两个数据源代码:

spring.application.name=testserver.port=8088#多数据源配置#第一个数据源spring.datasource.primary.url=jdbc:mysql://127.0.0.1:3306/db1spring.datasource.primary.username=rootspring.datasource.primary.password=root#连接驱动过时了#spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver##第二个数据源spring.datasource.secondary.url=jdbc:mysql://127.0.0.1:3306/db2spring.datasource.secondary.username=rootspring.datasource.secondary.password=root#连接驱动过时了#spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

数据源的配置类,创建JdbcTemplate的时候注入不同的数据源来区分不同的JdbcTemplate

package com.mundo.Test.datasource;import javax.sql.DataSource;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.core.JdbcTemplate;import com.alibaba.druid.pool.DruidDataSource;@Configurationpublic class PrimaryDataSourceConfig {@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary") // 配置文件中配置的数据源前缀@Primary // 相同的bean中,优先使用@Primarypublic DataSource primaryDataSource() {// 指定使用DruidDataSourcereturn DataSourceBuilder.create().type(DruidDataSource.class).build();}@Bean(name = "primaryJdbcTemplate")public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}}

package com.mundo.Test.datasource;import javax.sql.DataSource;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.core.JdbcTemplate;import com.alibaba.druid.pool.DruidDataSource;@Configurationpublic class SecondaryDatasourceConfig {@Bean(name = "secondaryDataSource")@Qualifier("secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {// 指定使用DruidDataSourcereturn DataSourceBuilder.create().type(DruidDataSource.class).build();}@Bean(name = "secondaryJdbcTemplate")public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}}

单元测试:

package com.mundo.Test;import java.util.List;import java.util.Map;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.test.context.junit4.SpringRunner;import com.alibaba.fastjson.JSONObject;@RunWith(SpringRunner.class)@SpringBootTestpublic class TestMandDatasource {@Autowired@Qualifier("primaryJdbcTemplate")private JdbcTemplate primary;@Autowired@Qualifier("secondaryJdbcTemplate")private JdbcTemplate secondary;@Testpublic void test() {// 第一个数据源List> list1 = primary.queryForList("select * from user");System.out.println(JSONObject.toJSONString(list1));// 第二个数据源List> list2 = secondary.queryForList("select * from computer");System.out.println(JSONObject.toJSONString(list2));}}
bb326663029485bf46b689cf6d9f9cd7.png

容易出错的地方:@Primary注解的使用,两个数据源都是使用了@Primary注解就会出现下面这个错误:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean found among candidates: [primaryDataSource, secondaryDataSource]at org.springframework.beans.factory.support.DefaultListableBeanFactory.determinePrimaryCandidate(DefaultListableBeanFactory.java:1370) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1028) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:344) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:339) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1092) ~[spring-context-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.init(DataSourceInitializer.java:77) ~[spring-boot-autoconfigure-1.5.19.RELEASE.jar:1.5.19.RELEASE]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_66]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]... 54 common frames omitted
455e091466b862ddb91c8e679be0c997.png

每天进步一点点,前进不止一小点,你侬我侬不如码农,欢迎关注转发评论!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值