Как показать древовидные ответы на сообщение? Java и Hibernate - PullRequest
2 голосов
/ 02 февраля 2011

У меня есть сообщение, и мне нужно показать десять (например) первых ответов «root» со всеми ответами на себя, и оно должно выглядеть как дерево.(Стандартные сообщения и просмотр дерева ответов, вы знаете).Итак, вопрос - как получить его из БД - я использую hibernate, и на самом деле у него будет много времени - для рекурсивного извлечения самой коллекции ВЕСЬ со всеми поддеревьями.(И, может быть, это хорошо только для небольших коллекций, в противном случае рекурсия вызовет переполнение стека (Ха-ха. Вот и мы :)) Есть ли более эффективное решение?

Так что теперь у меня есть что-то вроде кода ниже, но мне нужен еще один способ (BaseEntry является классом как для сообщения, так и для любого ответа):

@Entity public class BaseEntry extends VersionedEntity {
private @Nullable BaseEntry parent;

@ManyToOne
@ForeignKey(name="base_entry_parent__base_entry_fk")
@Nullable public BaseEntry getParent()
{
    return parent;
}

@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
private List<BaseEntry> children;

...

Не могли бы вы что-нибудь посоветовать, пожалуйста?

1 Ответ

3 голосов
/ 02 февраля 2011

Существует более эффективное решение, но оно будет означать полное изменение того, как вы храните вещи в базе данных.Прочитайте http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/, чтобы узнать, как использовать вложенные множества деревьев.Такой подход делает записи дорогими, но читает намного, намного дешевле.Если вы добавите флаг для корневых узлов, которые вы проиндексировали, то будет легко получить ваш список корневых узлов, а затем извлечь поддеревья.

Существует существенная модификация, которую я бы предложил в их подходе.Они использовали наборы целых чисел без пробелов вообще.Это означает, что каждая запись должна перенумеровывать все в дереве.Это делает запись на лот более дорогой.Но предположим, что вместо этого вы запускаете корневые узлы с пробелами 2 ** 20, и каждый дочерний узел по умолчанию занимает половину доступного для него пространства.Тогда вам вообще не нужно делать никакую нумерацию, пока у вас не будет набора ответов с глубиной 21 или шириной.И когда вы делаете перенумерацию, вы можете перенумеровать только поддерево под этим корневым узлом, потому что у вас еще есть много пробелов для использования.

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