Какой тип Java вы используете для коллекций JPA и почему? - PullRequest
53 голосов
/ 11 января 2011

Какой из следующих типов коллекций вы используете в модели вашего домена JPA и почему:

  • java.util.Collection
  • java.util.List
  • java.util.Set

Мне было интересно, есть ли какие-то основные правила для этого.

ОБНОВЛЕНИЕ Я знаю разницу между Set и List. List допускает дублирование и имеет порядок, а Set не может содержать дубликаты элементов и не определяет порядок. Я задаю этот вопрос в контексте JPA. Если вы строго следуете определению, то вам всегда следует использовать тип Set, поскольку ваша коллекция хранится в реляционной базе данных, где вы не можете иметь дубликаты и где вы сами определяете порядок, т.е. порядок в Ваша Java List не обязательно сохраняется в БД.

Например, большую часть времени я использую тип List, а не потому, что он имеет порядок или допускает дублирование (которого у меня не может быть в любом случае), потому что некоторые компоненты в моей библиотеке компонентов требуют список.

Ответы [ 5 ]

45 голосов
/ 11 января 2011

Как подсказывает ваш собственный вопрос, ключом является домен, а не JPA .JPA - это просто фреймворк, который вы можете (и должны) использовать таким образом, который наилучшим образом соответствует вашей проблеме.Выбор неоптимального решения из-за фреймворка (или его пределов) обычно является предупреждающим звонком.

Когда мне нужен набор, и я никогда не беспокоюсь о порядке, я использую Set.Когда по какой-то причине важен порядок (упорядоченный список, упорядочение по дате и т. Д.), Тогда List.

Вы, похоже, хорошо знаете разницу между Collection, Set иList.Единственная причина использовать один против другого зависит только от ваших потребностей.Вы можете использовать их, чтобы сообщить пользователям вашего API (или вашего будущего себя) свойства вашей коллекции (которые могут быть неявными или скрытыми).

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

Например, когда я вижу List, я знаю, что он каким-то образом отсортировани что дубликаты являются приемлемыми или несущественными для этого случая.Когда я вижу Set, я обычно ожидаю, что у него не будет дубликатов и определенного порядка (если это не SortedSet).Когда я вижу Collection, я не ожидаю от него ничего большего, чем содержать некоторые сущности.

Относительно упорядочения списка ... Да, его можно сохранить.И даже если это не так, и вы просто используете @OrderBy, это все равно может быть полезно.Подумайте о примере журнала событий, отсортированного по метке времени по умолчанию.Искусственное переупорядочивание списка не имеет большого смысла, но все же может быть полезно, если он отсортирован по умолчанию.

25 голосов
/ 30 июля 2013

Вопрос об использовании набора или списка гораздо сложнее, я думаю. По крайней мере, когда вы используете hibernate в качестве реализации JPA. Если вы используете Список в спящем режиме, он автоматически переключается на парадигму «Сумки» , где могут существовать дубликаты.

И это решение оказывает существенное влияние на запросы, которые выполняет Hibernate. Вот небольшой пример:

Существует два объекта: сотрудник и компания , типичное отношение «многие ко многим». для отображения этих объектов друг на друга существует JoinTable (назовем его «employeeCompany»).

Вы выбираете Список типов данных для обеих организаций (Компания / Сотрудник)

Так что если вы решите удалить Сотрудник Джо из CompanyXY , hibernate выполнит следующие запросы:

delete from employeeCompany where employeeId = Joe;
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXA);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXB);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXC);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXD);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXE);

А теперь вопрос: почему, черт возьми, Hibernate не только выполняет этот запрос?

delete from employeeCompany where employeeId = Joe AND company = companyXY;

Ответ прост (и большое спасибо Нираву Ассару за его пост в блоге): Он не может . В мире сумок удалите все и вставьте все остальное - единственный правильный путь! Прочитайте это для большего разъяснения. http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

Теперь большой вывод:

Если вы выберете набор вместо списка в своем сотруднике / компании - организациях, у вас не возникнет этой проблемы, и будет выполнен только один запрос!

И почему это? Поскольку hibernate больше не находится в мире сумок (как вы знаете, Sets не допускает дублирования), и теперь возможно выполнение только одного запроса.

Так что решение между List и Sets не так просто, по крайней мере, когда речь идет о запросах и производительности!

7 голосов
/ 11 января 2011

Я обычно использую список.Я считаю, что List API гораздо более полезен и совместим с другими библиотеками, чем Set.Список легче перебирать и, как правило, более эффективен для большинства операций и памяти.

Тот факт, что отношения не могут иметь дубликаты и обычно не упорядочены, не должен требовать использования Set, вы можете использовать любой тип Collection, наиболееполезно для вашего приложения.

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

Вы можетеупорядочить отношения в JPA, используя @OrderBy или @ OrderColumn.

См. http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Ordering

Дубликаты обычно не поддерживаются в JPA, но некоторые отображения, такие как ElementCollections, могут поддерживать дубликаты.

3 голосов
/ 11 января 2011

Я использую:

  • Набор: когда предметы в коллекциях не имеют порядка и являются уникальными
  • Список: когда у товара есть заказ
0 голосов
/ 12 марта 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...