Grails: Create dynamic SQL-Connection

后端 未结 2 1613
醉酒成梦
醉酒成梦 2021-01-06 15:30

For my application I need dynamic database connections at runtime. I know, there are ways to create multiple datasources but they are not that dynamically I think. Scenari

2条回答
  •  抹茶落季
    2021-01-06 16:21

    You can do this sort of thing to register DataSource beans at runtime:

    Given a Grails Service:

    package whatever
    
    import groovy.sql.Sql
    import org.springframework.context.*
    import org.apache.tomcat.jdbc.pool.DataSource
    import org.springframework.context.support.GenericApplicationContext
    
    class DataSourceService implements ApplicationContextAware {
    
        ApplicationContext  applicationContext
    
        def registerBean( String beanName, String dsurl, String uid, String pwd ) {
            if( !applicationContext.containsBean( beanName ) ) {
                def bb = new grails.spring.BeanBuilder()
                bb.beans {
                    "$beanName"( DataSource ) {
                        driverClassName = "com.mysql.jdbc.Driver"
                        url             = dsurl
                        username        = uid
                        password        = pwd
                        validationQuery = "SELECT 1"
                        testOnBorrow    = true
                        maxActive       = 1
                        maxIdle         = 1
                        minIdle         = 1
                        initialSize     = 1
                    }
                }
                bb.registerBeans( applicationContext )
                log.info "Added $beanName"
            }
            else {
                log.error "Already got a bean called $beanName"
            }
        }
    
        def deRegisterBean( String beanName ) {
            if( applicationContext.containsBean( beanName ) ) {
                (applicationContext as GenericApplicationContext).removeBeanDefinition( beanName )
                log.info "Removed $beanName"
            }
            else {
                log.error "Trying to deRegister a bean $beanName that I don't know about"
            }
        }
    
        def getSql( String beanName ) {
            Sql.newInstance( applicationContext.getBean( beanName ) )
        }
    }
    

    Then, you should be able to call the service to register a new datasource:

    dataSourceService.registerBean( 'myDS', 'jdbc:mysql://localhost:3306/mysql', 'test', 'test' )
    

    Get a Groovy Sql object for it:

    dataSourceService.getSql( 'myDS' ).rows( 'SELECT * FROM whatever' )
    

    And remove the bean when done

    dataSourceService.deRegisterBean( 'myDS' )
    

    Fingers crossed... I've yanked that code from a project of mine and changed/not-tested it ;-)

    Update

    The runtime-datasources plugin has been created which uses the approach outlined in this post to allow datasources to be added/removed at runtime.

提交回复
热议问题