【问题标题】:In Grails, how can I get a reference to the datasource used by a particular class?在 Grails 中,如何获取对特定类使用的数据源的引用?
【发布时间】:2016-08-26 20:12:44
【问题描述】:

在我正在处理的项目中(在 Grails 2.5.4/Hibernate 4.3 中)我有一堆不同的类,使用几个不同的数据源。我需要确定两个给定的 Class 对象是否使用相同的数据源。我想做的是:

Boolean doDataSourcesMatch(Class a, Class b)
{
  return a.mapping.datasource == b.mapping.datasource
}

但这当然行不通,因为a.mapping 是一个闭包。有谁知道如何访问一个类使用的数据源?我不需要知道连接的任何属性,只需要知道对两个类的查询是否会使用相同的连接。

非常感谢!

【问题讨论】:

    标签: grails grails-orm datasource


    【解决方案1】:

    虽然这些都没有具体说明,但它们可能会有所帮助:

    1. http://grails.1312388.n4.nabble.com/How-can-I-get-the-column-name-that-a-property-maps-to-for-a-domain-class-td4633766.html

    2. How to get the name of the table GORM object is mapped to?

    我没有找到任何具体的东西,但这一切都很奇怪。我的意思是你已经知道了,我认为这是一些动态查询,否则你编码它会知道一起查询什么等等。

    无论如何,作为一种解决方法,不确定是否可以,因为这取决于我们正在谈论的域类的数量,以及如果这是您已经实施或正在考虑写的东西,即如果可以的话,在这两种情况下都没有写将您自己的 getter 添加到所有相关的域类中

    //
    static String getDataSrc() {
      return 'data_source_a'
    }
    
    //or
    static boolean canQuery() {
      return true/false
    }
    

    你可以像这样从任何地方检查:

    boolean canQuery = UserAttributes.canQuery()
    String currentDataSource = UserAttributes.dataSrc
    

    由于它们是静态方法,因此不需要实例化。这意味着如果你有

    userObject(1) 你不需要做:

    User user = User.get(1)
    if (user.canQuery()) {
     // this is ok
    } 
    

    您可以通过引用大写类名称及其方法,直接从任何地方调用该方法。

    String currentDataSource = UserAttributes.dataSrc
    //Where this is exactly the same as above
    String currentDataSource = UserAttributes.getDataSrc()
    

    E2A:答案是:

    import org.grails.orm.hibernate.cfg.GrailsDomainBinder
    
    class TestController {
     //either this method
    def binder = new org.grails.orm.hibernate.cfg.GrailsDomainBinder().getMapping(Photos.class)
            println "binder : ${binder.table.name}"
            println "b: ${binder.datasources}"
    
    //Or this
            def dc=GrailsDomainBinder.getMapping(Photos.class)
    
            println "-dc is ${dc}"
            println "${dc.datasources}"
    }
    

    dc.datasources

    是一个列表,所以你需要比较列表。

    我当然傻了,如果你在 HQL 中查询类似的东西,你提供动态表名 ${tableA} ${tableB}

    您需要访问实际的域类才能调用GrailsDomainBinder

    So something like:def domainClass = grailsApplication.getDomainClass(domain).clazz

    将为您提供给定 tableName 的实际 domainClass。但是您的域必须是完全限定的打包名称,这样会再次导致您出现问题。 如果你查询com.domain.users.tableAcom.domain.info.tableB

    所以你可以在服务/控制器之外使用 If):

    def domainClass=Holders.grailsApplication?.domainClasses?.find { it.clazz.simpleName == tableName }?.clazz
    

    如果你在控制器服务中声明 grailsApplication,或者没有 Holders:

    def domainClass=grailsApplication?.domainClasses?.find { it.clazz.simpleName == tableName }?.clazz
    

    【讨论】:

    • 您实际上也可以在每个类中将数据源名称声明为静态字符串,然后将域对象中的数据源设置为该静态声明。像上面一样重用静态字符串来找出名称,所以在你有 mapping = { dataSource = dataSrc } 的位中,每个类只声明一次
    • 感谢您的回复,@vahid。如果可能的话,我想避免向每个类添加代码以返回数据源的名称。我有很多课,这对颈部维护来说会很痛苦。但我会看看我是否能从你提供的链接中找出一些东西。到目前为止,我发现 GrailsDomainBinder.getMapping(MyClass) 看起来很有希望,但我得到“没有方法签名:静态 GrailsDomainBinder.getMapping() 适用于参数类型:(java.lang.Class) 值:[MyClass] 可能的解决方案:getMapping (java.lang.Class), getMapping(GrailsDomainClass)"
    • 在那个 GrailsDomainBinder 我更新了我的答案@DavidLeaman
    • 再次感谢;我认为我的问题的答案是new org.grails.orm.hibernate.cfg.GrailsDomainBinder().getMapping(Photos.class)。但是,我遇到了一些自定义问题:我使用的一些类不是本机 Grails 域类,因此 GrailsDomainBinder 似乎并不了解它们。我会再考虑一下,以后可能会问另一个问题。
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 2015-05-24
    • 2014-02-24
    • 1970-01-01
    • 2011-01-17
    • 2011-03-09
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多