【问题标题】:Configuration of JTDS for use with HikariCP + Spring + MS SQL Server用于 HikariCP + Spring + MS SQL Server 的 JTDS 配置
【发布时间】:2016-02-07 06:50:35
【问题描述】:

我一直在谷歌上搜索 JTDS (1.3.1) 的配置,以便与 HikariCP (2.4.3)、Spring (4.1.2) 和 MS SQL Server (2008) 一起使用,但找不到完整且有效的示例。

这是我所拥有的:

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

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

任何人都可以分享生产环境中使用的 JTDS 配置吗?

问候。

更新

我发现了这个 SO 帖子:

HikariCP hanging on getConnection

JTDS 似乎在使用 HikariCP 时遇到了问题。其实我也有这个问题。这是我对 JTDS 的完整配置:

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

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="poolName" value="springHikariCP" />
    <property name="connectionTestQuery" value="${jdbc.connectionTestQuery}" />
    <property name="dataSourceClassName" value="${jdbc.dataSourceClassName}" />
    <property name="maximumPoolSize" value="${jdbc.maximumPoolSize}" />
    <property name="minimumIdle" value="${jdbc.minimumIdle}" />
    <property name="idleTimeout" value="${jdbc.idleTimeout}" />
    <property name="connectionTimeout" value="${jdbc.connectionTimeout}" />
    <property name="jdbcUrl" value="${jdbc.url}" />
    <property name="dataSourceProperties">
        <props>
            <prop key="user">${jdbc.username}</prop>
            <prop key="password">${jdbc.password}</prop>
            <prop key="cacheMetaData">${jtds.cacheMetaData}</prop>                              
        </props>
    </property>
</bean>

这正是我发布问题的原因,我希望看到一个完整的例子。但是,在 HikariCP 的页面上,JTDS 被列为支持。我很困惑。

【问题讨论】:

  • 如果您使用的是 SQL Server,我强烈建议您使用cacheMetaData=true。如果您有包含大量行(数千行)的 ResultSet,我建议使用 useCursors=true 并根据需要在每个 Statement 上设置 Statement.setFetchSize()(SQL Server 默认为一次 100 行)。
  • brettw,非常感谢您的意见!我确实使用 MS SQL Server。我忘了提。为什么不让你的回答成为一个完整的答案?我会选择它。另外我不知道如何添加数据库 URL。最好的。
  • brettw,在我的应用程序中,我总是通过 Spring Data 显示分页结果。在这种情况下,“我建议使用 useCursors=true 并在每个 Statement 上适当设置 Statement.setFetchSize()”是否仍然正确?最好的。

标签: spring jtds hikaricp


【解决方案1】:

以下作品:

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" depends-on="flyway">
    <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
    <property name="connectionTestQuery" value="SELECT GETDATE()"/>
    <property name="maximumPoolSize" value="32"/>
    <property name="jdbcUrl" value="${dbUrl}"/>
    <property name="username" value="${dbUsername}"/>
    <property name="password" value="${dbPassword}"/>
</bean>

注意connectionTestQuery 属性是必需的,因此 Hikari 不会假定驱动程序符合 JDBC4(jTDS 符合 3.0)。

【讨论】:

    【解决方案2】:

    基于@roded,我以这种方式实现了它,它对我有用。

        @Bean
        public JdbcTemplate jdbcTemplate() {
            HikariConfig c = new HikariConfig();
            c.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
            c.setConnectionTestQuery("SELECT GETDATE()");
            c.setMaximumPoolSize(32);
            c.setJdbcUrl("jdbc:jtds:sqlserver://serverIp:1433/DBName;");
            c.getDataSourceProperties().put("user", "user");
            c.getDataSourceProperties().put("password", "password");
            c.getDataSourceProperties().put("cacheMetaData", true);
    
            HikariDataSource hds = new HikariDataSource(c);
    
            JdbcTemplate jdbcTemplate = new JdbcTemplate(hds);
    
        return jdbcTemplate;
    }
    

    【讨论】:

    • 谢谢你拯救了我的一天...:-)..我使用了这样的 URL jdbc:jtds:sqlserver://1.1.1.1:1433/test;domain=Test;useNTLMv2=true;
    【解决方案3】:

    这两种方法都对我有用。我能够正确使用数据库连接。

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">  
          <property name="poolName" value="tmmConnPool"/>
          <property name="connectionTestQuery" value="SELECT 1"/>    
          <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
          <property name="maximumPoolSize" value="10"/>
          <property name="jdbcUrl" value="jdbc:jtds:sqlserver://127.0.0.1:1433/users;domain=workgroup"/>
          <property name="username" value="sa"/>
          <property name="password" value="admin"/>
        </bean>
    
        <!-- OR -->
    
         <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">  
          <property name="poolName" value="tmmConnPool"/>
          <property name="connectionTestQuery" value="SELECT 1"/>    
          <property name="dataSourceClassName" value="net.sourceforge.jtds.jdbcx.JtdsDataSource"/>
          <property name="maximumPoolSize" value="10"/>
          <property name="dataSourceProperties">
             <props>
               <prop key="user">sa</prop>
               <prop key="password">admin</prop>
               <prop key="serverName">127.0.0.1</prop>    
               <prop key="portNumber">1433</prop>    
               <prop key="databaseName">users</prop>    
               <!-- For SQLServer value is 1 -->   
               <prop key="serverType">1</prop>   
               <prop key="domain">workgroup</prop>                    
              </props>
          </property>
        </bean>  
    
        <!-- Reference of above databSource, both options given above works -->
    
        <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">  
           <constructor-arg ref="hikariConfig"/>  
        </bean>  
    

    除此之外,我还能够使用 java 实现获得连接

    public Connection getConnectionFromPool() {
            final HikariConfig hikariCfg = new HikariConfig();
            hikariCfg.setPoolName("tmmConnectionPool");
            hikariCfg.setDataSourceClassName("net.sourceforge.jtds.jdbcx.JtdsDataSource");
            hikariCfg.setConnectionTestQuery("SELECT 1");
            hikariCfg.setMaximumPoolSize(10);
            hikariCfg.getDataSourceProperties().put("user", "sa);
            hikariCfg.getDataSourceProperties().put("password", "admin");
            hikariCfg.getDataSourceProperties().put("serverName", "127.0.0.1");
            hikariCfg.getDataSourceProperties().put("portNumber", "1433");
            hikariCfg.getDataSourceProperties().put("databaseName", "users");
            hikariCfg.getDataSourceProperties().put("serverType", "1");
            hikariCfg.getDataSourceProperties().put("domain", "workgroup");
    
    
            final HikariDataSource hikariDs = new HikariDataSource(hikariCfg);
            Connection conn = null;
            try {
                conn = hikariDs.getConnection();
            } catch (SQLException excp) {
                LOGGER.error("Exception occurred while getting connection from dataSource", excp);
            } finally {
                if (hikariDs !=null) {
                    hikariDs.close();
                }
            }
            return conn;
        }
    

    【讨论】: