国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

spring boot es | spring boot 整合elasticsearch | spring boot整合多數(shù)據(jù)源es

這篇具有很好參考價值的文章主要介紹了spring boot es | spring boot 整合elasticsearch | spring boot整合多數(shù)據(jù)源es。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

Spring Boot與ES版本對應(yīng)

Maven依賴

配置類

使用方式

@Test中注入方式

@Component中注入方式

查詢文檔

實體類

通過ElasticsearchRestTemplate查詢

通過JPA查詢

保存文檔

參考鏈接


項目組件版本:

Spring Boot:2.2.13.RELEASE

Elasticsearch:6.8.0

JDK:1.8.0_66

Spring Boot與ES版本對應(yīng)

spring boot es | spring boot 整合elasticsearch | spring boot整合多數(shù)據(jù)源es

Tips: 主要看第3列和第5列,根據(jù)ES版本選擇對應(yīng)的Spring Boot版本,如果ES和Spring Boot版本不一致后續(xù)會報錯。

Maven依賴

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.13.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- 其他無關(guān)內(nèi)容省略 -->

 <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        <version>2.2.13.RELEASE</version>
    </dependency>
</dependencies>

配置類

通過配置類定義兩個ES鏈接的elasticsearchClient,如果是一個連接刪除其中一個即可。

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchEntityMapper;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.EntityMapper;
import org.springframework.http.HttpHeaders;

/**
 * @author He Changjie on 2022/6/6 14:02
 */
@Configuration
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration{
    /** ES鏈接一 [host:port] */
    @Value("${spring.data.elasticsearch.client.reactive.endpoints}")
    private String endpoints;
    /** ES鏈接二 [host:port] */
    @Value("${spring.data.elasticsearch.client.reactive.endpoints.zeek}")
    private String endpointsZeek;
    /** 連接elasticsearch超時時間 */
    @Value("${spring.data.elasticsearch.client.reactive.connection-timeout}")
    private Integer connectTimeout;
    /** 套接字超時時間 */
    @Value("${spring.data.elasticsearch.client.reactive.socket-timeout}")
    private Integer socketTimeout;

    /** 用戶名 */
    @Value("${spring.data.elasticsearch.client.reactive.username}")
    private String username;
    /** 密碼 */
    @Value("${spring.data.elasticsearch.client.reactive.password}")
    private String password;

    @Bean("elasticsearchRestTemplate")
    @Primary
    public ElasticsearchRestTemplate elasticsearchTemplate() {
        return new ElasticsearchRestTemplate(elasticsearchClient());
    }

    /**
     * 構(gòu)建方式一
     */
    @Bean("restHighLevelClient")
    @Primary
    @Override
    public RestHighLevelClient elasticsearchClient() {
        // 初始化 RestClient, hostName 和 port 填寫集群的內(nèi)網(wǎng) IP 地址與端口
        final String host = StringUtils.substringBefore(endpoints, ":");
        final int port = Integer.parseInt(StringUtils.substringAfter(endpoints, ":"));
        RestClientBuilder builder = RestClient.builder(new HttpHost(host, port))
                .setRequestConfigCallback(config -> {
                    config.setConnectTimeout(connectTimeout);
                    config.setSocketTimeout(socketTimeout);
                    return config;
                });
        //?;畈呗?        builder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
                .setDefaultIOReactorConfig(IOReactorConfig.custom()
                        .setSoKeepAlive(true)
                        .build()));
        // 設(shè)置認(rèn)證信息
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
        builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
            httpAsyncClientBuilder.disableAuthCaching();
            return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        });

        return new RestHighLevelClient(builder);
    }

    @Bean("zeekElasticsearchTemplate")
    public ElasticsearchRestTemplate ZeekElasticsearchTemplate() {
        return new ElasticsearchRestTemplate(zeekRestHighLevelClient());
    }

    /**
     * 構(gòu)建方式二
     */
    @Bean("zeekRestHighLevelClient")
    public RestHighLevelClient zeekRestHighLevelClient() {
        HttpHeaders defaultHeaders = new HttpHeaders();
        defaultHeaders.setBasicAuth(username, password);
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(endpointsZeek)
                .withConnectTimeout(connectTimeout)
                .withSocketTimeout(socketTimeout)
                .withDefaultHeaders(defaultHeaders)
                .withBasicAuth(username, password)
                .build();
        return RestClients.create(clientConfiguration).rest();
    }

    @Bean
    @Override
    public EntityMapper entityMapper() {
        ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
                new DefaultConversionService());
        entityMapper.setConversions(elasticsearchCustomConversions());
        return entityMapper;
    }
}

Tips:

  1. 配置類中定義RestHighLevelClient使用了兩個種方式,任選其中一種都可以
  2. 必須選擇一個ES鏈接打上@Primary注解
  3. 示例中兩個連接都需要密碼,且密碼相同

使用方式

elasticsearchRestTemplate的使用在@Test中和其他@Component中注入方式不同(親測),在@Component中直接使用@Resource注入ElasticsearchRestTemplate會報找不到對應(yīng)的Bean。

@Test中注入方式

@Resource(name = "elasticsearchRestTemplate")
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Resource(name = "zeekElasticsearchTemplate")
private ElasticsearchRestTemplate zeekElasticsearchTemplate;

@Component中注入方式

@Service
public class DemoServiceImpl implements DemoService {
    private final ElasticsearchRestTemplate elasticsearchRestTemplate;
    private final ElasticsearchRestTemplate zeekElasticsearchRestTemplate;

    @Autowired
    public DemoServiceImpl(RestHighLevelClient restHighLevelClient,
    					@Qualifier(value = "zeekRestHighLevelClient") RestHighLevelClient zeekRestHighLevelClient) {
        this.elasticsearchRestTemplate = new ElasticsearchRestTemplate(restHighLevelClient);
        this.zeekElasticsearchRestTemplate = new ElasticsearchRestTemplate(zeekRestHighLevelClient);
    }
}

查詢文檔

實體類

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.io.Serializable;

@Data
@Document(indexName = "demo-index-20220609", type = "log")
public class QdnsLogs implements Serializable {
    @Id
    private String _id;
    @Field(type = FieldType.Keyword)
    private String name;
    @Field(type = FieldType.Keyword)
    private String address;
    // ........
    @Field(type = FieldType.Date, name = "timestamp")
    private Long timestamp;
}

Tips:

  1. 該類具體內(nèi)容進行了脫敏
  2. 需要特別注意@Document的type一定要和es中的_type一致,否則查詢結(jié)果為是空
  3. 如果不需要保存文檔,可以不要@Field注解

通過ElasticsearchRestTemplate查詢

import com.xxx.entity.es.Eth0Logs;
import com.xxx.entity.es.QdnsLogs;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.*;
import javax.annotation.Resource;
import java.util.List;

/**
 * 實現(xiàn)描述:
 *
 * @author Hecj
 * @version v 1.0.0
 * @since 2022/06/17
 */
@SpringBootTest(classes = Application.class)
public class EsTest {
    @Resource(name = "elasticsearchRestTemplate")
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Resource(name = "zeekElasticsearchTemplate")
    private ElasticsearchRestTemplate zeekElasticsearchTemplate;

    /**
     * 通過時間范圍和是否存在某一字段查詢
     */
    @Test
    void test1(){
        SearchQuery searchQuery  = new NativeSearchQueryBuilder()//查詢數(shù)據(jù),構(gòu)造出一個查詢
                .withQuery(QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("timestamp").from(1654506000000L).to(1654507340785L)).must(QueryBuilders.existsQuery("name")))
                .build();//構(gòu)造一個SearchQuery
        List<QdnsLogs> list = elasticsearchRestTemplate.queryForList(searchQuery, QdnsLogs.class);
        System.out.println(list.size());
    }

    /**
     * 通過name值等于特定值
     */
    @Test
    void test2(){
        SearchQuery searchQuery  = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.termQuery("name", "zhangsan"))
                .build();//構(gòu)造一個SearchQuery
        List<Eth0Logs> eth0Logs = zeekElasticsearchTemplate.queryForList(searchQuery, Eth0Logs.class);
        System.out.println(eth0Logs.size());
        for (Eth0Logs log : eth0Logs) {
            System.out.println(log.getTs());
        }
    }

    /**
     * aggs查詢
     * 
     * 查詢指定時間范圍內(nèi)存在name值的記錄,進行通過name聚合,按照時間倒序排序取最新一條記錄
     */
    @Test
    void test3() {
        SearchQuery searchQuery  = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.boolQuery()
                        .must(
                                QueryBuilders.rangeQuery("timestamp")
                                        .from(1654506000000L)
                                        .to(1654507340785L)
                        )
                        .must(QueryBuilders.existsQuery("name")))
                .addAggregation(AggregationBuilders.terms("name")
                        .field("name")
                        .size(10000)
                        .subAggregation(
                                AggregationBuilders.topHits("top")
                                        .sort("timestamp", SortOrder.DESC)
                                        .size(1)
                        )
                )
                .build();
        AggregatedPage<QdnsLogs> logs = elasticsearchRestTemplate.queryForPage(searchQuery, QdnsLogs.class);
        ParsedStringTerms fqdn = (ParsedStringTerms)logs.getAggregation("name");
        List<? extends Terms.Bucket> buckets = fqdn.getBuckets();
        for (Terms.Bucket entry : buckets) {
            String key = entry.getKeyAsString();
            TopHits topHits= entry.getAggregations().get("top");
            SearchHits hits = topHits.getHits();
            SearchHit at = hits.getAt(0);
            System.out.println(key + "-" + at);
        }
    }
}

Tips: 部分包完整名稱進行了脫敏

通過JPA查詢

這里的接口不需要添加@Service,通過JPA方式需要特別注意書寫規(guī)范,字段名稱的正確性。

interface BookRepository extends Repository<Book, String> {
  List<Book> findByNameAndPrice(String name, Integer price);
}

相當(dāng)于:

{
    "query": {
        "bool" : {
            "must" : [
                { "query_string" : { "query" : "?", "fields" : [ "name" ] } },
                { "query_string" : { "query" : "?", "fields" : [ "price" ] } }
            ]
        }
    }
}

Table 2. Supported keywords inside method names

Keyword Sample Elasticsearch Query String

And

findByNameAndPrice

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, { "query_string" : { "query" : "?", "fields" : [ "price" ] } } ] } }}

Or

findByNameOrPrice

{ "query" : { "bool" : { "should" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, { "query_string" : { "query" : "?", "fields" : [ "price" ] } } ] } }}

Is

findByName

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } } ] } }}

Not

findByNameNot

{ "query" : { "bool" : { "must_not" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } } ] } }}

Between

findByPriceBetween

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}

LessThan

findByPriceLessThan

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } } ] } }}

LessThanEqual

findByPriceLessThanEqual

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}

GreaterThan

findByPriceGreaterThan

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } } ] } }}

GreaterThanEqual

findByPriceGreaterThan

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } ] } }}

Before

findByPriceBefore

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}

After

findByPriceAfter

{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } ] } }}

Like

findByNameLike

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}

StartingWith

findByNameStartingWith

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}

EndingWith

findByNameEndingWith

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}

Contains/Containing

findByNameContaining

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "*?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}

In

findByNameIn(Collection<String>names)

{ "query" : { "bool" : { "must" : [ {"bool" : {"must" : [ {"terms" : {"name" : ["?","?"]}} ] } } ] } }}

NotIn

findByNameNotIn(Collection<String>names)

{ "query" : { "bool" : { "must" : [ {"bool" : {"must_not" : [ {"terms" : {"name" : ["?","?"]}} ] } } ] } }}

Near

findByStoreNear

Not Supported Yet !

True

findByAvailableTrue

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "true", "fields" : [ "available" ] } } ] } }}

False

findByAvailableFalse

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "false", "fields" : [ "available" ] } } ] } }}

OrderBy

findByAvailableTrueOrderByNameDesc

{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "true", "fields" : [ "available" ] } } ] } }, "sort":[{"name":{"order":"desc"}}] }

保存文檔

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;

// 這里的dataList是需要保存到ES的bean集合,各位自行替換
List<IndexQuery> queries = dataList.stream().map(e -> {
        IndexQuery query = new IndexQuery();
        // 這個自行替換,也可以省略
        query.setId(IdUtil.simpleUUID());
        // 具體的數(shù)據(jù)
        query.setObject(e);
        // 索引名稱
        query.setIndexName("demo-index-20220609");
        // 索引類型
        query.setType("log");
        return query;
    }).collect(Collectors.toList());
    
    if(CollectionUtil.isNotEmpty(queries)){
        zeekElasticsearchTemplate.bulkIndex(queries);
        log.info("#~ 寫入日志成功,寫入條數(shù):{}", queries.size());
    }

參考鏈接

Spring Data版本依賴矩陣

elasticsearch官方手冊文章來源地址http://www.zghlxwxcb.cn/news/detail-416923.html

到了這里,關(guān)于spring boot es | spring boot 整合elasticsearch | spring boot整合多數(shù)據(jù)源es的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Spring Boot 3】【數(shù)據(jù)源】自定義JPA數(shù)據(jù)源

    軟件開發(fā)是一門實踐性科學(xué),對大多數(shù)人來說,學(xué)習(xí)一種新技術(shù)不是一開始就去深究其原理,而是先從做出一個可工作的DEMO入手。但在我個人學(xué)習(xí)和工作經(jīng)歷中,每次學(xué)習(xí)新技術(shù)總是要花費或多或少的時間、檢索不止一篇資料才能得出一個可工作的DEMO,這占用了我大量的時

    2024年01月21日
    瀏覽(32)
  • 【Spring Boot 3】【數(shù)據(jù)源】自定義JDBC多數(shù)據(jù)源

    軟件開發(fā)是一門實踐性科學(xué),對大多數(shù)人來說,學(xué)習(xí)一種新技術(shù)不是一開始就去深究其原理,而是先從做出一個可工作的DEMO入手。但在我個人學(xué)習(xí)和工作經(jīng)歷中,每次學(xué)習(xí)新技術(shù)總是要花費或多或少的時間、檢索不止一篇資料才能得出一個可工作的DEMO,這占用了我大量的時

    2024年01月23日
    瀏覽(28)
  • 【Spring Boot 3】【數(shù)據(jù)源】自定義JPA多數(shù)據(jù)源

    軟件開發(fā)是一門實踐性科學(xué),對大多數(shù)人來說,學(xué)習(xí)一種新技術(shù)不是一開始就去深究其原理,而是先從做出一個可工作的DEMO入手。但在我個人學(xué)習(xí)和工作經(jīng)歷中,每次學(xué)習(xí)新技術(shù)總是要花費或多或少的時間、檢索不止一篇資料才能得出一個可工作的DEMO,這占用了我大量的時

    2024年01月22日
    瀏覽(30)
  • Spring Boot 配置雙數(shù)據(jù)源

    Spring Boot 配置雙數(shù)據(jù)源

    Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive. happy for hardess to solve denpendies. 需求: 1.基本步驟 添加依賴 添加 Spring Boot 和數(shù)據(jù)庫驅(qū)動的依賴 配置數(shù)據(jù)源 在 application.properties 或 application.yml 中分別配

    2024年01月22日
    瀏覽(23)
  • ElasticSearch多數(shù)據(jù)源配置,連接多個ES集群

    開發(fā)時遇到需要連接多個ES的需求,類似于連接多個MySQL數(shù)據(jù)庫一樣。 Elasticsearch Java API有四類client連接方式 TransportClient RestClient Jest Spring Data Elasticsearch ????????其中TransportClient和RestClient是Elasticsearch原生的api。TransportClient可以支持2.x,5.x版本,TransportClient將會在Elasticsea

    2023年04月14日
    瀏覽(17)
  • 【Java】Spring Boot配置動態(tài)數(shù)據(jù)源

    1.1 創(chuàng)建動態(tài)數(shù)據(jù)源 通過實現(xiàn)Spring提供的AbstractRoutingDataSource類,可以實現(xiàn)自己的數(shù)據(jù)源選擇邏輯,從而可以實現(xiàn)數(shù)據(jù)源的動態(tài)切換。 1.2 創(chuàng)建動態(tài)數(shù)據(jù)源配置類 跟配置靜態(tài)多數(shù)據(jù)源一樣,需要手動配置下面的三個 Bean,只不過DynamicDataSource類的targetDataSources是空的。 1.3 創(chuàng)建動

    2024年02月09日
    瀏覽(25)
  • 實例講解Spring boot動態(tài)切換數(shù)據(jù)源

    摘要: 本文模擬一下在主庫查詢訂單信息查詢不到的時候,切換數(shù)據(jù)源去歷史庫里面查詢。 本文分享自華為云社區(qū)《springboot動態(tài)切換數(shù)據(jù)源》,作者:小陳沒煩惱 。 在公司的系統(tǒng)里,由于數(shù)據(jù)量較大,所以配置了多個數(shù)據(jù)源,它會根據(jù)用戶所在的地區(qū)去查詢那一個數(shù)據(jù)庫

    2024年02月06日
    瀏覽(26)
  • Spring Boot配置多個Kafka數(shù)據(jù)源

    application.properties配置文件如下 1.第一個kakfa 2.第二個kakfa 備注: 生產(chǎn)者消費者代碼參考鏈接,開發(fā)同學(xué)需要以實際情況按要求自己變更下代碼即可: Spring Boot 集成多個 Kafka_springboot集成多個kafka_//承續(xù)緣_紀(jì)錄片的博客-CSDN博客

    2024年02月07日
    瀏覽(27)
  • 如何在Spring Boot中配置雙數(shù)據(jù)源?

    在許多應(yīng)用程序中, 可能會遇到需要連接多個數(shù)據(jù)庫的情況 。這些數(shù)據(jù)庫可以是不同的類型,例如關(guān)系型數(shù)據(jù)庫和NoSQL數(shù)據(jù)庫,或者它們可以是相同類型但包含不同的數(shù)據(jù)。為了處理這種情況,我們可以使用雙數(shù)據(jù)源來管理多個數(shù)據(jù)庫連接。 雙數(shù)據(jù)源是指在一個應(yīng)用程序中

    2024年02月11日
    瀏覽(20)
  • Spring Boot 多數(shù)據(jù)源及事務(wù)解決方案

    Spring Boot 多數(shù)據(jù)源及事務(wù)解決方案

    一個主庫和N個應(yīng)用庫的數(shù)據(jù)源,并且會同時操作主庫和應(yīng)用庫的數(shù)據(jù),需要解決以下兩個問題: 如何動態(tài)管理多個數(shù)據(jù)源以及切換? 如何保證多數(shù)據(jù)源場景下的數(shù)據(jù)一致性(事務(wù))? 本文主要探討這兩個問題的解決方案,希望能對讀者有一定的啟發(fā)。 通過擴展Spring提供的抽象

    2024年02月10日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包