HikariCP 是目前最高效的 JDBC 连接池,能够显著提升应用程序的性能和响应速度。

我们为什么选择HikariCP?

  • 低延迟:HikariCP 在基准测试中表现优异,通常比其他流行的连接池(如 C3P0、DBCP)快得多。

  • 优化的锁机制:通过减少不必要的同步操作和优化锁机制,HikariCP 提供了更快的连接获取和释放速度。

  • 高效资源管理:HikariCP 使用较少的内存来维护连接池,减少了垃圾回收的压力。

  • 最少的对象和线程:内部使用少量的对象和线程,避免过多的上下文切换,从而提高整体性能。

  • 简单直观:提供了简单且直观的配置选项,大多数情况下默认配置已经足够使用。

  • 多种配置方式:支持属性文件、Java 配置类等多种配置方式,灵活适应不同的需求。

  • 兼容性强:可以与各种关系型数据库一起使用,包括 MySQL、PostgreSQL、Oracle 等。

  • 健康检查:能够自动检测并移除死连接,确保连接池中的连接始终有效。

  • 定期验证:通过定期检查和验证连接的有效性来维护连接池的状态。

  • 灵活性:允许动态调整连接池的大小和其他参数,满足不同应用场景的需求。

  • API支持:提供了丰富的 API 和回调机制,便于开发者进行定制化配置。

  • 无缝集成:SpringBoot默认使用HikariCP作为其内置的连接池实现,无需额外配置即可使用。

哪些公司使用了HikariCP?

  • Twitter在其推文发布和检索系统中使用 HikariCP 来管理数据库连接,支持大量的用户互动。

  • Uber在其调度系统和订单管理系统中使用 HikariCP 来管理数据库连接,确保实时性和可靠性。

  • eBay在其电子商务平台上使用 HikariCP 来管理数据库连接,支持高并发的用户请求。

  • Salesforce在其销售自动化和客户服务系统中使用 HikariCP 来管理数据库连接。

  • Microsoft Azure在其各种云服务中使用 HikariCP 来管理数据库连接,提供高效的数据处理能力。

  • IBM在其内部应用和云计算服务中使用 HikariCP 来管理数据库连接。

  • Spotify 是全球领先的音乐流媒体服务。用HikariCP优化其后端服务的数据库连接管理,支持高并发用户请求。

  • Square在其支付系统中使用HikariCP来管理数据库连接,确保交易的高效处理。

  • LinkedIn用于其庞大的用户数据管理和推荐系统中的数据库连接池。

  • Airbnb在其复杂的后端系统中使用 HikariCP 来管理数据库连接,确保用户体验的流畅性。

  • Dropbox在其文件管理系统中使用 HikariCP 来管理数据库连接,支持大量用户的文件操作。

  • Craigslist 是全球最大的分类广告网站,在其广告发布和搜索系统中使用 HikariCP 来管理数据库连接,支持大量的用户访问。

代码实操

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/><!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dynamic-hikaricp-config</name>
    <description>Demo project for Spring Boot with dynamic HikariCP configuration</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/ecommerce
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

配置HikariCP数据源

package com.example.demo.config;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    @Bean
    public DataSource dataSource() {
        // 创建HikariConfig实例
        HikariConfig config = new HikariConfig();
        // 设置JDBC URL
        config.setJdbcUrl("jdbc:mysql://localhost:3306/ecommerce");
        // 设置数据库用户名
        config.setUsername("root");
        // 设置数据库密码
        config.setPassword("password");
        // 启用预编译语句缓存
        config.addDataSourceProperty("cachePrepStmts", "true");
        // 设置预编译语句缓存大小
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        // 设置每个连接的最大预编译语句数量
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        // 返回HikariDataSource实例
        return new HikariDataSource(config);
    }
}

处理与产品的REST请求

package com.example.demo.controller;

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

import java.util.List;

@RestController
@RequestMapping("/api/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    // 获取所有产品
    @GetMapping
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }

    // 创建新产品
    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productService.createProduct(product);
    }

    // 根据ID获取单个产品
    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        return productService.getProductById(id);
    }

    // 更新产品信息
    @PutMapping("/{id}")
    public Product updateProduct(@PathVariable Long id, @RequestBody Product productDetails) {
        return productService.updateProduct(id, productDetails);
    }

    // 删除产品
    @DeleteMapping("/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
    }
}

用于动态调整HikariCP配置

package com.example.demo.controller;

import com.example.demo.service.HikariConfigService;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/api/config")
public class HikariConfigController {

    @Autowired
    private HikariConfigService hikariConfigService;

    // 获取当前HikariCP配置
    @GetMapping
    public String getConfig() {
        HikariDataSource dataSource = hikariConfigService.getDataSource();
        return"Current configuration: maxPoolSize=" + dataSource.getMaximumPoolSize() +
                ", connectionTimeout=" + dataSource.getConnectionTimeout();
    }

    // 设置最大连接数
    @PostMapping("/maxPoolSize/{size}")
    public String setMaxPoolSize(@PathVariable int size) {
        if (size > 0) {
            hikariConfigService.setMaxPoolSize(size);
            return"Updated maxPoolSize to " + size;
        } else {
            return"Invalid size";
        }
    }

    // 设置连接超时时间
    @PostMapping("/connectionTimeout/{timeout}")
    public String setConnectionTimeout(@PathVariable long timeout) {
        if (timeout >= 0) {
            hikariConfigService.setConnectionTimeout(timeout);
            return"Updated connectionTimeout to " + timeout + "ms";
        } else {
            return"Invalid timeout";
        }
    }
}

产品实体类

package com.example.demo.model;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 产品ID
    private String name; // 产品名称
    private double price; // 产品价格
    private String description; // 产品描述
}

订单实体类

package com.example.demo.model;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;


@Data
@Entity
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 订单ID
    private Long productId; // 关联的产品ID
    private int quantity; // 订单数量
    private double totalAmount; // 总金额
}

Product Repository

package com.example.demo.repository;

import com.example.demo.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product, Long> {
}

Order Repository

package com.example.demo.repository;

import com.example.demo.model.Order;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long> {
}

Product Service

package com.example.demo.service;

import com.example.demo.model.Product;
import com.example.demo.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    // 获取所有产品
    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }

    // 创建新产品
    public Product createProduct(Product product) {
        return productRepository.save(product);
    }

    // 根据ID获取单个产品
    public Product getProductById(Long id) {
        return productRepository.findById(id).orElse(null);
    }

    // 更新产品信息
    public Product updateProduct(Long id, Product productDetails) {
        Product product = productRepository.findById(id).orElseThrow(() -> new RuntimeException("Product not found"));
        product.setName(productDetails.getName());
        product.setPrice(productDetails.getPrice());
        product.setDescription(productDetails.getDescription());
        return productRepository.save(product);
    }

    // 删除产品
    public void deleteProduct(Long id) {
        productRepository.deleteById(id);
    }
}

管理HikariCP配置的服务层

package com.example.demo.service;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class HikariConfigService {

    @Autowired
    private HikariDataSource dataSource;

    // 获取HikariDataSource实例
    public HikariDataSource getDataSource() {
        return dataSource;
    }

    // 设置最大连接数
    public void setMaxPoolSize(int size) {
        dataSource.setMaximumPoolSize(size);
    }

    // 设置连接超时时间
    public void setConnectionTimeout(long timeout) {
        dataSource.setConnectionTimeout(timeout);
    }
}

Application

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

测试

设置最大连接数

curl -X POST http://localhost:8080/api/config/maxPoolSize/20

Respons:

Updated maxPoolSize to 20

设置连接超时时间

curl -X POST http://localhost:8080/api/config/connectionTimeout/30000

Respons:

Updated connectionTimeout to 30000ms

关注我,送Java福利

/**
 * 这段代码只有Java开发者才能看得懂!
 * 关注我微信公众号之后,
 * 发送:"666",
 * 即可获得一本由Java大神一手面试经验诚意出品
 * 《Java开发者面试百宝书》Pdf电子书
 * 福利截止日期为2025年02月28日止
 * 手快有手慢没!!!
*/
System.out.println("请关注我的微信公众号:");
System.out.println("Java知识日历");
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐