Grails与commons-dbcp2连接池数据源

Grails与commons-dbcp2连接池数据源,grails,apache-commons-dbcp,Grails,Apache Commons Dbcp,背景:我有两个项目 答:基于Spring的java项目 B:用于gui的Grails项目 我有两个相关的问题: 如何在grails项目中使用org.apache.commons.dbcp2.BasicDataSource而不是默认的ApacheTomcat数据源? org.apache.tomcat.jdbc.pool.DataSource有一个限制,它只允许一个initSql字符串。我想运行两个init sql语句[“SET SCHEMA”,“SET ROLE”],这在dbcp2中是可能的,因

背景:我有两个项目

答:基于Spring的java项目

B:用于gui的Grails项目

我有两个相关的问题:

  • 如何在grails项目中使用org.apache.commons.dbcp2.BasicDataSource而不是默认的ApacheTomcat数据源? org.apache.tomcat.jdbc.pool.DataSource有一个限制,它只允许一个initSql字符串。我想运行两个init sql语句[“SET SCHEMA”,“SET ROLE”],这在dbcp2中是可能的,因为它需要一个connectionInitSqls列表。我还尝试将2条sql语句与分号组合,但tomcat datasource给出了一个验证错误

  • 是否可以从另一个父bean扩展数据源?我想从java项目中定义的抽象bean扩展grails数据源,其思想是重用公共数据源属性


  • 我还没有看到这个泳池和Tomcat泳池之间的性能比较,但我猜你会用一辆只播放一个电台的法拉利换一辆播放两个电台的老爷车。如果你没有得到太多的流量,那么它可能不会是一个大问题

    撇开性能问题不谈,注册自己的
    数据源很容易
    ——只需在
    grails app/conf/spring/resources.groovy中创建一个具有正确名称的bean,您的bean就会覆盖grails配置的bean。所有的春豆都是如此;如果您使用Grails或插件先前配置的名称注册一个新bean,那么您的bean将获胜。并根据需要设置属性:

    import org.apache.commons.dbcp2.BasicDataSource
    
    beans = {
    
       dataSource(BasicDataSource) {
          url = '${dataSource.url}'
          driverClassName = '${dataSource.driverClassName}'
          username = '${dataSource.username}'
          password = '${dataSource.password}'
          // other valid setters - see the source or
          // javadocs for what's available
       }
    }
    
    请注意,在引用
    Config.groovy
    变量时必须使用单引号(来自
    DataSource.groovy
    的值合并到“DataSource”键下的主配置中),因为触发器的Spring属性占位符处理将用系统属性中的查找替换指定的键,属性文件,在Grails中,配置文件。如果使用双引号,则它们将成为gstring,并且过早求值,并将导致异常

    但这还不够——除了大幅度降低池性能之外,这将为您提供一个有效的连接池,但会消除Grails添加的两个很酷的特性。如果不自定义任何内容,则得到的
    dataSource
    bean实际上是两个代理,它们包装了真正的
    dataSource
    。一种是
    org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
    ,它避免了在事务开始时没有更新时配置连接的成本。它配置一个缓存方法调用的
    连接
    代理(
    setAutoCommit(false)
    ,设置隔离级别、只读、超时等),当您执行实际更新时,它将这些值应用于实际连接并使用该值。但是,如果你不做任何更新,你会节省时间,这不是一个大的节省,但将在繁忙的网站加起来。另一个是
    org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
    ,它确保在事务或Hibernate会话期间,如果您转到
    datasource
    获取连接,您将获得正在使用的连接,因此您将能够看到活动更新、读取未提交的更改等

    因此,实际上有3个数据源bean,您可以使用名称
    dataSourceUnproxied
    注册上面的一个,并通过引用注册其他数据源bean:

    dataSourceUnproxied(BasicDataSource) {
       url = ...
       ...
    }
    dataSourceLazy(LazyConnectionDataSourceProxy, ref('dataSourceUnproxied'))
    dataSource(TransactionAwareDataSourceProxy, ref('dataSourceLazy'))
    



    即使相关,你也应该每个问题问一个问题。我将用指向代码的指针回答第二个问题。如果有多个数据源,每个数据源有3个bean,那么最终会有大量冗余的代码和配置,因此
    DataSourceGrailsPlugin
    确实创建了一个具有公共属性的抽象父bean定义,并从中构建真正的bean;您可以看到这一切。

    非常感谢,感谢您的帮助!