Таблицы ссылок «многие ко многим» в Grails (GORM) / hibernate - PullRequest
4 голосов
/ 10 февраля 2010

Я хорошо играю с Grails и нахожу вещи ORM утомительными, потому что я не до конца понимаю, что я делаю, когда речь идет о классах предметной области. Я надеюсь, что кто-то может вернуть меня на правильный путь

Рассмотрим следующее

Тестовое задание Один: много Оборудование, используемое на задании Многие: одно Физическое оборудование

... это аналог классического сценария Order, OrderLine, Product, который можно увидеть в примерах БД университета

Я создал следующие классы доменов

class Job
{
  String jobName
  String jobDescription
}

class HardwareOnJob
{
   static hasMany = [  jobs:Job, physicalHardware:PhysicalHardware ]
   static belongsTo = Job

   String role
}

class PhysicalHardware
{
  String assetName
  String model
  String os 
}

Вопрос, который мне нужно задать, заключается в том, почему Grails создает мне две дополнительные таблицы в моей базе данных, а не использует определенный мной объект связи / класс домена. Например, Grails создает в базе данных hardware_on_job_job и hardware_on_job_physical_hardware.

Используя контроллеры, работающие на строительных лесах, я могу ввести некоторое оборудование, ввести задание и затем связать их вместе. У меня есть вопрос, почему он создает эти две дополнительные таблицы, а не использует объект домена (HardwareOnJob), который я указал.

Любая помощь / руководство будет очень цениться, как схожу с ума, глядя на это и пробуя новые вещи. Кстати, я на Grails версии 1.2.1

Ответы [ 5 ]

5 голосов
/ 12 февраля 2010

Посмотрите на ключевое слово joinTable, которое:

Настраивает таблицу соединений, используемую для однонаправленных типов коллекций «один ко многим», «многие ко многим» и «примитив»

Вот пример из руководства пользователя:

class Book {
    String title
    static belongsTo = Author
    static hasMany = [authors:Author]

    static mapping = {
        authors joinTable:[name:"mm_author_books", key:'mm_book_id' ]
    }
}
class Author {
    String name
    static hasMany = [books:Book]

    static mapping = {
        books joinTable:[name:"mm_author_books", key:'mm_author_id']
    }

}
1 голос
/ 23 февраля 2010

рассмотрите возможность использования явного класса / таблицы ассоциации. см. класс членства в http://www.grails.org/Many-to-Many+Mapping+without+Hibernate+XML

дополнительным преимуществом является создание леса для класса ассоциации (вы не получите этого без явного класса ассоциации).

0 голосов
/ 25 февраля 2011

Вкратце, если у Child ровно один родитель, то в Parent вы ставите

static hasMany = [children: Child]

и в Child вы положите

static belongsTo = [parent: Parent]

(или, если вы не хотите каскадировать, я думаю, что достаточно добавить «Родительский родитель», но я думаю, это более редкий случай)

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

Обычно это создает столбец в Child, содержащий идентификатор для его Parent. Это не может иметь место для многих ко многим, когда потребуется какая-то таблица ссылок (и GORM может справиться с этим). Так называемые «односторонние» отношения (как у вас в первом примере) также могут создавать таблицы ссылок, что немного объясняется этим:

http://grails.1312388.n4.nabble.com/Many-to-many-vs-Many-to-one-td1369336.html

0 голосов
/ 11 февраля 2010

Хорошо, так что после игры я придумал следующую структуру

class Job 
{ 
  String jobName 
  String jobDescription 

  static mapping = {
     id column:"jobId"
  }

  static hasMany = [hardware:HardwareOnJob]
} 

class HardwareOnJob 
{
   String role 
   Job job
   PhysicalHardware hardware


  static mapping = {
     id column:"hardware_on_job_id"
  }

} 

class PhysicalHardware 
{ 
  String assetName 
  String model 
  String os  

  static mapping = {
     id column:"physical_hardware_id"
  }

  static hasMany = [hardwareOnjob:HardwareOnJob]
} 

Это выглядит разумным для всех остальных? Созданная структура базы данных выглядит намного дружелюбнее и содержит только три таблицы, которые я ожидаю.

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

Комментарии приветствуются

0 голосов
/ 10 февраля 2010

При использовании отношений «один ко многим» или «многие ко многим» Grails создает таблицу соединений, содержащую идентификаторы объектов в отношении. Вы можете избежать использования таблицы соединений, сказав Grails использовать внешний ключ в отношении один ко многим. Насколько мне известно, нет способа избежать использования автоматически созданной таблицы соединений во многих отношениях. Для получения дополнительной информации см. Разделы 5.2.1.2 и 5.2.1.3 this , а также this

...