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
    评论
在Spring Boot项目中使用MyBatis Plus和Druid多数据源的步骤如下: 1. 添加依赖 在`pom.xml`文件中添加以下依赖: ```xml <!-- MyBatis Plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.1</version> </dependency> <!-- Druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version> </dependency> ``` 2. 配置Druid数据源 在`application.yml`中添加Druid数据源配置: ```yaml spring: datasource: # 主数据源 druid: url: jdbc:mysql://localhost:3306/main_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver # Druid配置 initialSize: 5 minIdle: 5 maxActive: 20 testOnBorrow: false testOnReturn: false testWhileIdle: true timeBetweenEvictionRunsMillis: 60000 validationQuery: SELECT 1 FROM DUAL # 从数据源 druid2: url: jdbc:mysql://localhost:3306/sub_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver # Druid配置 initialSize: 5 minIdle: 5 maxActive: 20 testOnBorrow: false testOnReturn: false testWhileIdle: true timeBetweenEvictionRunsMillis: 60000 validationQuery: SELECT 1 FROM DUAL ``` 3. 配置MyBatis Plus 在`application.yml`中添加MyBatis Plus的配置: ```yaml mybatis-plus: # 主数据源配置 mapper-locations: classpath:mapper/main/*.xml type-aliases-package: com.example.main.entity global-config: db-config: id-type: auto field-strategy: not_empty logic-delete-value: 1 logic-not-delete-value: 0 configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 从数据源配置 multi-datasource: main: mapper-locations: classpath:mapper/main/*.xml type-aliases-package: com.example.main.entity sub: mapper-locations: classpath:mapper/sub/*.xml type-aliases-package: com.example.sub.entity ``` 4. 配置数据源路由 在`com.example.config`包下创建`DynamicDataSourceConfig`类,用于配置数据源路由: ```java @Configuration public class DynamicDataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.druid") public DataSource mainDataSource() { return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.druid2") public DataSource subDataSource() { return DruidDataSourceBuilder.create().build(); } @Bean public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); Map<Object, Object> dataSourceMap = new HashMap<>(2); dataSourceMap.put("main", mainDataSource()); dataSourceMap.put("sub", subDataSource()); // 将主数据源作为默认数据源 dynamicDataSource.setDefaultTargetDataSource(mainDataSource()); dynamicDataSource.setTargetDataSources(dataSourceMap); return dynamicDataSource; } @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dynamicDataSource()); sqlSessionFactoryBean.setTypeAliasesPackage("com.example.main.entity"); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/main/*.xml")); return sqlSessionFactoryBean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplate() throws Exception { return new SqlSessionTemplate(sqlSessionFactory()); } } ``` 5. 配置数据源切换 在`com.example.config`包下创建`DynamicDataSource`类,用于实现数据源切换: ```java public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSource(); } } ``` 在`com.example.config`包下创建`DataSourceContextHolder`类,用于存储当前数据源: ```java public class DataSourceContextHolder { private static final ThreadLocal<String> DATASOURCE_CONTEXT_HOLDER = new ThreadLocal<>(); public static void setDataSource(String dataSource) { DATASOURCE_CONTEXT_HOLDER.set(dataSource); } public static String getDataSource() { return DATASOURCE_CONTEXT_HOLDER.get(); } public static void clearDataSource() { DATASOURCE_CONTEXT_HOLDER.remove(); } } ``` 在`com.example.aop`包下创建`DataSourceAspect`类,用于切换数据源: ```java @Aspect @Component public class DataSourceAspect { @Pointcut("@annotation(com.example.annotation.DataSource)") public void dataSourcePointCut() { } @Before("dataSourcePointCut()") public void before(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); DataSource dataSource = signature.getMethod().getAnnotation(DataSource.class); if (dataSource != null) { String value = dataSource.value(); DataSourceContextHolder.setDataSource(value); } } @After("dataSourcePointCut()") public void after(JoinPoint joinPoint) { DataSourceContextHolder.clearDataSource(); } } ``` 6. 使用多数据源 在需要使用从数据源的方法上加上`@DataSource("sub")`注解,如: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<User> listUsers() { DataSourceContextHolder.setDataSource("sub"); List<User> users = userMapper.selectList(null); DataSourceContextHolder.clearDataSource(); return users; } } ``` 这样就完成了Spring Boot项目中使用MyBatis Plus和Druid多数据源配置

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值