Таблицы ссылок «многие ко многим» в Grails (GORM) / hibernate

Я играю с 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


person K2J    schedule 10.02.2010    source источник


Ответы (5)


Взгляните на ключевое слово 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']
    }

}
person Heinrich Filter    schedule 12.02.2010

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

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

person Ray Tayek    schedule 23.02.2010

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

person Jared    schedule 10.02.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]
} 

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

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

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

person K2J    schedule 11.02.2010
comment
Я бы сказал, что для многих приложений структура базы данных, создаваемая Grails, не имеет значения, потому что это достаточно быстро, а данных для настройки базы данных недостаточно. Я работаю над приложением Grails, в котором я еще даже не видел структуру БД (используя БД в памяти). Однако, если вы знаете, что ваше приложение Grails будет создавать нагрузку на БД, вам лучше настроить его с самого начала, в противном случае изменение классов предметной области позже будет болезненным. - person Karsten Silz; 11.02.2010
comment
Почему вы указываете столбцы id? Вы должны полностью удалить сопоставление столбцов идентификаторов. - person Blacktiger; 11.02.2010
comment
Если вы можете сказать мне, почему я должен это делать, это поможет моему пониманию, поскольку я сказал, что я новичок в Grails. Многие разработчики полностью игнорируют базу данных и рассматривают ее как какой-то тупой уровень хранения. Подумайте, когда приложение работает и данные начинают накапливаться. Мне нужен красивый и понятный дизайн базы данных, по которому я могу легко писать отчеты. Причина для таблицы ссылок заключается в том, что я хочу сохранить элемент, например количество, встроенное с полями, которые связывают таблицы вместе. Рассмотрим строку заказа, которая составляет счет. Надеюсь, что все имеет смысл. - person K2J; 24.02.2010

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

static hasMany = [children: Child]

и в Ребенке вы помещаете

static belongsTo = [parent: Parent]

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

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

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

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

person user606153    schedule 25.02.2011