当前位置:   article > 正文

Java使用多数据源 方法配置_java多数据源配置

java多数据源配置

首先需要引入druid连接池依赖 ,此处选择alibaba连接池

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>druid-spring-boot-starter</artifactId>
  4. <version>1.2.8</version>
  5. </dependency>

配置数据源信息  可创建多个

  1. spring:
  2. datasource:
  3. druid:
  4. #第一个数据库连接信息 local
  5. local:
  6. type: com.alibaba.druid.pool.DruidDataSource
  7. username: root
  8. password: mima
  9. driver-class-name: com.mysql.cj.jdbc.Driver
  10. url: jdbc:mysql://localhost:3306/local?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  11. #第二个数据库连接信息 cloud
  12. cloud:
  13. type: com.alibaba.druid.pool.DruidDataSource
  14. username: root
  15. password: mima
  16. driver-class-name: com.mysql.cj.jdbc.Driver
  17. url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

创建配类DataSourceConfig 注入配置信息

  1. import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import javax.sql.DataSource;
  7. @Slf4j
  8. @Configuration
  9. public class DataSourceConfig {
  10. /**
  11. * 将cloud数据连接信息注入cloudDataSource
  12. */
  13. @Bean(name = "cloudDataSource")
  14. @ConfigurationProperties(prefix = "spring.datasource.druid.cloud")
  15. public DataSource cloudDataSource(){
  16. return DruidDataSourceBuilder.create().build();
  17. }
  18. /**
  19. * 将local数据连接信息注入localDataSource
  20. */
  21. @Bean(name = "localDataSource")
  22. @ConfigurationProperties(prefix = "spring.datasource.druid.local")
  23. public DataSource localDataSource(){
  24. return DruidDataSourceBuilder.create().build();
  25. }
  26. }

创建DataSourceNames类 给数据源命名 便于使用。

  1. public interface DataSourceNames {
  2. String cloudDataSource = "CLOUDDATASOURCE";
  3. String localDataSource = "LOCALDATASOURCE";
  4. }

自定义注解DataSource 默认选中数据源 localDataSource 

  1. import java.lang.annotation.*;
  2. @Documented
  3. @Target({ElementType.METHOD})
  4. @Retention(RetentionPolicy.RUNTIME)
  5. public @interface DataSource {
  6. String value() default DataSourceNames.localDataSource;
  7. }

创建 DynamicDataSource类 extends AbstractRoutingDataSource 重写determineCurrentLookupKey方法

  1. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  2. import javax.sql.DataSource;
  3. import java.util.Map;
  4. public class DynamicDataSource extends AbstractRoutingDataSource {
  5. private static final ThreadLocal<String> CONTEXT_HOLDER= new ThreadLocal<>();
  6. /**
  7. * 配置DataSource, defaultTargetDataSource为主数据库
  8. */
  9. public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
  10. super.setDefaultTargetDataSource(defaultTargetDataSource);
  11. super.setTargetDataSources(targetDataSources);
  12. super.afterPropertiesSet();
  13. }
  14. @Override
  15. protected Object determineCurrentLookupKey() {
  16. return getDataSource();
  17. }
  18. public static void setDataSource(String dataSource) {
  19. CONTEXT_HOLDER.set(dataSource);
  20. }
  21. public static String getDataSource() {
  22. return CONTEXT_HOLDER.get();
  23. }
  24. public static void clearDataSource() {
  25. CONTEXT_HOLDER.remove();
  26. }
  27. }

创建SqlSessionConfig

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.springframework.beans.factory.annotation.Qualifier;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.context.annotation.Primary;
  8. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  9. import javax.sql.DataSource;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. @Slf4j
  13. @Configuration
  14. public class SqlSessionConfig{
  15. @Bean(name = "dataSource")
  16. @Primary
  17. DataSource dataSource(@Qualifier("cloudDataSource") DataSource cloudDataSource , @Qualifier("localDataSource") DataSource localDataSource){
  18. Map<Object,Object> targetDataSources = new HashMap<>(2);
  19. targetDataSources.put(DataSourceNames.cloudDataSource,cloudDataSource);
  20. targetDataSources.put(DataSourceNames.localDataSource,localDataSource);
  21. log.info("DataSource:{}" + targetDataSources);
  22. return new DynamicDataSource(localDataSource,targetDataSources);
  23. }
  24. @Bean
  25. @Primary
  26. public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
  27. SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
  28. bean.setDataSource(dataSource);
  29. //在yml文件中配置开启驼峰式命名转化时不生效,在此设置
  30. bean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
  31. bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
  32. return bean.getObject();
  33. }
  34. }

配置切面 在使用自定义@DataSource注解时 将指定数据源注入

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.aspectj.lang.ProceedingJoinPoint;
  3. import org.aspectj.lang.annotation.Around;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Pointcut;
  6. import org.aspectj.lang.reflect.MethodSignature;
  7. import org.springframework.stereotype.Component;
  8. import java.lang.reflect.Method;
  9. @Component
  10. @Aspect
  11. @Slf4j
  12. public class DataSourceAspect {
  13. @Pointcut("@annotation(com.zhuodao.config.DataSource)")
  14. public void pointCut(){}
  15. @Around("pointCut()")
  16. public Object around(ProceedingJoinPoint point) throws Throwable {
  17. MethodSignature signature = (MethodSignature) point.getSignature();
  18. Method method = signature.getMethod();
  19. DataSource dataSource = method.getAnnotation(DataSource.class);
  20. DynamicDataSource.setDataSource(dataSource.value());
  21. log.info("set dataSource is {}" , dataSource.value());
  22. try {
  23. return point.proceed();
  24. }finally {
  25. DynamicDataSource.clearDataSource();
  26. log.info("clearDataSource");
  27. }
  28. }
  29. }

注解注入 在操作数据库时指定数据源 使用@DataSource()注解 示例如下

  1. @Service
  2. public class CloudTaskServiceImpl implements CloudTaskService {
  3. @Autowired
  4. private TaskMapper taskMapper;
  5. //注解注入
  6. @Override
  7. @DataSource(value = DataSourceNames.cloudDataSource)
  8. public int insertTask(Task task) {
  9. return taskMapper.insert(task);
  10. }
  11. }
  1. @Service
  2. @Slf4j
  3. public class LocalTaskServiceImpl implements LocalTaskService {
  4. @Autowired
  5. private TaskMapper taskMapper;
  6. @Override
  7. @DataSource //使用默认数据库
  8. public List<Task> selectAll() {
  9. log.info("task"+taskMapper.selectAll().size());
  10. return taskMapper.selectAll();
  11. }
  12. }

在某些业务上,可能要操作多个数据库,那么使用注解在方法上注入数据源就不是那么的方便,所以就需要手动注入

手动注入 在操作数据库前使用DynamicDataSource.setDataSource("")方法 也可注入 示例如下

  1. @Service
  2. public class CloudTaskServiceImpl implements CloudTaskService {
  3. @Autowired
  4. private TaskMapper taskMapper;
  5. //手动注入
  6. @Override
  7. public int insertTask(Task task) {
  8. DynamicDataSource.setDataSource("CLOUDDATASOURCE");
  9. return taskMapper.insert(task);
  10. }
  11. }

可能会遇到的问题

切面方法不执行 需要加入aspectjrt, aspectjweaver依赖 ,缺一不可!

  1. <dependency>
  2. <groupId>org.aspectj</groupId>
  3. <artifactId>aspectjrt</artifactId>
  4. <version>1.9.7</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.aspectj</groupId>
  8. <artifactId>aspectjweaver</artifactId>
  9. <version>1.9.7</version>
  10. </dependency>

如果你恰好也有可以用多数据源实现的类似场景,希望对你有帮助。如有写的不对或不够好的地方,欢迎指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/52369
推荐阅读
相关标签
  

闽ICP备14008679号