2016-08-26 3 views
1

В проекте, над которым я работаю (в Grails 2.5.4/Hibernate 4.3) У меня есть куча разных классов, используя несколько разных источников данных. Мне нужно определить, используют ли два заданных объекта класса один и тот же источник данных. То, что я хотел бы сделать что-то вроде:В Grails, как я могу получить ссылку на источник данных, используемый конкретным классом?

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

Но, конечно, не работает, так как a.mapping является замыканием. Кто-нибудь знает, как получить доступ к источнику данных, используемому классом? Мне не нужно знать какие-либо свойства соединения, просто ли запросы на двух классах будут использовать одно и то же соединение.

Большое спасибо!

ответ

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?

Я не нашел ничего конкретного, но это все довольно странно. Я имею в виду, что вы уже знаете, и я предполагаю, что это какой-то динамический запрос, иначе вы бы его кодировали, он знал бы, что запросить вместе и т. Д.

Во всяком случае, как обходной путь, неуверенный, может ли это быть, поскольку это зависит от того, сколько доменных разговоров мы говорим , и если это то, что вы уже поставили на месте или мышления не описываю то есть ничего не написано в любом случае, если вы можете добавить свой собственный метод получения всех классов предметной области в вопросе

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

даст вам фактическую domainClass для данного TABLENAME. Но ваш домен должен быть полностью квалифицированным упакованным именем, чтобы снова вызвать проблемы. Если вы запрашивая com.domain.users.tableA и com.domain.info.tableB

Так что вы могли бы вместо того, чтобы использовать если за пределами службы/контроллера):

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

или без держателей, если вы объявляющих grailsApplication в обслуживании контроллера:

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

Также вы могли бы фактически объявить имена источников данных статическими строками в каждом классе, а затем установить источник данных в объекте домена на это статическое объявление. Повторное использование статической строки для определения имени так же, как и выше, поэтому в бите у вас есть сопоставление = {dataSource = dataSrc}, тогда оно объявляется только один раз за класс – Vahid

+0

Спасибо за ваш ответ @vahid. Если это вообще возможно, я бы хотел избежать добавления кода в каждый класс, чтобы вернуть имя источника данных. У меня много классов, и это будет болью в обслуживании шеи. Но я посмотрю, смогу ли я что-нибудь выяснить из ссылок, которые вы предоставили. До сих пор я нашел «GrailsDomainBinder.getMapping (MyClass)», который выглядит многообещающим, но я получаю «Нет сигнатуры метода: static GrailsDomainBinder.getMapping() применим для типов аргументов: (java.lang.Class) значения: [MyClass ] Возможные решения: getMapping (java.lang.Class), getMapping (GrailsDomainClass) " –

+0

Именно в этом GrailsDomainBinder я обновил свой ответ @DavidLeaman – Vahid