场景描述
笔者在编写个人网站时,正处于开发分类管理模块,以下便是分类管理最初样式,现欲将样式修改为父子结构样式
这是对应sql 建表语句,可以看出,parent字段决定对应id的数据就是这行数据的父亲
-- 分类
drop table if exists `category`;
create table `category` (
`id` bigint not null comment 'id',
`parent` bigint not null default 0 comment '父id',
`name` varchar(50) not null comment '书名',
`sort` int comment '顺序',
primary key (`id`)
) engine=innodb default charset=utf8mb4 comment='父类表';
insert into `category` (id, parent, name, sort) values (100, 000, '前端', 100);
insert into `category` (id, parent, name, sort) values (101, 100, 'Vue', 101);
insert into `category` (id, parent, name, sort) values (102, 100, 'HTML & CSS', 102);
insert into `category` (id, parent, name, sort) values (200, 000, '后端', 200);
insert into `category` (id, parent, name, sort) values (201, 200, 'java', 201);
insert into `category` (id, parent, name, sort) values (202, 200, 'spring', 202);
insert into `category` (id, parent, name, sort) values (203, 200, '并发', 203);
insert into `category` (id, parent, name, sort) values (204, 200, '数据结构', 204);
复制代码
如下图所示,在查看ant-design-vue后查找了对应表格组件文档,很明显只需要在返回的数据中加一个children数组,这个数组就会挂到本行数据下。
自顶向下实现功能
定义dto数据结构
很明显我们需要返回的数据中要有children数组,所以我们在dto对象中就需要添加这样一个成员变量private List<Category> children;
public class Category {
private Long id;
private Long parent;
private String name;
private Integer sort;
private List<Category> children;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getParent() {
return parent;
}
public void setParent(Long parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public List<Category> getChildren() {
return children;
}
public void setChildren(List<Category> children) {
this.children = children;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", parent=").append(parent);
sb.append(", name=").append(name);
sb.append(", sort=").append(sort);
sb.append("]");
return sb.toString();
}
}
复制代码
编写service代码
这里就是提前编写一个selectCategoryTree,声明返回值来预定我们编码预期。这就是自顶向下编码方式的技巧。
public List<Category> list(CategoryReq req) {
logger.info("开始获取所有分类列表,请求参数{}", JSONUtil.toJsonStr(req));
List<Category> categoryList = categoryMapper.selectCategoryTree();
return categoryList;
}
复制代码
编写基于传入的父节点id查询对应数据的mybatis接口
既然要查询父子结构,就得有查询子的sql,以下就是编写的语句
<!--查找对应父id的子节点-->
<select id="selectChildrenTree" resultType="com.shark.wiki.domain.Category">
select * from category where parent=#{parent}
</select>
复制代码
基于mybatis自定义resultMap
上文中我们已经定义了dto,所以在mybatis配置文件中我们也得将返回类型与之对应,注意,这个声明的最后一行就是该功能完成的重点部分。
使用select指向查询子的sql selectChildrenTree,使用 column将 resultMap的 ID作为参数parent传到selectChildrenTree中,从而返回list类型的数据存到当前resultMap中。
<!--自定义返回值类型 需与java代码对应上-->
<resultMap type="com.shark.wiki.domain.Category" id="CategoryTreeMap">
<result column="ID" property="id" javaType="long"/>
<result column="PARENT" property="parent" javaType="long"/>
<result column="NAME" property="name" javaType="string"/>
<result column="SORT" property="sort" javaType="int"/>
<collection property="children" javaType="list" column="{parent=ID}" select="selectChildrenTree"/>
</resultMap>
复制代码
编写查询父子结构数据的mybatis接口
有了上面一步的铺垫之后,查询父子结构的sql就变得很方便,只需查询出对应的父数据,再将返回类型设置为上文编写的CategoryTreeMap保证返回值能够于dto对象对应即可。
<!--返回CategoryTreeMap 这个map包含父节点对应子节点-->
<select id="selectCategoryTree" resultMap="CategoryTreeMap">
select * from category where parent=0
</select>
复制代码
实验
可以看到很完美的实现我们的预期数据机构
也达到了组件的要求,自此功能实现完成,打完收工




近期评论