I'm trying to muddle my way thru setting up a tree structure and mapping it with MyBatis. My table is defined as;
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;
I tried to do an association in MyBatis with;
@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();
My class has;
private Integer id;
private Integer parentId;
private String name;
private List<Hierarchy> children;
I pretty quickly realized this wouldn't work, since it's going to wind up associating backwards, and I get children back multiple times in the result set. So what's the answer? Do I have to iterate after I do the select and populate my children that way?
I tried a few approaches to that, but they all seem horribly inefficient, and I'm finding it hard to handle forward-references of parent id's without iterating the list twice.
So, has anyone pulled this off before? What's the trick?
I did this a few years ago with iBatis, and was never satisfied with the result. My tree was read-only, which simplified the code. I also needed to navigate the tree up and down, so each record had a parent class pointer. The algorithm (using your class names etc) was:
This all works fine but is far from elegant. As you noted, it needs two passes through the list. If you find a better method, please share it.