Отображение дерева с помощью MyBatis?

Я пытаюсь запутаться, настроив древовидную структуру и сопоставив ее с MyBatis. Моя таблица определяется как;

CREATE TABLE `Hierarchy` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parentId` int(11) NULL DEFAULT NULL,
  `name` varchar(45) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Я попытался сделать ассоциацию в MyBatis с;

@Select(SELECT_ALL)
    @Results(value = {
            @Result(property = "id", column = "id"),
            @Result(property = "children", column = "parentId",
                    jdbcType = JdbcType.NUMERIC,
                    many = @Many(select = "selectById")),
            @Result(property = "name", column = "name")
    })
    List<Hierarchy> selectAll();

В моем классе есть;

private Integer id;
private Integer parentId;
private String name;
private List<Hierarchy> children;

Я довольно быстро понял, что это не сработает, так как это приведет к обратному связыванию, и я несколько раз возвращаю дочерние элементы в набор результатов. Так какой ответ? Должен ли я выполнять итерацию после выбора и заполнения своих детей таким образом?

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

Итак, кто-нибудь снял это раньше? В чем хитрость?


person Random Coder    schedule 15.02.2015    source источник


Ответы (1)


Я сделал это несколько лет назад с iBatis и никогда не был доволен результатом. Мое дерево было доступно только для чтения, что упростило код. Мне также нужно было перемещаться по дереву вверх и вниз, чтобы каждая запись имела указатель на родительский класс. Алгоритм (с использованием ваших имен классов и т. д.):

  1. Прочитайте всю таблицу базы данных в список. Это просто использовало «выбрать * из иерархии» и стандартное сопоставление результатов.
  2. Выполните итерацию по списку, сформировав индекс (Map) для первичных ключей и отметив корневой элемент, который должен быть единственной записью с нулевым parentId.
  3. Повторите список во второй раз, просматривая родительскую запись каждого элемента на карте и вызывая this.setParent(Hierarchy parent) и parent.addChild(Hierarchy child)

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

person kiwiron    schedule 15.02.2015
comment
Будет ли здесь использоваться самосоединение? - person Shailesh Pratapwar; 14.05.2015
comment
@Shinchan Я пробовал это, и самосоединение - это вариант для извлечения данных, если вы знаете максимальную глубину дерева. Но я понятия не имею, как упорядочить файлы сопоставления iBatis/myBatis для создания правильно связанного дерева. Есть предположения? - person kiwiron; 15.05.2015