最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?多數(shù)據(jù)源方法級(jí)別注解實(shí)現(xiàn)過程

 更新時(shí)間:2023年07月26日 14:16:12   作者:東皋長(zhǎng)歌  
多數(shù)據(jù)源管理是Spring框架中非常重要的一部分,它可以提高應(yīng)用程序的靈活性和可靠性,從而更好地滿足業(yè)務(wù)需求,這篇文章主要介紹了Spring?多數(shù)據(jù)源方法級(jí)別注解實(shí)現(xiàn),需要的朋友可以參考下

Spring框架提供了多種數(shù)據(jù)源管理方式,其中多數(shù)據(jù)源管理是其中之一。多數(shù)據(jù)源管理允許應(yīng)用程序使用多個(gè)數(shù)據(jù)源,而不是只使用一個(gè)數(shù)據(jù)源,從而提高了應(yīng)用程序的靈活性和可靠性。

多數(shù)據(jù)源管理的主要目的是讓應(yīng)用程序能夠在不同的數(shù)據(jù)庫(kù)之間切換,以滿足不同的業(yè)務(wù)需求。例如,如果應(yīng)用程序需要訪問一個(gè)高可用性的數(shù)據(jù)庫(kù),但是該數(shù)據(jù)庫(kù)當(dāng)前不可用,那么應(yīng)用程序可以自動(dòng)切換到備用數(shù)據(jù)庫(kù),以保證業(yè)務(wù)的連續(xù)性。

在多數(shù)據(jù)源管理中,Spring框架通過使用JNDI(Java命名和目錄接口)來管理數(shù)據(jù)源。JNDI允許應(yīng)用程序在運(yùn)行時(shí)動(dòng)態(tài)查找數(shù)據(jù)源,并且可以使用不同的數(shù)據(jù)源來訪問不同的數(shù)據(jù)庫(kù)。

在多數(shù)據(jù)源管理中,還需要考慮數(shù)據(jù)源的配置和管理。這包括創(chuàng)建數(shù)據(jù)源、配置數(shù)據(jù)源、管理連接池和處理連接泄漏等問題。Spring框架提供了多種數(shù)據(jù)源配置和管理的工具和技術(shù),例如Spring JDBC Template、Spring Data JPA和Spring Boot等。

總之,多數(shù)據(jù)源管理是Spring框架中非常重要的一部分,它可以提高應(yīng)用程序的靈活性和可靠性,從而更好地滿足業(yè)務(wù)需求。

廢話少說,直接開干!

下面詳細(xì)地介紹一下多數(shù)據(jù)源的實(shí)現(xiàn)過程,同時(shí)實(shí)現(xiàn)一個(gè)方法級(jí)別的注解,便于靈活使用。

1, Pom配置

引入mysql,spring-boot-starter-jdbc

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
	<version>2.4.2</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>${mysql-connector.version}</version>
</dependency>
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>${mybatis-plus.version}</version>
</dependency>

2,配置數(shù)據(jù)源

可以在項(xiàng)目里,或者在apollo,nacos等配置中心上

#數(shù)據(jù)源master
spring.dynamic.datasource.master.url = jdbc:mysql://127.0.0.1:3306/aaa?characterEncoding=utf-8&rewriteBatchedStatements=true&tinyInt1isBit=false&allowMultiQueries=true
spring.dynamic.datasource.master.username = root
spring.dynamic.datasource.master.password = xxxxxxxx
spring.dynamic.datasource.master.driver-class-name = com.mysql.cj.jdbc.Driver
spring.dynamic.datasource.master.type = com.zaxxer.hikari.HikariDataSource
#數(shù)據(jù)源slave
spring.dynamic.datasource.slave.url = jdbc:mysql://127.0.0.1:3306/bbb?characterEncoding=utf-8&rewriteBatchedStatements=true&tinyInt1isBit=false&allowMultiQueries=true
spring.dynamic.datasource.slave.username = root
spring.dynamic.datasource.slave.password = yyyyyyyy
spring.dynamic.datasource.slave.driver-class-name = com.mysql.cj.jdbc.Driver
spring.dynamic.datasource.slave.type = com.zaxxer.hikari.HikariDataSource

3,讀取數(shù)據(jù)源配置

3.1 先看整個(gè)項(xiàng)目結(jié)構(gòu)

3.2 新增讀取數(shù)據(jù)源配置類

import lombok.Data;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Map;
@Data
@ConfigurationProperties(prefix = "spring.dynamic")
public class DSProperties {
    private Map<String, DataSourceProperties> datasource;
}

 3.3 新增線程和數(shù)據(jù)源mapping的類

 
import com.xxx.gateway.common.Constant;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DynamicDataSourceHolder {
    /**
     * 保存動(dòng)態(tài)數(shù)據(jù)源名稱
     */
    private static final ThreadLocal<String> DYNAMIC_DATASOURCE_KEY = new ThreadLocal<>();
    /**
     * 設(shè)置/切換數(shù)據(jù)源,決定當(dāng)前線程使用哪個(gè)數(shù)據(jù)源
     */
    public static void setDynamicDataSourceKey(String key){
        log.info("數(shù)據(jù)源切換為:{}",key);
        DYNAMIC_DATASOURCE_KEY.set(key);
    }
    /**
     * 獲取動(dòng)態(tài)數(shù)據(jù)源名稱,默認(rèn)使用mater數(shù)據(jù)源
     */
    public static String getDynamicDataSourceKey(){
        String key = DYNAMIC_DATASOURCE_KEY.get();
        return key == null ? Constant.MASTER_DATASOURCE : key;
    }
    /**
     * 移除當(dāng)前數(shù)據(jù)源
     */
    public static void removeDynamicDataSourceKey(){
        log.info("移除數(shù)據(jù)源:{}",DYNAMIC_DATASOURCE_KEY.get());
        DYNAMIC_DATASOURCE_KEY.remove();
    }
}

3.4 繼承路由多數(shù)據(jù)源的抽象類,并實(shí)現(xiàn)determineCurrentLookupKey方法

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        String dataBaseType = DynamicDataSourceHolder.getDynamicDataSourceKey();
        return dataBaseType;
    }
}

4,根據(jù)配置重寫數(shù)據(jù)源和事務(wù)管理器

注意: 下面這個(gè)注解里的basePackages是你項(xiàng)目的路徑

@MapperScan(basePackages = {"com.xxx.gateway.mapper"},

sqlSessionFactoryRef = "SqlSessionFactory")

 
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableConfigurationProperties(DSProperties.class)
@MapperScan(basePackages = {"com.xxx.gateway.mapper"},
        sqlSessionFactoryRef = "SqlSessionFactory")
public class DynamicDataSourceConfig {
    @Bean(name = "dynamicDataSource")
    public DynamicDataSource DataSource(DSProperties dsProperties) {
        Map targetDataSource = new HashMap<>(8);
        dsProperties.getDatasource().forEach((k, v) -> {
            targetDataSource.put(k, v.initializeDataSourceBuilder().build());
        });
        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSource);
        return dataSource;
    }
    /**
     * 創(chuàng)建動(dòng)態(tài)數(shù)據(jù)源的SqlSessionFactory,傳入的是動(dòng)態(tài)數(shù)據(jù)源
     * @Primary這個(gè)注解很重要,如果項(xiàng)目中存在多個(gè)SqlSessionFactory,這個(gè)注解一定要加上
     */
    @Primary
    @Bean("SqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean(DynamicDataSource dynamicDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dynamicDataSource);
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setDefaultFetchSize(100);
        configuration.setDefaultStatementTimeout(30);
        sqlSessionFactoryBean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean.getObject();
    }
    /**
     * 重寫事務(wù)管理器,管理動(dòng)態(tài)數(shù)據(jù)源
     */
    @Primary
    @Bean(value = "transactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager(DynamicDataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

5,注解實(shí)現(xiàn)

5.1 新增注解定義 

import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DS {
    String value() default Constant.MASTER_DATASOURCE;
}

5.2 新增注解實(shí)現(xiàn)

import com.xxx.gateway.config.DynamicDataSourceHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Aspect
@Order(1)
@Component
@Slf4j
public class DsAspect {
    @Pointcut("@annotation(com.xgd.gateway.aspect.DS)")
    public void dsPointCut() {
    }
    //環(huán)繞通知
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        String key = getDefineAnnotation(joinPoint).value();
        DynamicDataSourceHolder.setDynamicDataSourceKey(key);
        try {
            return joinPoint.proceed();
        } finally {
            DynamicDataSourceHolder.removeDynamicDataSourceKey();
        }
    }
    /**
     * 先判斷方法的注解,后判斷類的注解,以方法的注解為準(zhǔn)
     * @param joinPoint
     * @return
     */
    private DS getDefineAnnotation(ProceedingJoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        DS dataSourceAnnotation = methodSignature.getMethod().getAnnotation(DS.class);
        if (Objects.nonNull(methodSignature)) {
            return dataSourceAnnotation;
        } else {
            Class<?> dsClass = joinPoint.getTarget().getClass();
            return dsClass.getAnnotation(DS.class);
        }
    }
}

6, 通過注解使用多數(shù)據(jù)源

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xxx.gateway.aspect.DS;
import com.xxx.gateway.domain.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper extends BaseMapper<User> {
    public User queryByCode(@Param("code") String code);
    @DS(value="master")
    public User queryByCodeNoPass(@Param("code") String code);
    @DS(value="slave1")
    public List<String> queryBanks();
}

注意:

1,@DS注解里的value值是可以隨意的,只要和配置中心里spring.dynamic.datasource.后面的一致就可以。

 2,如果方法上沒有配置數(shù)據(jù)源,那么就是走默認(rèn)的master數(shù)據(jù)源,所以項(xiàng)目里必須至少配置了master數(shù)據(jù)源。

3,各個(gè)數(shù)據(jù)源可以重復(fù),因?yàn)椴粫?huì)校驗(yàn)是否重復(fù)。

到此這篇關(guān)于Spring 多數(shù)據(jù)源方法級(jí)別注解實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Spring 多數(shù)據(jù)源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文詳解gRPC快速整合SpringCloud

    一文詳解gRPC快速整合SpringCloud

    這篇文章主要為大家介紹gRPC快速整合SpringCloud的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Sentinel Dashboard限流規(guī)則保存方式

    Sentinel Dashboard限流規(guī)則保存方式

    這篇文章主要介紹了Sentinel Dashboard限流規(guī)則保存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 在springboot中使用p6spy方式

    在springboot中使用p6spy方式

    這篇文章主要介紹了在springboot中使用p6spy方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 使用spring.profiles.active來分區(qū)配置的方法示例

    使用spring.profiles.active來分區(qū)配置的方法示例

    這篇文章主要介紹了使用spring.profiles.active來分區(qū)配置的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Spring中的Aware接口及應(yīng)用場(chǎng)景詳解

    Spring中的Aware接口及應(yīng)用場(chǎng)景詳解

    這篇文章主要介紹了Spring中的Aware接口及應(yīng)用場(chǎng)景,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java Linkedlist原理及實(shí)例詳解

    Java Linkedlist原理及實(shí)例詳解

    這篇文章主要介紹了Java Linkedlist原理及實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 淺談java8中map的新方法--replace

    淺談java8中map的新方法--replace

    下面小編就為大家?guī)硪黄獪\談java8中map的新方法--replace。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-10-10
  • java安全fastjson1.2.24反序列化TemplatesImpl分析

    java安全fastjson1.2.24反序列化TemplatesImpl分析

    這篇文章主要介紹了java安全fastjson1.2.24反序列化TemplatesImpl分析,fastjson是alibaba開源的一個(gè)用于處理json數(shù)據(jù)格式的解析庫(kù),它支持將java對(duì)象解析成json字符串格式的數(shù)據(jù),也可以將json字符串還原成java對(duì)象
    2022-07-07
  • mybatis之增刪改查

    mybatis之增刪改查

    本篇文章主要介紹了Mybatis實(shí)現(xiàn)數(shù)據(jù)的增刪改查實(shí)例(CRUD),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-07-07
  • Java List的sort()方法改寫compare()實(shí)現(xiàn)升序,降序,倒序的案例

    Java List的sort()方法改寫compare()實(shí)現(xiàn)升序,降序,倒序的案例

    這篇文章主要介紹了Java List的sort()方法改寫compare()實(shí)現(xiàn)升序,降序,倒序的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03

最新評(píng)論

通化县| 潮安县| 通辽市| 崇信县| 崇义县| 肥乡县| 阜阳市| 佛山市| 诸暨市| 澄城县| 文山县| 察雅县| 玛沁县| 万州区| 成都市| 阜阳市| 门源| 石河子市| 安平县| 花莲市| 天柱县| 广州市| 松原市| 美姑县| 昌图县| 通江县| 彭泽县| 永清县| 青河县| 江源县| 南华县| 瓦房店市| 芦溪县| 抚顺县| 阳东县| 邢台市| 桂东县| 伊宁县| 绿春县| 华阴市| 柯坪县|