用 MyBatis 映射一棵树?

Mapping a tree with MyBatis?

我试图通过设置树结构并将其映射到 MyBatis 来混淆我的方式。我的 table 定义为;

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();

我的class有;

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

我很快意识到这是行不通的,因为它最终会反向关联,而且我在结果集中多次返回 children。那么答案是什么?我是否必须在执行 select 并以这种方式填充我的 children 之后进行迭代?

我尝试了几种方法,但它们看起来都非常低效,而且我发现如果不迭代列表两次就很难处理 forward-references of parent id。

所以,以前有人成功过吗?有什么诀窍?

几年前我用 iBatis 做过这个,对结果一直不满意。我的树是只读的,这简化了代码。我还需要上下导航树,因此每条记录都有一个父 class 指针。该算法(使用您的 class 名称等)是:

  1. 将整个数据库table读入列表。这只是使用了 "select * from hierarchy" 和标准结果映射。
  2. 遍历列表,在主键上形成索引 (Map),并标记根元素,它应该是唯一具有 null parentId 的记录。
  3. 第二次遍历列表,从Map中查找每一项的父记录,并调用this.setParent(Hierarchy parent)parent.addChild(层次结构子)

这一切都很好,但远非优雅。正如您所指出的,它需要通过列表两次。如果您发现更好的方法,欢迎分享。