自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot與Druid整合,實現(xiàn)電商主從數(shù)據(jù)庫同步系統(tǒng)

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

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

我們?yōu)槭裁催x擇Druid?

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

哪些公司在使用Druid?

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

代碼實操

<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

動態(tài)數(shù)據(jù)源上下文持有者

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();
    }
}

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

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);
    }
}

測試

添加產(chǎn)品

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

Respons

true

獲取產(chǎn)品

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

Respons

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


責(zé)任編輯:武曉燕 來源: Java知識日歷
相關(guān)推薦

2025-04-01 08:38:41

2025-04-18 08:54:30

2025-03-26 08:43:17

2010-06-09 14:04:34

MySQL數(shù)據(jù)庫

2018-08-02 10:14:49

服務(wù)器數(shù)據(jù)庫主從同步

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數(shù)據(jù)庫

2010-06-02 16:57:50

MySQL數(shù)據(jù)庫同步

2025-03-03 07:30:00

SpringBootJGraphT網(wǎng)絡(luò)建模

2025-03-31 08:43:34

SpringTika優(yōu)化

2025-04-08 08:50:37

SpringCamel系統(tǒng)

2025-02-28 08:40:28

ZooKeeperSpringBoot計費系統(tǒng)

2010-11-03 08:41:55

MySQL

2024-12-06 08:29:29

2025-03-05 08:37:05

2010-06-09 15:01:18

MySQL數(shù)據(jù)庫同步

2010-06-09 17:36:45

MySQL數(shù)據(jù)庫同步

2010-08-27 09:59:51

SQL Server
點贊
收藏

51CTO技術(shù)棧公眾號