mybatis mysql 树形结构_Mybatis查询树形结构数据

数据表的设计

创建数据表

对于树形结构的数据库设计通常是基于继承关系设计的,也就是通过父ID关联来实现的。

一张树形结构的数据表基本的三个字段:id(自己)、name(名称)和parentid(父类编号)CREATE TABLE `tree` (

`id` int(20) NOT NULL COMMENT 'id',

`name` varchar(20) NOT NULL COMMENT '名称',

`parentid` int(20) NOT NULL COMMENT '父id',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入数据INSERT INTO `tree` VALUES ('100', '一级1', '0');

INSERT INTO `tree` VALUES ('101', '一级2', '0');

INSERT INTO `tree` VALUES ('201', '二级1-1', '100');

INSERT INTO `tree` VALUES ('202', '二级1-2', '100');

INSERT INTO `tree` VALUES ('203', '二级1-3', '100');

INSERT INTO `tree` VALUES ('211', '二级2-1', '101');

INSERT INTO `tree` VALUES ('212', '二级2-2', '101');

INSERT INTO `tree` VALUES ('213', '二级2-3', '101');

INSERT INTO `tree` VALUES ('301', '三级1-1-1', '201');

INSERT INTO `tree` VALUES ('302', '三级1-1-2', '201');

INSERT INTO `tree` VALUES ('311', '三级1-2-1', '202');

INSERT INTO `tree` VALUES ('321', '三级2-1-1', '211');

INSERT INTO `tree` VALUES ('322', '三级2-1-2', '211');

INSERT INTO `tree` VALUES ('331', '三级2-2-1', '212');

实体类@NoArgsConstructor

@ToString

public class implements Serializable{

private Integer id;

private String name;//名称

private Integer parentid;//父id

private List children=new ArrayList<>();//孩子

private static final long serialVersionUID = 1L;

}

实现方式

无论是通过Mybatis的递归查询还是通过代码的递归查询方式其思路都是一致的。先查询出所有一级节点

再跟进一级节点递归查询出其所有子节点

基于MyBatis的递归查询

基于注解

持久层接口:@Mapper

public interface TreeMapper{

@Select("select * from tree where parentid=#{parentId}") //根据父id查询出所有孩子

@Results({

@Result(id=true,property="id",column="id"),

@Result(property="name",column="name"),

@Result(property="parentid",column="parentid"),

@Result(property="children",column="id",javaType=java.util.List.class,

many=@Many(select="cn.ghjcloud.tree.dao.TreeMapper.selectChildrenByPId"))

//column为父节点Id

})

List selectChildrenByPId(Integer parentId);

@Select("select * from tree where parentid=0") //查询出所有一级目录

@Results({

@Result(id=true,property="id",column="id"),

@Result(property="name",column="name"),

@Result(property="parentid",column="parentid"),

@Result(property="children",column="id",javaType=java.util.List.class,

many=@Many(select="cn.ghjcloud.tree.dao.TreeMapper.selectChildrenByPId"))

})

List selectTreeList();

}

基于XML

TreeMapper.xml<?xml version="1.0" encoding="UTF-8"?>

select="selectChildrenByPId">

select * from tree where parentid=#{parentId}

select * from tree where parentid=0

接口:@Mapper

public interface TreeMapper{

List selectChildrenByPId(Integer parentId);

List selectTreeList();

}

注解对应的XML的元素注解xml@ResultsresultMap

@ResultResult

@Manycollection

column:实体类中对应的属性

property:mysql表中的字段

基于代码的递归查询

根据某个父节点递归获取子节点/**

* 根据某个父节点递归获取子节点

* @param parentTree 父节点

* @param list 全部节点

* @return

*/

public Tree getChildrenByPId(Tree parentTree,List list){

list.forEach((tree)->{

if(tree.getParentid().equals(parentTree.getId())){

tree=getChildrenByPId(tree,list);

parentTree.getChildren().add(tree);

}

});

return parentTree;

}

先获取所有一级节点,再调用上面的getChildrenByPId( )方法递归查询出所有子节点/**

* 递归获取树形结构的数据

* @param list 全部节点

* @return

*/

private List getTreeList(List list){

List treeList=new ArrayList<>();

list.forEach((tree -> {

//获取所有一级节点

if(tree.getParentid()==0){

treeList.add(tree);

}

}));

// 递归获取子节点

treeList.forEach((parentTree)->{

parentTree=this.getChildrenByPId(parentTree,list);

});

return treeList;

}

测试

基于MyBatis的递归查询

service层@Service

public class TreeService{

@Autowired

private TreeMapper treeMapper;

public List selectTreeList(){

List trees=treeMapper.selectTreeList();

return trees;

}

}

Controller层@RestController

@RequestMapping("/tree")

public class TreeController{

@Autowired

private TreeService treeService;

@GetMapping("/list")

public ResponseEntity> selectTreeList(){

return ResponseEntity.ok(treeService.selectTreeList());

}

}

基于代码的递归查询

Mapper接口@Repository

public interface TreeMapper extends Mapper<>{}

Service层@Service

public class TreeService{

@Autowired

private TreeMapper treeMapper;

public List findTreeList(){

//获取所有节点

List list=treeMapper.selectAll();

List treeList=this.getTreeList(list);

return treeList;

}

/**

* 递归获取树形结构的数据

* @param list 全部节点

* @return

*/

private List getTreeList(List list){

List treeList=new ArrayList<>();

list.forEach((tree -> {

//获取所有一级节点

if(tree.getParentid()==0){

treeList.add(tree);

}

}));

// 递归获取子节点

treeList.forEach((parentTree)->{

parentTree=this.getChildrenByPId(parentTree,list);

});

return treeList;

}

/**

* 根据某个父节点递归获取子节点

* @param parentTree 父节点

* @param list 全部节点

* @return

*/

public Tree getChildrenByPId(Tree parentTree,List list){

list.forEach((tree)->{

if(tree.getParentid().equals(parentTree.getId())){

tree=getChildrenByPId(tree,list);

parentTree.getChildren().add(tree);

}

});

return parentTree;

}

}

Controller层@RestController

@RequestMapping("/tree")

public class TreeController{

@Autowired

private TreeService treeService;

@GetMapping("/list")

public ResponseEntity> selectTreeList(){

return ResponseEntity.ok(treeService.findTreeList());

}

}

调试

result.PNG

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值