【问题标题】:How to set up datasource with Spring for HikariCP?如何使用 Spring 为 HikariCP 设置数据源?
【发布时间】:2014-06-04 01:21:27
【问题描述】:

您好,我正在尝试将 HikariCP 与 Spring 一起用于连接池。我正在使用 jdbcTempLate 和 JdbcdaoSupport。
这是我的数据源 spring 配置文件:

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="dataSourceClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="dataSource.url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
    <property name="dataSource.user" value="username"/>
    <property name="dataSource.password" value="password"/>
</bean>

但不幸的是,正在生成以下错误消息:

Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.zaxxer.hikari.HikariDataSource]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.zaxxer.hikari.HikariDataSource.<init>()

谁能告诉我如何解决这个问题?

【问题讨论】:

  • 使用 oracle.jdbc.pool.OracleDataSource 见github.com/brettwooldridge/…
  • 在 xml 参数中,这个答案和下面的许多都将 dataSourceClass 名称定义为 Hikari 以外的名称。当我们真正想要的是 Hikari 数据源时,将 oracle.jdbc 定义为 dataSourceClassName 的目的是什么?
  • 在文档github.com/brettwooldridge/HikariCP#configuration-knobs-baby 中找到了我的答案。参数dataSourceClassName其实是指jdbc驱动类名。

标签: spring jdbc spring-jdbc jdbctemplate hikaricp


【解决方案1】:

你需要在你的 bean 配置上写下这个结构(这是你的数据源):

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="poolName" value="springHikariCP" />
    <property name="connectionTestQuery" value="SELECT 1" />
    <property name="dataSourceClassName" value="${hibernate.dataSourceClassName}" />
    <property name="maximumPoolSize" value="${hibernate.hikari.maximumPoolSize}" />
    <property name="idleTimeout" value="${hibernate.hikari.idleTimeout}" />

    <property name="dataSourceProperties">
        <props>
            <prop key="url">${dataSource.url}</prop>
            <prop key="user">${dataSource.username}</prop>
            <prop key="password">${dataSource.password}</prop>
        </props>
    </property>
</bean>

<!-- HikariCP configuration -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>

这是我的例子,它正在工作。您只需将您的属性放在 hibernate.properties 上并在之前设置:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:hibernate.properties</value>
        </list>
    </property>
</bean>

Obs.:版本是
log4j:1.2.16
springframework:3.1.4.RELEASE
HikariCP:1.4.0

属性文件(hibernate.properties):

hibernate.dataSourceClassName=oracle.jdbc.pool.OracleDataSource
hibernate.hikari.maximumPoolSize=10
hibernate.hikari.idleTimeout=30000
dataSource.url=jdbc:oracle:thin:@localhost:1521:xe
dataSource.username=admin
dataSource.password=

【讨论】:

  • 但是如何在我的 java 代码中使用上述配置,例如HikariConfig hikariConfig = new HikariConfig(); ,hikarConfig 怎么知道选择上面的配置?
【解决方案2】:

我的测试 java 配置(用于 MySql)

@Bean(destroyMethod = "close")
public DataSource dataSource(){
    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
    hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/spring-test"); 
    hikariConfig.setUsername("root");
    hikariConfig.setPassword("admin");

    hikariConfig.setMaximumPoolSize(5);
    hikariConfig.setConnectionTestQuery("SELECT 1");
    hikariConfig.setPoolName("springHikariCP");

    hikariConfig.addDataSourceProperty("dataSource.cachePrepStmts", "true");
    hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSize", "250");
    hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048");
    hikariConfig.addDataSourceProperty("dataSource.useServerPrepStmts", "true");

    HikariDataSource dataSource = new HikariDataSource(hikariConfig);

    return dataSource;
}

【讨论】:

    【解决方案3】:

    您可以在 servlet 上下文中创建一个数据源 bean,如下所示:

    <beans:bean id="dataSource"
        class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <beans:property name="dataSourceClassName"
            value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
        <beans:property name="maximumPoolSize" value="5" />
        <beans:property name="maxLifetime" value="30000" />
        <beans:property name="idleTimeout" value="30000" />
        <beans:property name="dataSourceProperties">
            <beans:props>
                <beans:prop key="url">jdbc:mysql://localhost:3306/exampledb</beans:prop>
                <beans:prop key="user">root</beans:prop>
                <beans:prop key="password"></beans:prop>
                <beans:prop key="prepStmtCacheSize">250</beans:prop>
                <beans:prop key="prepStmtCacheSqlLimit">2048</beans:prop>
                <beans:prop key="cachePrepStmts">true</beans:prop>
                <beans:prop key="useServerPrepStmts">true</beans:prop>
            </beans:props>
        </beans:property>
    </beans:bean>
    

    【讨论】:

    【解决方案4】:

    使用 XML 配置,您的数据源应如下所示:

        <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">  
          <property name="dataSourceProperties" >
            <props>
                <prop key="dataSource.url">jdbc:oracle:thin:@localhost:1521:XE</prop>
                <prop key="dataSource.user">username</prop>
                <prop key="dataSource.password">password</prop>
            </props>
          </property>  
          <property name="dataSourceClassName"   
                    value="oracle.jdbc.driver.OracleDriver" />  
        </bean>  
    
        <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">  
              <constructor-arg ref="hikariConfig" />  
        </bean>  
    

    或者您可以完全跳过 HikariConfig bean 并使用提到的方法 here

    【讨论】:

    • OK。但是我将如何在spring配置文件中声明数据源bean?你能帮我一些示例代码吗!!!
    • 您是在 Spring 配置中使用任何 Java Config 还是全部是 xml?
    • 没有人。它抛出另一个异常.......................无法在设置bean属性'dataSource'时解析对bean'dataSource'的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建 ServletContext 资源 [/WEB-INF/dispatcher-servlet.xml] 中定义的名称为“dataSource”的 bean 时出错:bean 的实例化失败;嵌套异常是 java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
    • 你的类路径中有 slf4j 吗?
    • "dataSourceClassName" 错误应该是 "oracle.jdbc.pool.OracleDataSource" 见:github.com/brettwooldridge/…
    【解决方案5】:

    我最近在一个基于 Spring 和 Hibernate 的项目中从 C3P0 迁移到 HikariCP,这并不像我想象的那么容易,在这里我分享我的发现。

    对于Spring Boot,请参阅我的答案here

    我有以下设置

    • 春季 4.3.8+
    • Hiberante 4.3.8+
    • Gradle 2.x
    • PostgreSQL 9.5

    下面的一些配置与上面的一些答案相似,但存在差异。

    Gradle 的东西

    为了拉入正确的罐子,我需要拉入以下罐子

    //latest driver because *brettw* see https://github.com/pgjdbc/pgjdbc/pull/849
    compile 'org.postgresql:postgresql:42.2.0'
    compile('com.zaxxer:HikariCP:2.7.6') {
        //they are pulled in separately elsewhere
        exclude group: 'org.hibernate', module: 'hibernate-core'
    }
    
    // Recommended to use HikariCPConnectionProvider by Hibernate in 4.3.6+    
    compile('org.hibernate:hibernate-hikaricp:4.3.8.Final') {
            //they are pulled in separately elsewhere, to avoid version conflicts
            exclude group: 'org.hibernate', module: 'hibernate-core'
            exclude group: 'com.zaxxer', module: 'HikariCP'
    }
    
    // Needed for HikariCP logging if you use log4j
    compile('org.slf4j:slf4j-simple:1.7.25')  
    compile('org.slf4j:slf4j-log4j12:1.7.25') {
        //log4j pulled in separately, exclude to avoid version conflict
        exclude group: 'log4j', module: 'log4j'
    }
    

    基于 Spring/Hibernate 的配置

    为了让 Spring & Hibernate 使用 Hikari 连接池,您需要定义 HikariDataSource 并将其输入到 sessionFactory bean 中,如下所示。

    <!-- HikariCP Database bean -->
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig" />
    </bean>
    
    <!-- HikariConfig config that is fed to above dataSource -->
    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
            <property name="poolName" value="SpringHikariPool" />
            <property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource" />
            <property name="maximumPoolSize" value="20" />
            <property name="idleTimeout" value="30000" />
    
            <property name="dataSourceProperties">
                <props>
                    <prop key="serverName">localhost</prop>
                    <prop key="portNumber">5432</prop>
                    <prop key="databaseName">dbname</prop>
                    <prop key="user">dbuser</prop>
                    <prop key="password">dbpassword</prop>
                </props>
            </property>
    </bean>
    
    <bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">
            <!-- Your Hikari dataSource below -->
            <property name="dataSource" ref="dataSource"/>
            <!-- your other configs go here -->
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</prop>
                    <!-- Remaining props goes here -->
                </props>
            </property>
     </bean>
    

    完成上述设置后,您需要向log4j or logback 添加一个条目并将level 设置为DEBUG 以查看Hikari 连接池启动。

    Log4j1.2

    <!-- Keep additivity=false to avoid duplicate lines -->
    <logger additivity="false" name="com.zaxxer.hikari">
        <level value="debug"/>
        <!-- Your appenders goes here -->
    </logger>
    

    回退

    通过application.propertiesSpring Boot

    debug=true
    logging.level.com.zaxxer.hikari.HikariConfig=DEBUG 
    

    使用logback.xml

    <logger name="com.zaxxer.hikari" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    

    有了以上内容,您应该一切顺利!显然,您需要自定义 HikariCP 池配置以获得它所承诺的性能。

    【讨论】:

    • 我注意到所有答案都是设置凭据。如果我有这样一种情况,即通过请求者的凭据在运行时为每个 http 请求设置凭据,该怎么办?我可以将它们排除在配置之外吗?
    【解决方案6】:

    最后一个错误是由未找到库 SLF4J 引起的。 HikariCP 有两个依赖项:slf4j 和 javassist。顺便说一句,HikariDataSource 确实 有一个默认构造函数并且不需要 HikariConfig,请参阅this link。所以这从来都不是问题。

    【讨论】:

    • 我已经添加了 SLF4J jar。现在那个错误消失了。你能告诉我如何添加javassist????????????
    • 只需从 here 下载 Javassist 3.18.1-GA jar 文件,然后像 slf4j 一样将其添加到您的类路径中。
    【解决方案7】:

    我在http://www.baeldung.com/hikaricp 中找到了它,它可以工作。

    你的 pom.xml

    <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>2.6.3</version>
            </dependency>
    

    你的 data.xml

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="jdbcUrl" value="${jdbc.databaseurl}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig" />
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"
    />
    

    你的 jdbc.properties

    jdbc.driverClassName=org.postgresql.Driver
    jdbc.dialect=org.hibernate.dialect.PostgreSQL94Dialect
    jdbc.databaseurl=jdbc:postgresql://localhost:5432/dev_db
    jdbc.username=dev
    jdbc.password=dev
    

    【讨论】:

    • 我写在Baeldung :)
    【解决方案8】:

    这也可以帮助使用java类方式的配置文件。

    @Configuration
    @PropertySource("classpath:application.properties")
    public class DataSourceConfig {
        @Autowired
        JdbcConfigProperties jdbc;
    
    
        @Bean(name = "hikariDataSource")
        public DataSource hikariDataSource() {
            HikariConfig config = new HikariConfig();
            HikariDataSource dataSource;
    
            config.setJdbcUrl(jdbc.getUrl());
            config.setUsername(jdbc.getUser());
            config.setPassword(jdbc.getPassword());
            // optional: Property setting depends on database vendor
            config.addDataSourceProperty("cachePrepStmts", "true");
            config.addDataSourceProperty("prepStmtCacheSize", "250");
            config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
            dataSource = new HikariDataSource(config);
    
            return dataSource;
        }
    }
    

    如何使用:

    @Component
    public class Car implements Runnable {
        private static final Logger logger = LoggerFactory.getLogger(AptSommering.class);
    
    
        @Autowired
        @Qualifier("hikariDataSource")
        private DataSource hikariDataSource;
    
    
    }
    

    【讨论】:

      【解决方案9】:

      对于 DB2,请尝试以下配置。

      <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
          <property name="poolName" value="springHikariCP" />
          <property name="dataSourceClassName" value="com.ibm.db2.jcc.DB2SimpleDataSource"/>
      
          <property name="maximumPoolSize" value="${db.maxTotal}" />
          <property name="dataSourceProperties">
              <props>
                  <prop key="driverType">4</prop>
                  <prop key="serverName">192.168.xxx.xxx</prop>
                  <prop key="databaseName">dbname</prop>
                  <prop key="portNumber">50000</prop>
                  <prop key="user">db2inst1</prop>
                  <prop key="password">password</prop>
              </props>
          </property>
      
          <property name="jdbcUrl" value="${db.url}" />
          <property name="username" value="${db.username}" />
          <property name="password" value="${db.password}" />
      </bean>
      <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
          <constructor-arg ref="hikariConfig" />
      </bean>
      

      【讨论】:

        猜你喜欢
        • 2014-07-01
        • 1970-01-01
        • 2014-10-05
        • 1970-01-01
        • 2018-11-03
        • 2016-05-03
        • 1970-01-01
        • 2018-09-30
        • 1970-01-01
        相关资源
        最近更新 更多