栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Springboot 整合数据源

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot 整合数据源

Springboot 整合数据源 整合 Mybaits

pom.xml


    mysql
    mysql-connector-java


    org.springframework.boot
    spring-boot-starter-jdbc


    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    2.1.0

添加配置 application.yml

spring:
  datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql:///bank? useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
      username: root
      password: 123456
mybatis:
  # 扫描 mapper.xml 文件路径
  mapper-locations: classpath:mapper/*.xml

定义接口 com.demo.mapper.UserMapper

public interface UserMapper {
    List findAll();
}

编写 xml 文件 mapper/UserMapper.xml




    
        select * from user
    


多数据源

添加配置 application.yml

spring:
  datasource:
    master:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql:///bank? useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
      username: root
      password: 123456
    slave:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql:///test? useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
      username: root
      password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml

根据配置生成 DataSource

@Configuration
public class MultipleDataSourceConfig {

    @Bean("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    private DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    private DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
}

将生成的 DataSource 放入 targetDataSources 这个 Map中

@Configuration
public class PrimaryDataSourceConfig {

    @Autowired
    @Qualifier("masterDataSource")
    private DataSource masterDataSource;

    @Autowired
    @Qualifier("slaveDataSource")
    private DataSource slaveDataSource;

    @Bean
    @Primary
    DataSource primaryDataSource() {
        Map map = new HashMap<>();
        map.put("masterDataSource", masterDataSource);
        map.put("slaveDataSource", slaveDataSource);
        RoutingDataSource routing = new RoutingDataSource();
        routing.setTargetDataSources(map);
        return routing;
    }
}

继承 AbstractRoutingDataSource 返回需要使用的 数据源的 key

public class RoutingDataSource extends AbstractRoutingDataSource {
	@Override
    protected Object determineCurrentLookupKey() {
        return "masterDataSource";
    }
}

此时 key 不能写死,将 key 放入 ThreadLocal 中

public class RoutingDataSourceContext {

    private static final ThreadLocal threadLocalDataSourceKey = new ThreadLocal<>();

    // 获取数据源的 key
    public static String getDataSourceRoutingKey() {
        String key = threadLocalDataSourceKey.get();
        return key == null ? "masterDataSource" : key;
    }

    // 往 ThreadLocal 中设置 key
    public RoutingDataSourceContext(String key) {
        threadLocalDataSourceKey.set(key);
    }

    // 移除 ThreadLocal 中的 key
    public void close() {
        threadLocalDataSourceKey.remove();
    }
}

// 进行设置 key
// RoutingDataSourceContext routingDataSourceContext = new RoutingDataSourceContext("slaveDataSource");

public class RoutingDataSource extends AbstractRoutingDataSource {
	@Override
    protected Object determineCurrentLookupKey() {
        return RoutingDataSourceContext.getDataSourceRoutingKey();
    }
}

此时每次调用方法都需要设置数据源的 key,可以按照 AOP 思想,将设置 key 的方法提取出来

定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RoutingWith {
    String value() default "masterDataSource";
}
@Aspect
@Component
public class RoutingAspect {
    @Around("@annotation(routingWith)")
    public Object routingWithDataSource(ProceedingJoinPoint joinPoint, RoutingWith routingWith) throws Throwable {
        String key = routingWith.value();
        RoutingDataSourceContext ctx = new RoutingDataSourceContext(key);
        return joinPoint.proceed();
    }
}
@RequestMapping("/findAll")
// 该注解能够判断使用哪个数据源
@RoutingWith("slaveDataSource")
public List findAll() {
    return userMapper.findAll();
}
整合 spring data JPA

pom.xml


    org.springframework.boot
    spring-boot-starter-data-jpa


    mysql
    mysql-connector-java

定义接口

public interface UserRepository extends JpaRepository {}
多数据源

application.yml 配置同上

根据配置生成 DataSource

@Configuration
public class MultipleDataSourceConfig {
    // 此处和 Mybatis 的设置区别,需要 @Primary
    @Primary
    @Bean("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    DataSource masterDataSource() {
        System.out.println("create master datasource...");
        return DataSourceBuilder.create().build();
    }

    @Bean("slaverDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    DataSource slaveDataSource() {
        System.out.println("create slave datasource...");
        return DataSourceBuilder.create().build();
    }
}

根据两个 DataSource 生成 entityManager

@Configuration
@EnableJpaRepositories(
    // //配置连接工厂 entityManagerFactory
    entityManagerFactoryRef = "entityManagerFactoryMaster",
    // com.demo.repository 为 repository 接口所在的目录
    basePackages = {"com.demo.repository"}
)
public class MasterDataSourceConfig {

    @Autowired
    @Qualifier("masterDataSource")
    private DataSource dataSourceMaster;

    @Primary
    @Bean("entityManagerMaster")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryBean(builder).getObject().createEntityManager();
    }

    @Primary
    @Bean("entityManagerFactoryMaster")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
        // com.demo.pojo 为实体类所在目录
        return builder.dataSource(dataSourceMaster).packages("com.demo.pojo").build();
    }
}
@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "entityManagerFactorySlave",
    basePackages = {"com.demo.slaveRepository"}
)
public class SlaveDataSourceConfig {

    @Autowired
    @Qualifier("slaverDataSource")
    private DataSource dataSource;

    @Bean("entityManagerSlave")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryBean(builder).getObject().createEntityManager();
    }

    @Bean("entityManagerFactorySlave")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dataSource).packages("com.demo.slave").build();
    }
}

定义 repository 接口

    接口名不同的情况
public interface MasterUserRepository extends JpaRepository {}

public interface SlaveUserRepository extends JpaRepository {}

@Autowired
private masterUserRepository userRepository;

List all = userRepository.findAll();
    接口名相同的情况
@Repository("masterUserRepository")
public interface UserRepository extends JpaRepository {}

@Repository("slaveUserRepository")
public interface UserRepository extends JpaRepository {}

@Autowired
@Qualifier("masterUserRepository")
private UserRepository userRepository;

List all = userRepository.findAll();

参考git:https://gitee.com/zhangyizhou/learning-spring-boot-datasource-demo.git

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759880.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号