我的考虑是用一个level字段代替lft和rgt字段,level字段维护着Category实例的层级关系。
例如,将root的level定义为1(这个在数据库或程序中可配),那么Child 1的level就为1|${id}(其中'|'为Level分层标记,${id}表示当前数据Id或其它可唯一标识的字段值),假定为1|2,同理Child 1.1的level就是1|2|3。
类结构如下所示:使用的是annotation的hibernate
- @Entity
- public class Category implements Serializable {
- /** Level分层标记 */
- public static final String LEVEL_SPLIT = "|";
- @Id
- @GeneratedValue
- private Integer id;
- /** 名称 */
- private String name;
- /** level */
- private String level;
- /** 删除标记 */
- private Boolean delFlag;
- /** 下级的类别 */
- @OneToMany(fetch = FetchType.LAZY, mappedBy="parent")
- @OrderBy("id")
- private List<Category> children = new ArrayList<Category>();
- /** 上级的类别 */
- @ManyToOne
- @JoinColumn(name = "category_id")
- private Category parent;
- // 省略所有 getter/setter 方法...
- }
维护后数据库中的数据如下:
查找某个特定类型及其子类,只需要获得当前类型的level值,然后查找 (level like 'xxxx%')即可。如下所示:
Rails中需要重写Category中类似find的方法。