成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot與Druid整合,實現電商主從數據庫同步系統

開發 前端
通過引入主從數據庫同步系統,可以顯著提升電商平臺的性能和穩定性,同時保證數據的一致性和安全性。Druid連接池也提供了強大的監控和安全防護功能,使得整個系統更加健壯和可靠。

通過引入主從數據庫同步系統,可以顯著提升電商平臺的性能和穩定性,同時保證數據的一致性和安全性。Druid連接池也提供了強大的監控和安全防護功能,使得整個系統更加健壯和可靠。

我們為什么選擇Druid?

  • 高效的連接管理:Druid 提供了高效的物理連接復用機制,能夠快速獲取和釋放數據庫連接,減少連接建立和關閉的開銷。
  • 異步初始化:支持異步初始化連接池,提高應用啟動速度。
  • 詳細的統計信息:Druid 內置了豐富的統計功能,可以收集 SQL 執行情況、慢查詢記錄等詳細數據,幫助我們更好地進行性能調優。
  • 防火墻規則:支持配置防火墻規則,限制哪些 IP 地址可以訪問數據庫,增強安全性。
  • SQL 防注入:提供 WallFilter 插件,防止 SQL 注入攻擊,保護數據庫不受惡意 SQL 的影響。
  • 多數據源支持:Druid 支持配置多個數據源,非常適合實現讀寫分離等高級場景。在我們的項目中,主從數據庫的配置正是利用了這一特性。

哪些公司在使用Druid?

  • 阿里巴巴 :Druid 是由阿里巴巴開源的一個項目,最初是為了滿足其內部龐大的業務需求而開發。目前用于阿里巴巴旗下的淘寶、天貓等電商平臺的數據庫連接管理。
  • 京東 : 在京東的電商平臺中,Druid 用于處理高并發的讀寫請求,提升系統性能和穩定性。
  • 美團點評 : 在美團點評的各個業務線中,Druid 用于提高數據庫的響應速度和吞吐量,特別是在高并發場景下的表現。
  • 小米 : 在小米的電商平臺和其他業務系統中,Druid 用于高效地管理數據庫連接,確保系統的穩定性和性能。
  • 去哪兒網 : 在去哪兒網的業務系統中,Druid 用于處理大量的用戶請求,提高數據庫的并發處理能力。
  • 攜程旅行網 : 在攜程的電商平臺中,Druid 用于管理和優化數據庫連接,支持高并發的讀寫操作。
  • 知乎 : 在知乎的系統中,Druid 用于管理和優化數據庫連接,支持高并發的讀寫操作,確保系統的穩定性和性能。
  • 拼多多 : 在拼多多的系統中,Druid 用于管理和優化數據庫連接,支持高并發的讀寫操作,確保系統的穩定性和性能。

代碼實操

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MyBatis Plus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
    </dependency>

    <!-- Druid -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.8</version>
    </dependency>

    <!-- MySQL Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

application.yml

server:
  port:8080

spring:
datasource:
    type:com.alibaba.druid.pool.DruidDataSource
    druid:
      master:
        url:jdbc:mysql://localhost:3306/master_db?useSSL=false&serverTimezone=UTC
        username:root
        password:root
      slave:
        url:jdbc:mysql://localhost:3307/slave_db?useSSL=false&serverTimezone=UTC
        username:root
        password:root

mybatis-plus:
configuration:
    log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations:classpath*:mybatis-mapper.xml

動態數據源上下文持有者

package com.example.demo.config;

publicclass DynamicDataSourceContextHolder {
    privatestaticfinal ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setDataSourceType(String dataSourceType) {
        contextHolder.set(dataSourceType);
    }

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

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

數據源配置

package com.example.demo.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
publicclass DataSourceConfig {

    @Value("${spring.datasource.druid.master.url}")
    private String masterUrl;

    @Value("${spring.datasource.druid.master.username}")
    private String masterUsername;

    @Value("${spring.datasource.druid.master.password}")
    private String masterPassword;

    @Value("${spring.datasource.druid.slave.url}")
    private String slaveUrl;

    @Value("${spring.datasource.druid.slave.username}")
    private String slaveUsername;

    @Value("${spring.datasource.druid.slave.password}")
    private String slavePassword;

    @Bean
    public DataSource dynamicDataSource() {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", masterDataSource());
        targetDataSources.put("slave", slaveDataSource());

        AbstractRoutingDataSource abstractRoutingDataSource = new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                return DynamicDataSourceContextHolder.getDataSourceType();
            }
        };
        abstractRoutingDataSource.setDefaultTargetDataSource(masterDataSource());
        abstractRoutingDataSource.setTargetDataSources(targetDataSources);

        return abstractRoutingDataSource;
    }

    @Bean
    public DataSource masterDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(masterUrl);
        dataSource.setUsername(masterUsername);
        dataSource.setPassword(masterPassword);
        return dataSource;
    }

    @Bean
    public DataSource slaveDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(slaveUrl);
        dataSource.setUsername(slaveUsername);
        dataSource.setPassword(slavePassword);
        return dataSource;
    }
}

實體類

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

@TableName("product")
publicclass Product {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Double price;

    // getters and setters
}

Mapper接口

package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.Product;

public interface ProductMapper extends BaseMapper<Product> {
}

mybatis-mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ProductMapper">

    <select id="selectById" resultType="com.example.demo.entity.Product">
        SELECT * FROM product WHERE id = #{id}
    </select>

    <insert id="insert" parameterType="com.example.demo.entity.Product">
        INSERT INTO product (name, price) VALUES (#{name}, #{price})
    </insert>

</mapper>

Service接口

package com.example.demo.service;

import com.example.demo.entity.Product;

public interface ProductService {
    Product getProductById(Long id);
    boolean saveProduct(Product product);
}

Service

package com.example.demo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.config.DynamicDataSourceContextHolder;
import com.example.demo.entity.Product;
import com.example.demo.mapper.ProductMapper;
import com.example.demo.service.ProductService;
import org.springframework.stereotype.Service;

@Service
publicclass ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    @Override
    public Product getProductById(Long id) {
        DynamicDataSourceContextHolder.setDataSourceType("slave");
        try {
            return getById(id);
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    @Override
    public boolean saveProduct(Product product) {
        DynamicDataSourceContextHolder.setDataSourceType("master");
        try {
            return save(product);
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }
}

Controller

package com.example.demo.controller;

import com.example.demo.entity.Product;
import com.example.demo.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/products")
publicclass ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return productService.getProductById(id);
    }

    @PostMapping("/")
    public boolean addProduct(@RequestBody Product product) {
        return productService.saveProduct(product);
    }
}

Application

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

測試

添加產品

curl -X POST http://localhost:8080/products/ \
     -H "Content-Type: application/json" \
     -d '{"name": "Sample Product", "price": 99.99}'

Respons

true

獲取產品

curl -X GET http://localhost:8080/products/1

Respons

{"id":1,"name":"Sample Product","price":99.99}


責任編輯:武曉燕 來源: Java知識日歷
相關推薦

2025-04-01 08:38:41

2025-04-18 08:54:30

2025-05-16 08:55:58

2025-03-26 08:43:17

2010-06-09 14:04:34

MySQL數據庫

2025-06-03 02:10:00

SpringInfluxDB數據

2018-08-02 10:14:49

服務器數據庫主從同步

2010-09-01 10:05:32

MySQL

2025-04-23 08:50:00

SpringBootCurator分布式鎖

2012-11-26 10:17:44

InnoDB

2025-04-29 08:36:28

SpringCanal數據庫

2010-06-02 16:57:50

MySQL數據庫同步

2025-05-09 08:34:57

RSocketSpringBoot聊天系統

2025-03-31 08:43:34

SpringTika優化

2025-05-06 08:40:21

SpringPostGIS系統

2025-03-03 07:30:00

SpringBootJGraphT網絡建模

2025-02-28 08:40:28

ZooKeeperSpringBoot計費系統

2025-04-08 08:50:37

SpringCamel系統

2010-11-03 08:41:55

MySQL

2025-03-05 08:37:05

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品免费 | 日韩一区中文字幕 | 亚洲欧美在线免费观看 | 99免费精品 | 毛片一级黄色 | 亚洲精品久久国产高清情趣图文 | 欧美精品一区二区三区四区 在线 | 自拍视频国产 | 亚洲码欧美码一区二区三区 | 欧美精品一区二区三区在线 | 亚洲视频免费在线播放 | 天天干夜夜操 | 欧美精品一区二区三区在线播放 | 欧美一级免费看 | 亚洲一区中文字幕 | 羞羞视频网站免费看 | 九九热国产精品视频 | 成人亚洲性情网站www在线观看 | 日韩成人免费视频 | 精品一区二区三区免费视频 | 欧美日韩亚洲国产 | 妹子干综合 | 欧美日本高清 | 国产精品久久视频 | 久久久精品一区二区三区 | 一区二区免费 | 国产免费视频 | 99久久精品国产一区二区三区 | 午夜久久久 | 成人免费在线 | 国产欧美日韩精品一区二区三区 | 国产亚洲精品精品国产亚洲综合 | 国产精品精品视频一区二区三区 | www.色.com | 欧美日韩一区二区三区视频 | 免费精品在线视频 | 欧美日韩高清一区二区三区 | 久久蜜桃av一区二区天堂 | 成人性生交a做片 | 91免费视频 | 国产精品视频网 |