GORM Mapping Manifesto :: Долго или не долго - PullRequest
4 голосов
/ 29 сентября 2011

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

В чем проблема?

Grails автоматически вводит поле id типа Long в ваши домены ( см. комментарий Беквита ).При использовании устаревшей БД Grails по умолчанию сопоставляет Longs с bigints, неэффективный тип хранилища будет избегать любой, кто имеет дело с таблицами с миллионами записей.

Обнаружив это несколько месяцев назад, я принялся за работу над созданием «правильного» типа столбца для идентификаторов моего домена.Не имея фона Java, я слепо подумал: длинный-плохой, хороший-целочисленный и установить диалект отображения гибернации для целочисленных типов на то, что я делал бы вручную в mysql

registerColumnType (Types.INTEGER, 'mediumint unsigned ')

и затем определили "Integer id" во всех моих доменах (необязательно в соответствии с комментарием Берта в ссылке выше).Все работало плавно, замечательно, по другим вопросам.

Перенесемся в Grails 2.0 (так как я не смог устоять перед всеми вкусностями ;-)) и Споком.На протяжении всей жизни я не мог понять, почему, несмотря на новый 2.0 GORM в памяти и поддержку динамических искателей, Domain.findByFoo (fooVal) всегда будет возвращать ноль (да, я @Mock (Domain) и заполняться тестовыми данными).Фактически, как в самом тесте, так и в цели @TestFor, единственными работающими методами GORM были save () и get ();все остальное вернулось null.

Я запустил быстрое тестовое приложение, спецификация domain + controller + spoc и обнаружил источник проблемы: если вы используете для идентификаторов тип свойства, отличный от Long (включая ссылочные FK), ваш домен @Mock станет бесполезным.

Итак, я прав или нет, говоря, что для использования всех преимуществ фреймворка необходимо использовать длинные идентификаторы?@Mock + @TestFor + Спок - невероятное комбо!Руководство ценится прежде, чем я отправлюсь по дороге от рефактора к Длинной дороге ...

1 Ответ

5 голосов
/ 29 сентября 2011

Я не могу представить ни одного реалистичного сценария, в котором разница между Integer и Long имела бы какое-либо заметное влияние на производительность (что, похоже, было первоначальной мотивацией для внесения этого изменения).

Если использование Long работает, но Integer вызывает проблемы, тогда используйте Long и переходите к более важным задачам. Я бы беспокоился только об этом, если бы вы могли доказать , что использование Integer имеет какое-то существенное значение.

Обновление

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

class Person {
   Long id

   static mapping = {
      // See here for alternatives to integer, and how they map to DB types
      // http://docs.jboss.org/hibernate/stable/core/manual/en-US/html/mapping.html#mapping-types-basictypes
      id type:'integer'
   }
}

Ты тоже воспитывался в комментариях

имеет дело с Long на уровне кода, где необходимо указать def foo (Long id) {...} и params.id.toLong (), а не Integer

Вы можете просто определить действие как

def myAction = {Person p ->

}

или

def myAction = {
   Person p = new Person(params)
}

А Grails позаботится о преобразовании типа параметра запроса id в Person.id, независимо от того, является ли это Long, Integer, BigDecimal и т. Д.

...