前言:
当前各位老铁们对“java 实现多种分类查询”大约比较看重,咱们都想要了解一些“java 实现多种分类查询”的相关内容。那么小编也在网络上收集了一些对于“java 实现多种分类查询””的相关文章,希望我们能喜欢,朋友们快快来学习一下吧!需求:生活中常见的页面一次性展示一级商品、二级商品、三级商品…甚至更多级别的商品
大家通常会想到数据库一张表设计商品分类,有等级level字段,parent_id父id等关键设计字段
实体类也通常设计本实体关联子集的List
@TableName("item_cat")@Data@Accessors(chain = true)public class ItemCat extends BasePojo{ @TableId(type = IdType.AUTO) private Integer id; //定义主键 private Integer parentId; //定义父级菜单 private String name; //分类名称 private Boolean status; //分类状态 0 停用 1 正常 private Integer level; //商品分类等级 1 2 3 @TableField(exist = false) private List<ItemCat> children;}
但java后台代码返回的lsit怎么包含各层级商品分类结构呢?
假设这里商品等级最多三级, 相信很多人首先想到的思路是:
先查询出一级商品,然后遍历一级商品,拿着一级商品的id去数据库查二级商品,然后又依次遍历二级商品,拿着二级商品的id去数据库查三级商品,常规代码如下
/** * 3层商品分类嵌套 1一级分类(children(2级商品分类)) * 2一级分类(children(3级商品分类)) * 一级查询条件 parent_id=0 * 二级查询条件 parent_id=一级的ID * 三级查询条件 parent_id=二级的ID */ @Override public List<ItemCat> findItemCatList(Integer level) { QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("parent_id", 0); List<ItemCat> list = itemCatMapper.selectList(queryWrapper); for (ItemCat oneItemCat : list) { queryWrapper.clear(); queryWrapper.eq("parent_id", oneItemCat.getId()); List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper); oneItemCat.setChildren(twoList); for (ItemCat children : twoList) { queryWrapper.clear(); queryWrapper.eq("parent_id", children.getId()); children.setChildren(itemCatMapper.selectList(queryWrapper)); } } return list; }
大家想过没有,以上代码执行效率非常低下,最大问题在于for循环的嵌套,嵌套太多层导致程序运行速度慢,占用内存高。假设一级商品有500种,对应的二级商品又有500种,这样至少查询数据库500*500=25000次,与数据库交互的频次太多,导致性能出现问题,所以以上代码非常不可取。
现要求,只查询一次数据库,即可获取3级商品分类信息。
大家想到思路没?没有想到的可以学习以下设计思路和代码,想到啦,看看以下思路是否是同一种思路,有好的建议,欢迎分享
设计:
查询数据库中的所有的数据信息
key: parentId value: 当前parentId下的所有的子级 封装成Map集合
将查询的结果封装到Map集合中
如需获取子级数据信息,通过getKey 即可获取数据
代码如下
/** * 1.准备Map集合,实现数据封装 Map<Key,Value> Map<parentId,List<ItemCat>> * 2.业务说明 * map中的key~~~parentId 不存在 可以存储该key 设定key,同时封装一个list集合,将自己作为第一个元素封装到其中 * 存在 根据key获取所有子集集合,将自己追加进去,形成第二个元素 */ public Map<Integer, List<ItemCat>> itemCatMap() { Map<Integer, List<ItemCat>> map = new HashMap<>(); //1.查询所有的数据库信息 List<ItemCat> list = itemCatMapper.selectList(null); for (ItemCat itemCat : list) { int parentId = itemCat.getParentId(); if (map.containsKey(parentId)) {//有key 获取list集合 将自己追加到集合中 List<ItemCat> exeList = map.get(parentId);//引用对象,无需在put exeList.add(itemCat); } else {//没有key--将自己封装为第一个list元素 List<ItemCat> firstList = new ArrayList<>(); firstList.add(itemCat); map.put(parentId, firstList); } } return map; } @Override public List<ItemCat> findItemCatList(Integer level) { Map<Integer, List<ItemCat>> map = itemCatMap(); //1.如果level=1 说明获取一级商品分类信息 parent_id=0 if (level == 1) { return map.get(0); } if (level == 2) {//2.获取二级商品信息, return getTwoList(map); } //3.获取三级商品信息 //3.1 获取二级商品分类信息 List<ItemCat> oneList = getTwoList(map); for (ItemCat oneItemCat : oneList) { List<ItemCat> twoList = oneItemCat.getChildren(); //如果该元素没有2级列表,则跳过本次循环 if (twoList == null || twoList.size() == 0) { continue; } for (ItemCat twoItemCat : twoList) { //查询三级商品分类 条件parentId=2级id twoItemCat.setChildren(map.get(twoItemCat.getId())); } } return oneList; } /** * 获取二级商品分类信息(注:二级嵌套在一级集合中,所以永远返回的都是第一级) */ public List<ItemCat> getTwoList(Map<Integer, List<ItemCat>> map) { List<ItemCat> oneList = map.get(0); for (ItemCat oneItemCat : oneList) {//查询二级 parentId=1级id List<ItemCat> twoList = map.get(oneItemCat.getId()); oneItemCat.setChildren(twoList); } //二级嵌套在一级集合中,所以永远返回的都是一级 return oneList; }
标签: #java 实现多种分类查询 #java 实现多种分类查询方式 #java 实现多种分类查询方式的方法 #java 实现多种分类查询方式的方法是