ฉันจะกำหนดค่า HikariCP ในแอป Spring Boot ในไฟล์ application.properties ได้อย่างไร


92

ฉันกำลังพยายามตั้งค่า HikariCP ในแอป Spring Boot (1.2.0.M1) ของฉันดังนั้นฉันจึงสามารถทดสอบใช้แทน Tomcat DBCP ได้ ฉันต้องการกำหนดค่าพูลการเชื่อมต่อในไฟล์ application.properties เหมือนที่ทำกับ Tomcat แต่ฉันคิดไม่ออกว่าควรทำอย่างไร ตัวอย่างทั้งหมดที่ฉันพบแสดงสไตล์ JavaConfig หรือใช้ไฟล์คุณสมบัติ HikariCP แยกต่างหาก ใครสามารถช่วยฉันหาชื่อคุณสมบัติเพื่อกำหนดค่าใน application.properties ฉันต้องการเปลี่ยนจากการใช้แนวทาง driverClassName เป็นแนวทาง DataSourceClassName เนื่องจากดูสะอาดกว่าและขอแนะนำ เป็นไปได้ในไฟล์ application.properties ของฉันหรือไม่

นี่คือสิ่งที่ฉันมีสำหรับ Tomcat DBCP (มีเพียงการกำหนดค่าพื้นฐานบางอย่างไม่ได้ล้างออกทั้งหมด)

spring.datasource.validation-query=SELECT 1
spring.datasource.max-active=10
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=5
spring.datasource.test-on-borrow=true
spring.datasource.test-on-return=true

และฉันกำลังใช้ driverClassName และ jdbc url เพื่อตั้งค่าการเชื่อมต่อ:

spring.datasource.url=jdbc:mysql://localhost:3306/myDb
spring.datasource.driverClassName=com.mysql.jdbc.Driver

คุณใช้ Spring Boot รุ่นใดอยู่
geoand

1.2.0.M1 ฉันคิดว่าฉันอาจหาวิธีตั้งค่าคุณสมบัติเพื่อตั้งค่าสิ่งต่างๆเช่น maximumPoolSize สำหรับ hikariCP แต่ฉันไม่สามารถรับการกำหนดค่าที่ทำงานโดยใช้วิธีที่ hikariCP แนะนำโดยใช้ dataSourceClassName และ serverName แทน driverClassName และ jdbc url ผมจึงยอมแพ้ในส่วนนั้น หากมีใครสามารถคิดส่วนนั้นได้นั่นจะช่วยได้
Kevin M

ฉันจะลอง 1.2.0.M1 ในภายหลังและฉันจะพบสิ่งที่ฉันจะโพสต์
geoand

2
คุณไม่สามารถใช้แนวทาง dataSourceClassName กับการกำหนดค่าอัตโนมัติของแหล่งข้อมูลของ Spring Boot ได้เนื่องจากต้องตั้งค่า spring.datasource.url โปรดทราบว่าคุณไม่จำเป็นต้องระบุ driverClassName เนื่องจาก Boot จะอนุมานจาก jdbcUrl
Andy Wilkinson

1
application.properties spring.datasource.hikari.*
:,

คำตอบ:


142
@Configuration
@ConfigurationProperties(prefix = "params.datasource")
public class JpaConfig extends HikariConfig {

    @Bean
    public DataSource dataSource() throws SQLException {
        return new HikariDataSource(this);
    }

}

application.yml

params:
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/myDb
    username: login
    password: password
    maximumPoolSize: 5

อัพเดท! ตั้งแต่เวอร์ชัน Spring Boot 1.3.0 :

  1. เพียงเพิ่ม HikariCP ในการอ้างอิง
  2. กำหนดค่า application.yml

application.yml

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:h2:mem:TEST
    driver-class-name: org.h2.Driver
    username: username
    password: password
    hikari:
      idle-timeout: 10000

อัพเดท! ตั้งแต่เวอร์ชัน Spring Boot 2.0.0 :

พูลการเชื่อมต่อเริ่มต้นเปลี่ยนจาก Tomcat เป็น Hikari :)


1
ฉันคิดว่านี่เป็นแนวทางที่ดีกว่าและพกพาสะดวกกว่ามาก ไชโย!
Jesús Zazueta

2
สิ่งนี้สามารถใช้สำหรับการกำหนดค่าสปริงมาตรฐานได้เช่นกัน แต่สิ่งหนึ่งที่สำคัญคือ Hikari ใช้ url ของแหล่งข้อมูลผ่าน jdbcUrl แต่สปริงผ่าน url {สตริงส่วนตัว url; @Bean สาธารณะ DataSource dataSource () พ่น SQLException {ส่งคืน HikariDataSource ใหม่ (นี้); } getUrl String สาธารณะ () {return url; } โมฆะสาธารณะ setUrl (สตริง url) {this.url = url; // HikariConfig ถือ JDBC-URL ในคุณสมบัติ jdbcUrl แต่ spring จัดเตรียมคุณสมบัตินี้เป็น url this.setJdbcUrl (url); }}
Tomas Hanus

ขออภัยที่ตอบช้าไปหน่อย แต่โซลูชัน @Sergey ควรเปลี่ยนเล็กน้อยเพื่อให้ได้คุณสมบัติทั้งหมด หากต้องการรับคุณสมบัติ DS เฉพาะของ hikari คุณต้องตั้งค่าคีย์เป็น "spring.datasource. dataSourceProperties" แทน "spring.datasource.hikari"
bluelabel

3
ก่อนหน้านี้เราต้องดูว่ามีการกำหนดค่าอย่างไรโดยดูที่เอกสารของแหล่งข้อมูลตอนนี้มันแย่ลงตอนนี้เราต้องรู้ว่ามีการกำหนดค่าอย่างไรเมื่อใช้ Spring Boot ฉันไม่เห็นว่าการกำหนดค่าอัตโนมัตินี้ช่วยเราได้จริงๆ
supertonsky

31

ฉันพบHikariCPและรู้สึกประหลาดใจกับเกณฑ์มาตรฐานและฉันต้องการลองใช้แทนตัวเลือกเริ่มต้นของฉันC3P0และฉันประหลาดใจที่ฉันพยายามดิ้นรนเพื่อให้ได้สิ่งที่configurationsถูกต้องอาจเป็นเพราะการกำหนดค่าแตกต่างกันไปขึ้นอยู่กับการผสมผสานของเทคโนโลยีที่คุณใช้

ฉันมีการตั้งค่าSpring Bootโปรเจ็กต์พร้อมJPA, Web, Securitystarters (โดยใช้Spring Initializer ) เพื่อใช้PostgreSQLเป็นฐานข้อมูลพร้อมกับHikariCPการเชื่อมต่อ
ฉันใช้Gradleเป็นเครื่องมือสร้างและฉันต้องการแบ่งปันสิ่งที่ได้ผลสำหรับฉันสำหรับสมมติฐานต่อไปนี้:

  1. Spring Boot Starter JPA (เว็บและความปลอดภัย - ทางเลือก)
  2. สร้าง Gradle ด้วย
  3. PostgreSQL ทำงานและตั้งค่าด้วยฐานข้อมูล (เช่น schema, user, db)

คุณต้องมีสิ่งต่อไปนี้build.gradleหากคุณใช้Gradleหรือเทียบเท่าpom.xmlหากคุณใช้ maven

buildscript {
    ext {
        springBootVersion = '1.5.8.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'

group = 'com'
version = '1.0'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-aop')

    // Exclude the tomcat-jdbc since it's used as default for connection pooling
    // This can also be achieved by setting the spring.datasource.type to HikariCP 
    // datasource see application.properties below
    compile('org.springframework.boot:spring-boot-starter-data-jpa') {
        exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc'
    }
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime('org.postgresql:postgresql')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.security:spring-security-test')

    // Download HikariCP but, exclude hibernate-core to avoid version conflicts
    compile('com.zaxxer:HikariCP:2.5.1') {
        exclude group: 'org.hibernate', module: 'hibernate-core'
    }

    // Need this in order to get the HikariCPConnectionProvider
    compile('org.hibernate:hibernate-hikaricp:5.2.11.Final') {
        exclude group: 'com.zaxxer', module: 'HikariCP'
        exclude group: 'org.hibernate', module: 'hibernate-core'
    }
}

มีข้อยกเว้นมากมายในด้านบนbuild.gradleและนั่นเป็นเพราะ

  1. ก่อนอื่นให้ยกเว้นคำสั่งให้ gradle ที่ไม่รวมjdbc-tomcatพูลการเชื่อมต่อเมื่อดาวน์โหลดการspring-boot-starter-data-jpaอ้างอิง สิ่งนี้สามารถทำได้โดยการตั้งค่าspring.datasource.type=com.zaxxer.hikari.HikariDataSourceแต่ฉันไม่ต้องการการพึ่งพาเพิ่มเติมหากฉันไม่ต้องการ
  2. การยกเว้นครั้งที่สองสั่งให้ gradle ยกเว้นhibernate-coreเมื่อดาวน์โหลดการcom.zaxxerอ้างอิงและนั่นเป็นเพราะhibernate-coreดาวน์โหลดแล้วSpring Bootและเราไม่ต้องการลงเอยด้วยเวอร์ชันที่แตกต่างกัน
  3. การยกเว้นประการที่สามสั่งให้ gradle ยกเว้นhibernate-coreเมื่อดาวน์โหลดhibernate-hikaricpโมดูลที่จำเป็นเพื่อให้ HikariCP ใช้org.hibernate.hikaricp.internal.HikariCPConnectionProviderเป็นผู้ให้บริการการเชื่อมต่อแทนการเลิกใช้งานcom.zaxxer.hikari.hibernate.HikariConnectionProvider

เมื่อฉันรู้build.gradleและสิ่งที่ควรเก็บและสิ่งที่ไม่ควรทำฉันก็พร้อมที่จะคัดลอก / วางการdatasourceกำหนดค่าลงในของฉันapplication.propertiesและคาดว่าทุกอย่างจะทำงานกับสีที่บินได้ แต่ไม่จริงและฉันก็สะดุดกับปัญหาต่อไปนี้

  • Spring boot ไม่สามารถค้นหารายละเอียดฐานข้อมูล (เช่น url, ไดรเวอร์) ดังนั้นจึงไม่สามารถตั้งค่า jpa และ hibernate ได้ (เพราะฉันไม่ได้ตั้งชื่อค่าคีย์คุณสมบัติถูกต้อง)
  • HikariCP ถอยกลับไป com.zaxxer.hikari.hibernate.HikariConnectionProvider
  • หลังจากสอนฤดูใบไม้ผลิที่จะใช้การเชื่อมต่อให้บริการใหม่เมื่ออัตโนมัติกำหนดค่าจำศีล / JPA แล้ว HikariCP ล้มเหลวเนื่องจากมันถูกมองหาบางอย่างkey/valueในและได้รับการร้องเรียนเกี่ยวกับapplication.properties dataSource, dataSourceClassName, jdbcUrlฉันต้องดีบักHikariConfig, HikariConfigurationUtil, HikariCPConnectionProviderและพบว่าHikariCPไม่สามารถหาคุณสมบัติจากapplication.propertiesเพราะมันมีชื่อแตกต่างกัน

อย่างไรก็ตามนี่คือที่ที่ฉันต้องพึ่งพาการลองผิดลองถูกและตรวจสอบให้แน่ใจว่าHikariCPสามารถเลือกคุณสมบัติ (เช่นแหล่งข้อมูลที่มีรายละเอียดฐานข้อมูลรวมถึงคุณสมบัติการรวมกัน) รวมถึง Sping Boot ทำงานตามที่คาดไว้และฉันก็จบลงด้วยapplication.propertiesไฟล์ต่อไปนี้

server.contextPath=/
debug=true

# Spring data source needed for Spring boot to behave
# Pre Spring Boot v2.0.0.M6 without below Spring Boot defaults to tomcat-jdbc connection pool included 
# in spring-boot-starter-jdbc and as compiled dependency under spring-boot-starter-data-jpa
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:postgresql://localhost:5432/somedb
spring.datasource.username=dbuser
spring.datasource.password=dbpassword

# Hikari will use the above plus the following to setup connection pooling
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000

# Without below HikariCP uses deprecated com.zaxxer.hikari.hibernate.HikariConnectionProvider
# Surprisingly enough below ConnectionProvider is in hibernate-hikaricp dependency and not hibernate-core
# So you need to pull that dependency but, make sure to exclude it's transitive dependencies or you will end up 
# with different versions of hibernate-core 
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider

# JPA specific configs
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql=true
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.default_schema=dbschema
spring.jpa.properties.hibernate.search.autoregister_listeners=false
spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false

# Enable logging to verify that HikariCP is used, the second entry is specific to HikariCP
logging.level.org.hibernate.SQL=DEBUG
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE 

ดังที่แสดงไว้ด้านบนการกำหนดค่าจะแบ่งออกเป็นหมวดหมู่ตามรูปแบบการตั้งชื่อต่อไปนี้

  • spring.datasource.x (การกำหนดค่าอัตโนมัติของ Spring จะเลือกสิ่งเหล่านี้ดังนั้น HikariCP จะ)
  • spring.datasource.hikari.x (HikariCP เลือกสิ่งเหล่านี้เพื่อตั้งค่าพูลจดชื่อฟิลด์ camelCase)
  • spring.jpa.hibernate.connection.provider_class (สั่งให้ Spring ใช้ HibernateConnectionProvider ใหม่)
  • spring.jpa.properties.hibernate.x (ใช้โดย Spring เพื่อกำหนดค่า JPA อัตโนมัติจดชื่อฟิลด์พร้อมขีดล่าง)

เป็นการยากที่จะเจอบทช่วยสอนหรือโพสต์หรือแหล่งข้อมูลบางอย่างที่แสดงวิธีใช้ไฟล์คุณสมบัติข้างต้นและวิธีตั้งชื่อคุณสมบัติ คุณมีแล้ว

การโยนข้างต้นapplication.propertiesด้วยbuild.gradle(หรืออย่างน้อยก็คล้ายกัน) ลงในเวอร์ชันโครงการ Spring Boot JPA (1.5.8) ควรใช้งานได้ดีและเชื่อมต่อกับฐานข้อมูลที่กำหนดไว้ล่วงหน้าของคุณ (เช่นในกรณีของฉันคือ PostgreSQL ที่ทั้งHikariCP & Springคู่คิดออกจากสิ่งspring.datasource.urlที่ โปรแกรมควบคุมฐานข้อมูลที่จะใช้)

ฉันไม่เห็นความจำเป็นในการสร้างDataSourcebean และนั่นเป็นเพราะ Spring Boot สามารถทำทุกอย่างให้ฉันได้เพียงแค่มองเข้าไปapplication.propertiesและมันก็เรียบร้อย

บทความใน HikariCP ของ GitHub วิกิพีเดียที่แสดงให้เห็นวิธีการติดตั้งสปริง Boot กับ JPA แต่ขาดคำอธิบายและรายละเอียด

ไฟล์สองไฟล์ข้างต้นยังมีให้ใช้งานในรูปแบบสาธารณะhttps://gist.github.com/rhamedy/b3cb936061cc03acdfe21358b86a5bc6


ฉันกำลังดิ้นรนกับสิ่งนี้ก่อนที่คุณจะโพสต์ ขอบคุณ!
Bogdan Pușcașu

ดีใจที่ช่วยคุณได้! 👍
Raf

Raf คุณมีคำตอบที่ยอดเยี่ยม ฉันอยากรู้ว่าคุณจะโพสต์การเปลี่ยนแปลงที่จำเป็นสำหรับ Spring Boot 2.0.0.M6 ได้หรือไม่ กำลังดิ้นรนกับการกำหนดค่าไม่ได้รับและคู่มือการย้ายข้อมูลยังไม่ได้รับการอัปเดต
Matthew Fontana

สวัสดีจ้าฉันใช้รุ่น 1.5.8 เมื่อฉันแบ่งปันวิธีแก้ปัญหาของฉันที่นี่ ฉันต้องการลอง 2.0.0.M6 อย่างรวดเร็ว แต่น่าเสียดายที่พวกเขาต้องการให้คุณมี gradle เวอร์ชันที่สูงกว่า การเปลี่ยนแปลงเดียวที่ฉันจำได้ใน 2.0.0.M6 คือการทำให้การเชื่อมต่อเริ่มต้น HikariCP รวมกันสำหรับ spring jpa ดูที่นี่github.com/spring-projects/spring-boot/commit/… ลองดีบั๊ก HikariConfig, HikariConfigurationUtil, HikariCPConnectionProvider เพื่อให้แน่ใจว่า คุณสมบัติถูกหยิบขึ้นมา
Raf

26

คุณสามารถใช้ประโยชน์จาก application.yml / application.properties เท่านั้น ไม่จำเป็นต้องสร้างDataSourceBean อย่างชัดเจน

คุณต้องยกเว้น tomcat-jdbc ตามที่ ydemartino กล่าวไว้

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

เนื่องจากคุณจะไม่สร้างDataSourcebean คุณต้องระบุอย่างชัดเจนโดยใช้ Hikari through spring.datasource.typeด้วยค่าcom.zaxxer.hikari.HikariDataSourceใน application.yml / application.properties

spring:
    datasource:
        hikari:
            connection-test-query: SELECT 1 FROM DUAL
            minimum-idle: 1
            maximum-pool-size: 5
            pool-name: yourPoolName
            auto-commit: false
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/myDb
        username: login
        password: password
        type: com.zaxxer.hikari.HikariDataSource

ใน application.yml / application.properties ของคุณคุณสามารถกำหนดค่าพารามิเตอร์เฉพาะของ Hikari เช่นขนาดพูลเป็นต้นใน spring.datasource.hikari.*


คุณไม่จำเป็นต้องยกเว้น Tomcat เพื่อทำงานนี้เพิ่มspring.datasource.typeก็เพียงพอแล้ว
Michael Piefel

3
@MichaelPiefel คุณต้องทำการยกเว้น javadoc ของDataSourceBuilderกล่าวว่า: ถ้า Tomcat, HikariCP หรือ Commons DBCP อยู่บน classpath หนึ่งในนั้นจะถูกเลือก (ตามลำดับนั้นกับ Tomcat ก่อน) การทดสอบของฉันยืนยันสิ่งนี้
ม.ค. Bodnar

1
@JanBodnar: DataSourceConfigurationซึ่งใช้ในการกำหนดค่าอัตโนมัติมีการกำหนดค่าขึ้นอยู่กับspring.datasource.typeว่ามีการตั้งค่าไว้หรือไม่ ดังนั้นฉันมีtomcat-jdbcใน classpath ของฉันและยังคงใช้ HikariCP เป็นพูลของฉัน การทดสอบของฉันยืนยันสิ่งนี้ บางทีเรากำลังพูดถึง Spring Boot เวอร์ชันที่แตกต่างกันมากที่นี่
Michael Piefel

1
@MichaelPiefel ที่น่าสนใจฉันสามารถเรียกใช้งานได้โดยไม่ต้องยกเว้นด้วยการกำหนดค่า Java โดยใช้ DataSourceBuilder.create () ... type (com.zaxxer.hikari.HikariDataSource.class) ด้วยการกำหนดค่าในไฟล์ yaml มันไม่ได้ผลสำหรับฉัน จึงต้องมีการจับบ้าง
ม.ค. Bodnar

14

ฉันใช้ Spring Boot 2.0.4 รีลีส Hikari เป็นพูลการเชื่อมต่อเริ่มต้นและ.hikariไม่จำเป็นอีกต่อไป

application.properties

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.jdbcUrl=jdbc:mysql://localhost:3306/myDB...
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.poolname=myPool

application.yml

spring:
    datasource:
        driverClassName: com.mysql.jdbc.Driver
        jdbcUrl: jdbc:mysql://localhost:3306/myDB...
        username: xxx
        password: xxx
        poolName: myPool

และconfigurationไม่จำเป็นต้องขยายHikariConfigและDataSourceBuilderสามารถใช้งานได้เหมือนเดิม

@Configuration
public class DataSourceConfiguration {

    @Bean(name="myDataSource")
    @ConfigurationProperties("spring.datasource")
    public DataSource myDataSource() {
        return DataSourceBuilder.create().build();
    }
}

10

ตามเอกสารมีการเปลี่ยนแปลง

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html

ตัวอย่าง:

spring:
    datasource:
        url: 'jdbc:mysql://localhost/db?useSSL=false'
        username: root
        password: pass
        driver: com.mysql.jdbc.Driver
        hikari:
            minIdle: 10
            idle-timeout: 10000
            maximumPoolSize: 30

นี่คือการเปลี่ยนแปลงการกำหนดค่าต่อไปนี้ที่เราสามารถทำได้ใน hikari โปรดเพิ่ม / อัปเดตตามความต้องการของคุณ

autoCommit
connectionTimeout
idleTimeout
maxLifetime
connectionTestQuery
connectionInitSql
validationTimeout
maximumPoolSize
poolName
allowPoolSuspension
readOnly
transactionIsolation
leakDetectionThreshold

9

คุณไม่จำเป็นต้องใช้รหัสซ้ำซ้อนในการใส่ค่าคุณสมบัติให้กับตัวแปร คุณสามารถตั้งค่าคุณสมบัติด้วยไฟล์คุณสมบัติได้โดยตรง

ใส่hikari.propertiesไฟล์ใน classpath

driverClassName=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/myDb
connectionTestQuery=SELECT 1
maximumPoolSize=20
username=...
password=...

และสร้าง datasource bean แบบนี้

@Bean(destroyMethod = "close")
public DataSource dataSource() throws SQLException {
    HikariConfig config = new HikariConfig("/hikari.properties");
    HikariDataSource dataSource = new HikariDataSource(config);

    return dataSource;
}

8

สิ่งนี้ใช้ได้กับแอปพลิเคชันบูตของฉันในกรณีที่ช่วยได้ คลาสนี้จะบอกคุณว่าคุณสมบัติใดที่อ็อบเจ็กต์ config กำลังมองหา:

https://github.com/brettwooldridge/HikariCP/blob/2.3.x/hikaricp-common/src/main/java/com/zaxxer/hikari/AbstractHikariConfig.java

ฉันคิดว่าแหล่งข้อมูลหลายแหล่งสามารถรองรับได้โดยการเพิ่มdatasource_whateverลงในคีย์คุณสมบัติในไฟล์กำหนดค่าต้นทาง ไชโย!

@Configuration
class DataSourceConfig {

   @Value('${spring.datasource.username}')
   private String user;

   @Value('${spring.datasource.password}')
   private String password;

   @Value('${spring.datasource.url}')
   private String dataSourceUrl;

   @Value('${spring.datasource.dataSourceClassName}')
   private String dataSourceClassName;

   @Value('${spring.datasource.connectionTimeout}')
   private int connectionTimeout;

   @Value('${spring.datasource.maxLifetime}')
   private int maxLifetime;

   @Bean
   public DataSource primaryDataSource() {
      Properties dsProps = [url: dataSourceUrl, user: user, password: password]
      Properties configProps = [
            connectionTestQuery: 'select 1 from dual',
            connectionTimeout: connectionTimeout,
            dataSourceClassName: dataSourceClassName,
            dataSourceProperties: dsProps,
            maxLifetime: maxLifetime
      ]

      // A default max pool size of 10 seems reasonable for now, so no need to configure for now.
      HikariConfig hc = new HikariConfig(configProps)
      HikariDataSource ds = new HikariDataSource(hc)
      ds
   }
}

มันคือ. มันแปลเป็น Java ได้อย่างง่ายดาย
Jesús Zazueta

ใช่ตอนนี้ฉันรู้ตัวแล้วว่าต้องทำสิ่งนี้เพราะตอนนี้ฉันต้องการกำหนดค่าเมตริก และวิธีเดียวที่ฉันสามารถทำได้คือใช้ JavaConfig นี้เพื่อแทนที่การกำหนดค่าอัตโนมัติ ขอบคุณ.
Kevin M

ใช่มันช่วยได้! คุณได้รับ opvote ของฉันด้วย ... มัน groovie? มันน่าสนใจมากเหมือน javascript :-)
Joao Polo

8

คุณสามารถใช้แนวทาง dataSourceClassName ต่อไปนี้เป็นตัวอย่างกับ MySQL (ทดสอบกับสปริงบูต 1.3 และ 1.4)

ก่อนอื่นคุณต้องแยก tomcat-jdbc ออกจาก classpath เนื่องจากจะถูกเลือกโดย hikaricp

pom.xml

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

application.properties

spring.datasource.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
spring.datasource.dataSourceProperties.serverName=localhost
spring.datasource.dataSourceProperties.portNumber=3311
spring.datasource.dataSourceProperties.databaseName=mydb
spring.datasource.username=root
spring.datasource.password=root

จากนั้นเพิ่ม

@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

ฉันสร้างโครงการทดสอบที่นี่: https://github.com/ydemartino/spring-boot-hikaricp


8

คุณไม่สามารถใช้วิธี dataSourceClassName ในการกำหนดค่า application.properties ตามที่ @Andy Wilkinson กล่าว หากคุณต้องการมี dataSourceClassName อย่างไรก็ตามคุณสามารถใช้ Java Config เป็น:

@Configuration
@ComponentScan
class DataSourceConfig {

 @Value("${spring.datasource.username}")
private String user;

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

@Value("${spring.datasource.url}")
private String dataSourceUrl;

@Value("${spring.datasource.dataSourceClassName}")
private String dataSourceClassName;

@Value("${spring.datasource.poolName}")
private String poolName;

@Value("${spring.datasource.connectionTimeout}")
private int connectionTimeout;

@Value("${spring.datasource.maxLifetime}")
private int maxLifetime;

@Value("${spring.datasource.maximumPoolSize}")
private int maximumPoolSize;

@Value("${spring.datasource.minimumIdle}")
private int minimumIdle;

@Value("${spring.datasource.idleTimeout}")
private int idleTimeout;

@Bean
public DataSource primaryDataSource() {
    Properties dsProps = new Properties();
    dsProps.put("url", dataSourceUrl);
    dsProps.put("user", user);
    dsProps.put("password", password);
    dsProps.put("prepStmtCacheSize",250);
    dsProps.put("prepStmtCacheSqlLimit",2048);
    dsProps.put("cachePrepStmts",Boolean.TRUE);
    dsProps.put("useServerPrepStmts",Boolean.TRUE);

    Properties configProps = new Properties();
       configProps.put("dataSourceClassName", dataSourceClassName);
       configProps.put("poolName",poolName);
       configProps.put("maximumPoolSize",maximumPoolSize);
       configProps.put("minimumIdle",minimumIdle);
       configProps.put("minimumIdle",minimumIdle);
       configProps.put("connectionTimeout", connectionTimeout);
       configProps.put("idleTimeout", idleTimeout);
       configProps.put("dataSourceProperties", dsProps);

   HikariConfig hc = new HikariConfig(configProps);
   HikariDataSource ds = new HikariDataSource(hc);
   return ds;
   }
  } 

เหตุผลที่คุณไม่สามารถใช้ dataSourceClassName ได้เนื่องจากมันจะโยนและยกเว้น

Caused by: java.lang.IllegalStateException: both driverClassName and dataSourceClassName are specified, one or the other should be used.

ซึ่งหมายความว่าสปริงบูตอนุมานจากคุณสมบัติ spring.datasource.url ไดรเวอร์และในเวลาเดียวกันการตั้งค่า dataSourceClassName จะสร้างข้อยกเว้นนี้ เพื่อให้แอปพลิเคชันของคุณถูกต้องคุณสมบัติควรมีลักษณะเช่นนี้สำหรับแหล่งข้อมูล HikariCP:

# hikariCP 
  spring.jpa.databasePlatform=org.hibernate.dialect.MySQLDialect
  spring.datasource.url=jdbc:mysql://localhost:3306/exampledb
  spring.datasource.username=root
  spring.datasource.password=
  spring.datasource.poolName=SpringBootHikariCP
  spring.datasource.maximumPoolSize=5
  spring.datasource.minimumIdle=3
  spring.datasource.maxLifetime=2000000
  spring.datasource.connectionTimeout=30000
  spring.datasource.idleTimeout=30000
  spring.datasource.pool-prepared-statements=true
  spring.datasource.max-open-prepared-statements=250

หมายเหตุ: โปรดตรวจสอบว่ามี tomcat-jdbc.jar หรือ commons-dbcp.jar ใน classpath ของคุณหรือไม่โดยส่วนใหญ่แล้วโดยการพึ่งพาสกรรมกริยา หากมีอยู่ใน classpath Spring Boot จะกำหนดค่า Datasource โดยใช้ default connection pool ซึ่งเป็น tomcat HikariCP จะใช้เพื่อสร้าง Datasource ก็ต่อเมื่อไม่มีผู้ให้บริการรายอื่นใน classpath มีลำดับทางเลือกจาก tomcat -> ถึง HikariCP -> ถึง Commons DBCP


1
สิ่งนี้มีประโยชน์มากแม้ว่าฉันจะต้องหาชื่อคุณสมบัติบางอย่างที่ไม่ได้กล่าวถึงที่นี่เช่น stringType เพื่อกำหนดค่าอุปกรณ์ประกอบฉากแหล่งข้อมูล
comiventor

สิ่งที่ควรรู้มันช่วยได้
Shahid Yousuf

8

สิ่งนี้จะช่วยให้ทุกคนที่ต้องการกำหนดค่า hikaricp สำหรับแอปพลิเคชันของตนด้วยการกำหนดค่าสปริงอัตโนมัติ สำหรับโครงการของฉันฉันใช้ spring boot 2 กับ hikaricp เป็นพูลการเชื่อมต่อ JDBC และ mysql เป็นฐานข้อมูล สิ่งหนึ่งที่ฉันไม่เห็นในคำตอบอื่น ๆ คือสิ่งdata-source-propertiesที่สามารถใช้เพื่อตั้งค่าคุณสมบัติต่างๆที่ไม่มีในspring.datasource.hikari.*เส้นทาง สิ่งนี้เทียบเท่ากับการใช้HikariConfigคลาส ในการกำหนดคอนฟิกแหล่งข้อมูลและพูลการเชื่อมต่อ hikaricp สำหรับคุณสมบัติเฉพาะของ mysql ฉันใช้คำอธิบายประกอบการกำหนดค่า spring auto และคุณสมบัติต่อไปนี้ในไฟล์ application.yml

วาง@EnableAutoConfigurationบนไฟล์ configuration bean ของคุณ

ไฟล์application.ymlมีลักษณะดังนี้

spring:
  datasource:
    url: 'jdbc:mysql://127.0.0.1:3306/DATABASE?autoReconnect=true&useSSL=false'
    username: user_name
    password: password
    hikari:
      maximum-pool-size: 20
      data-source-properties:
        cachePrepStmts: true
        prepStmtCacheSize: 250
        prepStmtCacheSqlLimit: 2048
        useServerPrepStmts: true
        useLocalSessionState: true
        rewriteBatchedStatements: true
        cacheResultSetMetadata: true
        cacheServerConfiguration: true
        elideSetAutoCommits: true
        maintainTimeStats: false

การตอบกลับนี้มีค่าสำหรับการให้ตัวอย่างการทำงานกับคุณสมบัติแหล่งข้อมูล!
Mauro Molinari

6

นี่คือข่าวดี HikariCP เป็นพูลการเชื่อมต่อเริ่มต้นในขณะนี้ที่มี Spring Boot 2.0.0

หมายเหตุประจำรุ่น Spring Boot 2.0.0

เทคโนโลยีการรวมฐานข้อมูลเริ่มต้นใน Spring Boot 2.0 ได้ถูกเปลี่ยนจาก Tomcat Pool เป็น HikariCP เราพบว่า Hakari มอบประสิทธิภาพที่เหนือกว่าและผู้ใช้ของเราหลายคนชอบมากกว่า Tomcat Pool


5

ดังนั้นปรากฎว่าการตั้งค่าเริ่มต้นเกือบทั้งหมดสำหรับ HikariCP ใช้ได้กับฉันยกเว้นจำนวนการเชื่อมต่อ DB ฉันตั้งค่าคุณสมบัตินั้นใน application.properties ของฉัน:

spring.datasource.maximumPoolSize=20

Andy Wilkinson ถูกต้องเท่าที่ฉันสามารถบอกได้ว่าคุณไม่สามารถใช้วิธีการกำหนดค่า dataSourceClassName สำหรับ HikariCP กับ Spring Boot


2
ฉันใช้ HikariCP มาระยะหนึ่งแล้วในแอปพลิเคชันต่างๆและจนถึงตอนนี้ก็ไม่เคยมีปัญหาใด ๆ ฉันใช้วิธี HikariConfig ซึ่งคุณมีการกำหนดค่าทั้งหมดของคุณในไฟล์คุณสมบัติ ทำงานได้ตามที่คาดไว้กับ SpringBoot และ SpringCore เช่นกัน ฉันยังกำหนดค่า maximumPoolSize
Davi Alves

ควรเป็นspring.datasource.maximum-pool-sizeเมื่อคุณใช้คุณสมบัติmaximumPoolSizeการกำหนดค่าสปริงมิฉะนั้นชื่อพารามิเตอร์ HikariCP
sura2k

3

My
SetUp : Spring Boot v1.5.10
Hikari v.3.2.x (สำหรับการประเมินผล)

เพื่อให้เข้าใจการกำหนดค่าของแหล่งข้อมูล Hikari อย่างแท้จริงขอแนะนำให้ปิดใช้งานการกำหนดค่าอัตโนมัติของ Spring Boot สำหรับแหล่งข้อมูล

เพิ่มสิ่งต่อไปนี้ใน application.properties:-

spring.autoconfigure.exclude = org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

การดำเนินการนี้จะปิดใช้งานความสามารถของ Spring Boot ในการกำหนดค่า DataSource ด้วยตัวเอง

ตอนนี้เป็นโอกาสที่คุณจะกำหนด Custom Configuration ของคุณเองเพื่อสร้าง HikariDataSource bean และเติมด้วยคุณสมบัติที่ต้องการ

หมายเหตุ :::
คลาสสาธารณะ HikariDataSource ขยาย HikariConfig

คุณต้อง

  1. เติมข้อมูล HikariConfig Object โดยใช้คุณสมบัติ Hikari ที่ต้องการ
  2. เริ่มต้นวัตถุ HikariDataSource ด้วยวัตถุ HikariConfig ที่ส่งผ่านเป็นอาร์กิวเมนต์ไปยังตัวสร้าง

ฉันเชื่อในการกำหนดคลาส Custom Configuration (@Configuration)ของฉันเองเพื่อสร้างแหล่งข้อมูลด้วยตัวเองและเติมข้อมูลด้วยคุณสมบัติแหล่งข้อมูลที่กำหนดในไฟล์แยกต่างหาก (กว่าแบบดั้งเดิม: application.properties)

ในลักษณะนี้ฉันสามารถกำหนดของฉันเอง sessionFactory Bean ที่ใช้ Hibernate แนะนำ: คลาส "LocalSessionFactoryBean" และเติมข้อมูลด้วยแหล่งข้อมูล Hikari ของคุณ> และคุณสมบัติอื่น ๆ ตาม Hiberante-JPA

สรุปคุณสมบัติแหล่งข้อมูล Hikari จาก Spring Boot: -

spring.datasource.hikari.allow-pool-suspension = true
spring.datasource.hikari.auto-comm = false
spring.datasource.hikari.catalog =
spring.datasource.hikari.connection-init-sql =
spring.datasource.hikari connection-test-query =
spring.datasource.hikari.connection-timeout = 100
spring.datasource.hikari.data-source-class-name =
spring.datasource.hikari.data-source-jndi =
spring.datasource.hikari.driver -class-name =
spring.datasource.hikari.idle-timeout = 50
spring.datasource.hikari.initialization-fail-fast = true
spring.datasource.hikari.isolate-internal-queries = true
spring.datasource.hikari.jdbc- url =
spring.datasource.hikari.leak-detection-threshold =
spring.datasource.hikari.login-timeout = 60
spring.datasource.hikari.max-life =
spring.datasource.hikari.maximum-pool-size = 500
spring.datasource.hikari.minimum-idle = 30
spring.datasource.hikari .password =
spring.datasource.hikari.pool-name =
spring.datasource.hikari.read-only = true
spring.datasource.hikari.register-mbeans = true
spring.datasource.hikari.transaction-isolation =
spring.datasource.hikari .username =
spring.datasource.hikari.validation-timeout =


spring.datasource.hikari.maximum-pool-size = 500 น่ากลัวจริงๆและไม่แนะนำจาก hikari :) github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
mertaksu

นั่นเป็นเพียงการกำหนดค่าตัวอย่างด้วยค่า :)
Philip Dilip

2

ด้วยการเปิดตัวสปริงบูตในภายหลังที่เปลี่ยนไปใช้ Hikari สามารถทำได้ทั้งหมดในการกำหนดค่า ฉันใช้1.5.6.RELEASEและวิธีนี้ใช้ได้ผล

build.gradle:

compile "com.zaxxer:HikariCP:2.7.3"

แอปพลิเคชัน YAML

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      idleTimeout: 60000
      minimumIdle: 2
      maximumPoolSize: 20
      connectionTimeout: 30000
      poolName: MyPoolName
      connectionTestQuery: SELECT 1

เปลี่ยนconnectionTestQueryเพื่อให้เหมาะกับฐานข้อมูลพื้นฐานของคุณ เพียงเท่านี้ไม่ต้องใช้รหัส


2

โค้ดด้านล่างสามารถใช้สำหรับการเริ่มต้นแหล่งข้อมูลแบบคงที่

public class MyDataSource {
    private static final String DB_USERNAME="spring.datasource.username";
    private static final String DB_PASSWORD="spring.datasource.password";
    private static final String DB_URL ="spring.datasource.url";
    private static final String DB_DRIVER_CLASS="spring.datasource.driver-class-name";

    private static Properties properties = null;
    private static HikariDataSource dataSource;

    static {
        try {
            properties = new Properties();
            properties.load(new FileInputStream("src/main/resources/application.properties"));

            dataSource = new HikariDataSource();
            dataSource.setDriverClassName(properties.getProperty(DB_DRIVER_CLASS));

            dataSource.setJdbcUrl(properties.getProperty(DB_URL));
            dataSource.setUsername(properties.getProperty(DB_USERNAME));
            dataSource.setPassword(properties.getProperty(DB_PASSWORD));

            dataSource.setMinimumIdle(100);
            dataSource.setMaximumPoolSize(2000);
            dataSource.setAutoCommit(false);
            dataSource.setLoginTimeout(3);

        } catch (IOException | SQLException e) {
            ((Throwable) e).printStackTrace();
        }
    }

    public static DataSource getDataSource(){
        return dataSource;
    }

    public static Connection getConnection() throws SQLException{
        return getDataSource().getConnection();
    }
}

1

ฉันประสบปัญหาและปัญหาก็คือช่องว่างในตอนท้ายของspring.datasource.type = com.zaxxer.hikari.HikariDataSource

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.