在 Grails 中,我如何获得对特定 class 使用的数据源的引用?

In Grails, how can I get a reference to the datasource used by a particular class?

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

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

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

非常感谢!

尽管其中 none 说明了任何具体的内容,但它们可能会有所帮助:

  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 添加到所有有问题的域 classes

//
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
} 

只要引用大写class名称及其方法,就可以从任何地方直接调用该方法。

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 的东西,你在其中提供动态 table 名称 ${tableA} ${tableB}

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

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

将为您提供给定 table 名称的实际域类。但是您的域必须是完全限定的打包名称,这样会再次给您带来问题。 如果您查询 com.domain.users.tableAcom.domain.info.tableB

所以您可以在 service/controller 之外使用 If):

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

如果您在控制器服务中声明 grailsApplication,则不使用 Holders:

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