专业的编程技术博客社区

网站首页 > 博客文章 正文

springboot多数据源配置(springboot多数据源配置mybaits不生效)

baijin 2024-08-15 16:54:32 博客文章 7 ℃ 0 评论

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

用到的注解介绍

@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名称进入注入

多数据源配置:

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

spring.application.name=test
server.port=8088
#多数据源配置
#第一个数据源
spring.datasource.primary.url=jdbc:mysql://127.0.0.1:3306/db1
spring.datasource.primary.username=root
spring.datasource.primary.password=root
#连接驱动过时了
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
#
#第二个数据源
spring.datasource.secondary.url=jdbc:mysql://127.0.0.1:3306/db2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root
#连接驱动过时了
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.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;
@Configuration
public class PrimaryDataSourceConfig {
	@Bean(name = "primaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.primary") // 配置文件中配置的数据源前缀
	@Primary // 相同的bean中,优先使用@Primary
	public DataSource primaryDataSource() {
		// 指定使用DruidDataSource
		return 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;
@Configuration
public class SecondaryDatasourceConfig {
	@Bean(name = "secondaryDataSource")
	@Qualifier("secondaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.secondary")
	public DataSource secondaryDataSource() {
		// 指定使用DruidDataSource
		return 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)
@SpringBootTest
public class TestMandDatasource {
	@Autowired
	@Qualifier("primaryJdbcTemplate")
	private JdbcTemplate primary;
	@Autowired
	@Qualifier("secondaryJdbcTemplate")
	private JdbcTemplate secondary;
	@Test
	public void test() {
		// 第一个数据源
		List<Map<String, Object>> list1 = primary.queryForList("select * from user");
		System.out.println(JSONObject.toJSONString(list1));
		// 第二个数据源
		List<Map<String, Object>> list2 = secondary.queryForList("select * from computer");
		System.out.println(JSONObject.toJSONString(list2));
	}
}

容易出错的地方:@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

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

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表