欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot進(jìn)行多數(shù)據(jù)源配置的詳細(xì)步驟

 更新時(shí)間:2025年06月23日 09:40:55   作者:墨鴉_Cormorant  
多數(shù)據(jù)源是指在一個(gè)應(yīng)用程序中同時(shí)連接和使用多個(gè)數(shù)據(jù)庫的能力,這篇文章主要為大家介紹了SpringBoot進(jìn)行多數(shù)據(jù)源配置的詳細(xì)步驟,有需要的小伙伴可以了解下

多數(shù)據(jù)源核心概念

多數(shù)據(jù)源是指在一個(gè)應(yīng)用程序中同時(shí)連接和使用多個(gè)數(shù)據(jù)庫的能力。在實(shí)際開發(fā)中,我們經(jīng)常會(huì)遇到以下場景需要多數(shù)據(jù)源:

  • 同時(shí)連接生產(chǎn)數(shù)據(jù)庫和報(bào)表數(shù)據(jù)庫
  • 讀寫分離場景(主庫寫,從庫讀)
  • 微服務(wù)架構(gòu)中需要訪問其他服務(wù)的數(shù)據(jù)庫
  • 多租戶系統(tǒng)中每個(gè)租戶有獨(dú)立數(shù)據(jù)庫

多數(shù)據(jù)源實(shí)現(xiàn)示例

多數(shù)據(jù)源的配置文件以及配置類

application.yml 配置示例

spring:
  datasource:
      jdbc-url: jdbc:mysql://localhost:3306/db1 # 主數(shù)據(jù)源
      username: root
      password: root123
      driver-class-name: com.mysql.cj.jdbc.Driver
      hikari:
        pool-name: PrimaryHikariPool
        # 最大連接數(shù) 
        maximum-pool-size: 20
        # 最小空閑連接
        minimum-idle: 5
        # 空閑連接超時(shí)時(shí)間(ms)
        idle-timeout: 30000
        # 連接最大生命周期(ms)
        max-lifetime: 1800000
        # 獲取連接超時(shí)時(shí)間(ms)
        connection-timeout: 30000
        connection-test-query: SELECT 1
  second-datasource:
      jdbc-url: jdbc:mysql://localhost:3306/db2 # 主數(shù)據(jù)源
      username: root
      password: root123
      driver-class-name: com.mysql.cj.jdbc.Driver
      hikari:
        pool-name: SecondHikariPool
        maximum-pool-size: 20
        minimum-idle: 5
        idle-timeout: 30000
        max-lifetime: 1800000
        connection-timeout: 30000
        connection-test-query: SELECT 1

多數(shù)據(jù)源配置類

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;

@Configuration
public class DbConfig {

    @Bean("db1DataSourceProperties")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties db1DataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "db1DataSource")
    public DataSource dataSource() {
        return db1DataSourceProperties().initializeDataSourceBuilder().build();
    }

    
    @Bean("db2DataSourceProperties")
    @ConfigurationProperties(prefix = "spring.second-datasource")
    public DataSourceProperties db2DataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "db2DataSource")
    public DataSource db2DataSource() {
        return db2DataSourceProperties().initializeDataSourceBuilder().build();
    }
}

禁用默認(rèn)數(shù)據(jù)源

多數(shù)據(jù)源時(shí)需在主類排除自動(dòng)配置

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

JPA 多數(shù)據(jù)源配置

主數(shù)據(jù)源 JAP 配置

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Objects;

@Configuration
// 啟用 Spring 的事務(wù)管理功能,允許使用 @Transactional 注解來管理事務(wù)
@EnableTransactionManagement
// 啟用 JPA 倉庫的自動(dòng)掃描和注冊(cè)功能
@EnableJpaRepositories(
        // 指定要掃描的 JPA 倉庫接口所在的包路徑
        basePackages = "com.example.db1",
        // 指定使用的實(shí)體管理器工廠的 Bean 名稱
        entityManagerFactoryRef = "db1EntityManagerFactory",
        // 指定使用的事務(wù)管理器的 Bean 名稱
        transactionManagerRef = "db1TransactionManager"
)
public class Db1JpaConfig {
    /**
     * 創(chuàng)建實(shí)體管理器工廠的 Bean,并將其標(biāo)記為主要的實(shí)體管理器工廠 Bean
     */
    @Bean(name = "db1EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            @Qualifier("db1DataSource")DataSource dataSource,
            JpaProperties jpaProperties) {
        return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), 
                                               new HashMap<>(), null)
                // 設(shè)置數(shù)據(jù)源
                .dataSource(dataSource)
                // 指定要掃描的實(shí)體類所在的包路徑
                .packages("com.example.db1")
                // 設(shè)置持久化單元的名稱
                .persistenceUnit("db1")
                // 設(shè)置 JPA 的屬性
                .properties(jpaProperties.getProperties())
                .build();
    }

    /**
     * 創(chuàng)建事務(wù)管理器的 Bean,并將其標(biāo)記為主要的事務(wù)管理器 Bean
     */
    @Bean(name = "db1TransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("db1EntityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory.getObject()));
    }

    /**
     * QueryDSL的核心組件
     */
    @Bean(name = "db1JPAQueryFactory")
    public JPAQueryFactory db1JPAQueryFactory(
            @Qualifier("db1EntityManagerFactory") EntityManager entityManager) {
        return new JPAQueryFactory(entityManager);
    }
}

從數(shù)據(jù)源 JAP 集成配置(略)

MyBatis 多數(shù)據(jù)源配置

主數(shù)據(jù)源 MyBatis 配置

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;

@Configuration
// 此注解用于指定 MyBatis Mapper 接口的掃描范圍和對(duì)應(yīng)的 SqlSessionFactory 引用
@MapperScan(
        // 指定要掃描的 Mapper 接口所在的基礎(chǔ)包路徑
        basePackages = "com.example.mapper.db1",
        // 配置使用的 SqlSessionFactory Bean 的名稱
        sqlSessionFactoryRef = "db1SqlSessionFactory"
)
public class Db1MyBatisConfig {

    /**
     * 創(chuàng)建 SqlSessionFactory Bean
     */
    @Bean("db1SqlSessionFactory")
    public SqlSessionFactory db1SqlSessionFactory(
            @Qualifier("db1DataSource") DataSource dataSource) throws Exception {
        // 創(chuàng)建 SqlSessionFactoryBean 實(shí)例,用于創(chuàng)建 SqlSessionFactory
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        // 設(shè)置 SqlSessionFactory 使用的數(shù)據(jù)源
        sessionFactory.setDataSource(dataSource);
        // 設(shè)置 Mapper XML 文件的位置,使用 PathMatchingResourcePatternResolver 來查找匹配的資源
        sessionFactory.setMapperLocations(
                new PathMatchingResourcePatternResolver()
                        .getResources("classpath:mapper/db1/*.xml"));
        // 獲取并返回 SqlSessionFactory 實(shí)例
        return sessionFactory.getObject();
    }

    /**
     * 創(chuàng)建 SqlSessionTemplate Bean
     */
    @Bean("db1SqlSessionTemplate")
    public SqlSessionTemplate db1SqlSessionTemplate(
            @Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        // 創(chuàng)建并返回 SqlSessionTemplate 實(shí)例,用于簡化 MyBatis 的操作
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * 創(chuàng)建事務(wù)管理器的 Bean,并將其標(biāo)記為主要的事務(wù)管理器 Bean
     */
    @Bean("db1TransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("db1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

從數(shù)據(jù)源 MyBatis 配置(略)

事務(wù)管理:跨數(shù)據(jù)源事務(wù)處理

單數(shù)據(jù)源事務(wù)

在單數(shù)據(jù)源場景下,Spring的事務(wù)管理非常簡單:

@Service
public class AccountService {

    @Transactional  // 使用默認(rèn)事務(wù)管理器
    public void transfer(Long fromId, Long toId, BigDecimal amount) {
        // do some thing ...
    }
}

多數(shù)據(jù)源事務(wù)挑戰(zhàn)

多數(shù)據(jù)源事務(wù)面臨的主要問題是分布式事務(wù)的挑戰(zhàn)。Spring 的 @Transactional 注解默認(rèn)只能管理單個(gè)事務(wù)管理器,無法直接協(xié)調(diào)多個(gè)數(shù)據(jù)源的事務(wù)。

解決方案對(duì)比:

方案原理優(yōu)點(diǎn)缺點(diǎn)適用場景
JTA (Java Transaction API)使用全局事務(wù)協(xié)調(diào)器強(qiáng)一致性性能開銷大,配置復(fù)雜需要強(qiáng)一致性的金融系統(tǒng)
最終一致性 (Saga模式)通過補(bǔ)償操作實(shí)現(xiàn)高性能,松耦合實(shí)現(xiàn)復(fù)雜,需要補(bǔ)償邏輯高并發(fā),可接受短暫不一致
本地消息表通過消息隊(duì)列保證可靠性高需要額外表存儲(chǔ)消息需要可靠異步處理的場景

事務(wù)管理器:DataSourceTransactionManager 和 JpaTransactionManager

DataSourceTransactionManager 和 JpaTransactionManager 是 Spring 框架中針對(duì)不同持久層技術(shù)的事務(wù)管理器。

技術(shù)棧適配差異

1.DataSourceTransactionManager

適用場景:純 JDBC、MyBatis、JdbcTemplate 等基于原生 SQL 的數(shù)據(jù)訪問技術(shù)

事務(wù)控制對(duì)象:直接管理 java.sql.Connection ,通過數(shù)據(jù)庫連接實(shí)現(xiàn)事務(wù)

局限性:

  • 無法自動(dòng)綁定 JPA 或 Hibernate 的 EntityManager/Session 到當(dāng)前事務(wù)上下文
  • 混合使用 JDBC 和 JPA 時(shí)可能導(dǎo)致連接隔離(各自使用獨(dú)立連接),破壞事務(wù)一致性

2.JpaTransactionManager

適用場景:JPA 規(guī)范實(shí)現(xiàn)(如 Hibernate、EclipseLink)

事務(wù)控制對(duì)象:管理 JPA EntityManager,通過其底層連接協(xié)調(diào)事務(wù)

核心優(yōu)勢(shì):

  • 自動(dòng)將 EntityManager 綁定到線程上下文,確保同一事務(wù)中多次操作使用同一連接
  • 支持 JPA 的延遲加載(Lazy Loading)、緩存同步等特性

3.混合技術(shù)棧的特殊情況

混合技術(shù)棧需嚴(yán)格隔離事務(wù)管理器,并考慮分布式事務(wù)需求

JPA操作使用JpaTransactionManager,MyBatis操作使用DataSourceTransactionManager

跨數(shù)據(jù)源事務(wù)需引入分布式事務(wù)(如Atomikos),否則不同數(shù)據(jù)源的事務(wù)無法保證原子性

若一個(gè) Service 方法同時(shí)使用 JPA和 Mybatis(未驗(yàn)證):

  • 使用 DataSourceTransactionManager 可能導(dǎo)致兩個(gè)操作使用不同連接,違反 ACID
  • 使用 JpaTransactionManager 能保證兩者共享同一連接(因 JPA 底層復(fù)用 DataSource 連接)

事務(wù)同步機(jī)制對(duì)比

特性DataSourceTransactionManagerJpaTransactionManager
連接資源管理直接管理 Connection通過 EntityManager 間接管理連接
跨技術(shù)兼容性僅限 JDBC 系技術(shù)支持 JPA 及其混合場景(如 JPA+JDBC)
高級(jí) ORM 功能支持不支持(如延遲加載)完整支持 JPA 特性
配置復(fù)雜度簡單(僅需 DataSource)需額外配置 EntityManagerFactory

多數(shù)據(jù)源事務(wù)使用

事務(wù)配置詳見上文

多數(shù)據(jù)源事務(wù)使用示例

import org.springframework.transaction.annotation.Transactional;

@Service
public class AccountService {
    
    @Transactional(transactionManager = "db1TransactionManager")  // 指定事務(wù)管理器
    public void transfer(Long fromId, Long toId, BigDecimal amount) {
        // do some thing ...
    }
}

基于 AbstractRoutingDataSource 的動(dòng)態(tài)數(shù)據(jù)源

動(dòng)態(tài)數(shù)據(jù)源上下文

public class DynamicDataSourceContextHolder {
    // 使用ThreadLocal保證線程安全
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    // 數(shù)據(jù)源列表
    public static final String PRIMARY_DS = "primary";
    public static final String SECONDARY_DS = "secondary";

    public static void setDataSourceType(String dsType) {
        CONTEXT_HOLDER.set(dsType);
    }

    public static String getDataSourceType() {
        return CONTEXT_HOLDER.get();
    }

    public static void clearDataSourceType() {
        CONTEXT_HOLDER.remove();
    }
}

動(dòng)態(tài)數(shù)據(jù)源配置

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DynamicDataSourceConfig {

    /**
     * 創(chuàng)建動(dòng)態(tài)數(shù)據(jù)源 Bean,并將其設(shè)置為主要的數(shù)據(jù)源 Bean
     */
    @Bean
    @Primary
    public DataSource dynamicDataSource(
            @Qualifier("db1DataSource") DataSource db1DataSource,
            @Qualifier("db2DataSource") DataSource db2DataSource) {
        // 用于存儲(chǔ)目標(biāo)數(shù)據(jù)源的映射,鍵為數(shù)據(jù)源標(biāo)識(shí),值為數(shù)據(jù)源實(shí)例
        Map<Object, Object> targetDataSources = new HashMap<>();
        // 將主數(shù)據(jù)源添加到目標(biāo)數(shù)據(jù)源映射中,使用自定義的主數(shù)據(jù)源標(biāo)識(shí)
        targetDataSources.put(DynamicDataSourceContextHolder.PRIMARY_DS, db1DataSource);
        // 將從數(shù)據(jù)源添加到目標(biāo)數(shù)據(jù)源映射中,使用自定義的從數(shù)據(jù)源標(biāo)識(shí)
        targetDataSources.put(DynamicDataSourceContextHolder.SECONDARY_DS, db2DataSource);

        // 創(chuàng)建自定義的動(dòng)態(tài)數(shù)據(jù)源實(shí)例
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 設(shè)置動(dòng)態(tài)數(shù)據(jù)源的目標(biāo)數(shù)據(jù)源映射
        dynamicDataSource.setTargetDataSources(targetDataSources);
        // 設(shè)置動(dòng)態(tài)數(shù)據(jù)源的默認(rèn)目標(biāo)數(shù)據(jù)源為主數(shù)據(jù)源
        dynamicDataSource.setDefaultTargetDataSource(db1DataSource);

        return dynamicDataSource;
    }

    /**
     * 自定義動(dòng)態(tài)數(shù)據(jù)源類,繼承自 AbstractRoutingDataSource
     */
    private static class DynamicDataSource extends AbstractRoutingDataSource {
        /**
         * 確定當(dāng)前要使用的數(shù)據(jù)源的標(biāo)識(shí)
         * @return 當(dāng)前數(shù)據(jù)源的標(biāo)識(shí)
         */
        @Override
        protected Object determineCurrentLookupKey() {
            // 從上下文持有者中獲取當(dāng)前要使用的數(shù)據(jù)源類型
            return DynamicDataSourceContextHolder.getDataSourceType();
        }
    }
}

基于AOP的讀寫分離實(shí)現(xiàn)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReadOnly {
    // 標(biāo)記為讀操作
}

@Aspect
@Component
public class ReadWriteDataSourceAspect {
    
    @Before("@annotation(readOnly)")
    public void beforeSwitchDataSource(JoinPoint point, ReadOnly readOnly) {
        DynamicDataSourceContextHolder.setDataSourceType(DynamicDataSourceContextHolder.SECONDARY_DS);
    }
    
    @After("@annotation(readOnly)")
    public void afterSwitchDataSource(JoinPoint point, ReadOnly readOnly) {
        DynamicDataSourceContextHolder.clearDataSourceType();
    }
}

使用示例

@Service
public class ProductService {
    
    @Autowired
    private ProductRepository productRepository;
    
    @Transactional
    public void createProduct(Product product) {
        // 默認(rèn)使用主數(shù)據(jù)源(寫)
        productRepository.save(product);
    }
    
    @ReadOnly  // 執(zhí)行該注解標(biāo)記的方法時(shí),前后都會(huì)執(zhí)行ReadWriteDataSourceAspect切面類方法
    @Transactional
    public Product getProduct(Long id) {
        // 使用從數(shù)據(jù)源(讀)
        return productRepository.findById(id).orElse(null);
    }
    
    @ReadOnly
    @Transactional
    public List<Product> listProducts() {
        // 使用從數(shù)據(jù)源(讀)
        return productRepository.findAll();
    }
}

常見問題與解決方案

典型問題排查表

方案原理優(yōu)點(diǎn)缺點(diǎn)適用場景
JTA (Java Transaction API)使用全局事務(wù)協(xié)調(diào)器強(qiáng)一致性性能開銷大,配置復(fù)雜需要強(qiáng)一致性的金融系統(tǒng)
最終一致性 (Saga模式)通過補(bǔ)償操作實(shí)現(xiàn)高性能,松耦合實(shí)現(xiàn)復(fù)雜,需要補(bǔ)償邏輯高并發(fā),可接受短暫不一致
本地消息表通過消息隊(duì)列保證可靠性高需要額外表存儲(chǔ)消息需要可靠異步處理的場景

數(shù)據(jù)源切換失敗案例分析

問題描述:

在動(dòng)態(tài)數(shù)據(jù)源切換場景下,有時(shí)切換不生效,仍然使用默認(rèn)數(shù)據(jù)源。

原因分析:

  • 數(shù)據(jù)源切換代碼被異常繞過,未執(zhí)行
  • 線程池場景下線程復(fù)用導(dǎo)致上下文污染
  • AOP 順序問題導(dǎo)致切換時(shí)機(jī)不對(duì)

解決方案:

@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)  // 確保最先執(zhí)行
public class DataSourceAspect {
    
    @Around("@annotation(targetDataSource)")
    public Object around(ProceedingJoinPoint joinPoint, TargetDataSource targetDataSource) throws Throwable {
        String oldKey = DynamicDataSourceContextHolder.getDataSourceType();
        try {
            DynamicDataSourceContextHolder.setDataSourceType(targetDataSource.value());
            return joinPoint.proceed();
        } finally {
            // 恢復(fù)為原來的數(shù)據(jù)源
            if (oldKey != null) {
                DynamicDataSourceContextHolder.setDataSourceType(oldKey);
            } else {
                DynamicDataSourceContextHolder.clearDataSourceType();
            }
        }
    }
}

???????// 線程池配置確保清理上下文
@Configuration
public class ThreadPoolConfig {
    
    @Bean
    public ExecutorService asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("Async-");
        executor.setTaskDecorator(runnable -> {
            String dsKey = DynamicDataSourceContextHolder.getDataSourceType();
            return () -> {
                try {
                    if (dsKey != null) {
                        DynamicDataSourceContextHolder.setDataSourceType(dsKey);
                    }
                    runnable.run();
                } finally {
                    DynamicDataSourceContextHolder.clearDataSourceType();
                }
            };
        });
        executor.initialize();
        return executor.getThreadPoolExecutor();
    }
}

多數(shù)據(jù)源與緩存集成

當(dāng)多數(shù)據(jù)源與緩存(如 Redis)一起使用時(shí),需要注意緩存鍵的設(shè)計(jì):

@Service
public class CachedUserService {
    @Autowired
    private PrimaryUserRepository primaryUserRepository;
    @Autowired
    private SecondaryUserRepository secondaryUserRepository;
    @Autowired
    private RedisTemplate<String, User> redisTemplate;
    
    private String getCacheKey(String source, Long userId) {
        return String.format("user:%s:%d", source, userId);
    }
    
    @Cacheable(value = "users", key = "#root.target.getCacheKey('primary', #userId)")
    public User getPrimaryUser(Long userId) {
        return primaryUserRepository.findById(userId).orElse(null);
    }
    
    @Cacheable(value = "users", key = "#root.target.getCacheKey('secondary', #userId)")
    public User getSecondaryUser(Long userId) {
        return secondaryUserRepository.findById(userId).orElse(null);
    }
    
    @CacheEvict(value = "users", allEntries = true)
    public void clearAllUserCache() {
        // 清除所有用戶緩存
    }
}

總結(jié)與擴(kuò)展

技術(shù)選型建議

場景推薦方案理由
簡單多數(shù)據(jù)源,無交叉訪問獨(dú)立配置多個(gè)數(shù)據(jù)源簡單直接,易于維護(hù)
需要?jiǎng)討B(tài)切換數(shù)據(jù)源AbstractRoutingDataSource靈活,可運(yùn)行時(shí)決定數(shù)據(jù)源
需要強(qiáng)一致性事務(wù)JTA(XA)保證ACID,但性能較低
高并發(fā),最終一致性可接受Saga模式高性能,松耦合
讀寫分離AOP+注解方式透明化,對(duì)業(yè)務(wù)代碼侵入小

以上就是SpringBoot進(jìn)行多數(shù)據(jù)源配置的詳細(xì)步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot多數(shù)據(jù)源配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot整合定時(shí)任務(wù)的方法

    SpringBoot整合定時(shí)任務(wù)的方法

    通過 ThreadPoolExecutor 可以實(shí)現(xiàn)各式各樣的自定義線程池,而 ScheduledThreadPoolExecutor 類則在自定義線程池的基礎(chǔ)上增加了周期性執(zhí)行任務(wù)的功能,這篇文章主要介紹了SpringBoot整合定時(shí)任務(wù),需要的朋友可以參考下
    2024-05-05
  • Maven私服倉庫Nexus配置小結(jié)

    Maven私服倉庫Nexus配置小結(jié)

    Maven 私服是一種特殊的Maven遠(yuǎn)程倉庫,它是架設(shè)在局域網(wǎng)內(nèi)的倉庫服務(wù),本文就來介紹一下Maven私服倉庫Nexus配置小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • 如何讓@EnableConfigurationProperties的值注入到@Value中

    如何讓@EnableConfigurationProperties的值注入到@Value中

    這篇文章主要介紹了如何讓@EnableConfigurationProperties的值注入到@Value中的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Spring?Security權(quán)限注解啟動(dòng)及邏輯處理使用示例

    Spring?Security權(quán)限注解啟動(dòng)及邏輯處理使用示例

    這篇文章主要為大家介紹了Spring?Security權(quán)限注解啟動(dòng)及邏輯處理使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Feign如何使用protobuf的類作為參數(shù)調(diào)用

    Feign如何使用protobuf的類作為參數(shù)調(diào)用

    這篇文章主要介紹了Feign如何使用protobuf的類作為參數(shù)調(diào)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 指定springboot的jar運(yùn)行內(nèi)存方式

    指定springboot的jar運(yùn)行內(nèi)存方式

    這篇文章主要介紹了指定springboot的jar運(yùn)行內(nèi)存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java實(shí)現(xiàn)視頻格式轉(zhuǎn)化的操作代碼

    Java實(shí)現(xiàn)視頻格式轉(zhuǎn)化的操作代碼

    在當(dāng)今數(shù)字化時(shí)代,視頻已成為我們?nèi)粘I詈凸ぷ髦胁豢苫蛉钡囊徊糠?不同的設(shè)備和平臺(tái)可能支持不同的視頻格式,因此,視頻格式轉(zhuǎn)換的需求也日益增長,本文將介紹如何使用Java實(shí)現(xiàn)視頻格式轉(zhuǎn)換,需要的朋友可以參考下
    2025-01-01
  • Java模擬服務(wù)器解析web數(shù)據(jù)

    Java模擬服務(wù)器解析web數(shù)據(jù)

    本篇文章主要給大家詳細(xì)分享了搭建JavaWeb服務(wù)器的詳細(xì)步驟以及用到的代碼,對(duì)此有需要的朋友可以跟著學(xué)習(xí)下,希望能給你帶來幫助
    2021-07-07
  • Java雙重校驗(yàn)鎖單例原理

    Java雙重校驗(yàn)鎖單例原理

    大家好,本篇文章主要講的是Java雙重校驗(yàn)鎖單例原理,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • 圖解如何在Spring Boot中使用JSP頁面

    圖解如何在Spring Boot中使用JSP頁面

    這篇文章主要介紹了圖解如何在Spring Boot中使用JSP頁面,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評(píng)論