The third-level directory of the third-level classification cannot be loaded. The back-end interface can return all data on the front-end.

Project scene: The three-category classification part is not displayed

实现ElementUI中三级分类的功能,发现没有前端三级目录的二级目录可以新建三级目录,数据库中也有数据,但是无法在前端显示!后端的接口没有返回数据库的数据。
Insert image description here


Problem description: Directories after database serial number 128 are not displayed

提示:这里描述项目中遇到的问题:

For example: data is lost from time to time during data transmission, and occasionally part of the data is lost
Data receiving code in APP:

@Override
	public void run() {
    
    
		bytes = mmInStream.read(buffer);
		mHandler.obtainMessage(READ_DATA, bytes, -1, buffer).sendToTarget();
	}

Cause analysis: Database &JAVA backend

Tips: For example: for a directory created after 骑行运动 the headphone directory, the front-end interface shows that the creation is successful, and the database also has data, but it will not be displayed on the front-end.

Insert image description here
Insert image description here
Insert image description here
The newly created data in the database is successful, but the newly created third-level stroller directory will not be displayed during cycling.
Insert image description here
The IDEA log print record shows that the insertion was successful
Insert image description here
Use sql to query the secondary directory whose parent_cid is 128
Insert image description here

Then use the interface to test the front-end interface without a stroller.
Insert image description here

Code:

backend interface

//controller层
  /**
     * 查出所有分类以及子分类,以树形结构组装起来
     */
    @RequestMapping("/list/tree")
    public R list(){
    
    
        List<CategoryEntity> entities = categoryService.listWithTree();
        return R.ok().put("data", entities);
    }

//接口Service层
    List<CategoryEntity> listWithTree();


Specific implementation of Service

    @Override
    public List<CategoryEntity> listWithTree() {
    
    
        //1、查出所有分类
        List<CategoryEntity> entities = baseMapper.selectList(null);

        //2、 组装成父子的树形结构
            //2.1) 找到所有一级分类(父分类id为0)
        List<CategoryEntity> level1Menus = entities.stream().filter(categoryEntity ->
                categoryEntity.getCatLevel() == 1
        ).map((menu)->{
    
    
//            System.out.println(menu);
            menu.setChildren(getChildrens(menu,entities));
//            menu.setChildren(getSubtreeById(menu.getCatId(), entities));
            return menu;
        }).sorted((menu1,menu2)->{
    
    
            return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
        }).collect(Collectors.toList());
        return level1Menus;
    }

    //递归查找所有菜单的子菜单
    private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
    
    

        //1.找到当前菜单的子菜单(每个子菜单还有子菜单)
//        Stream<CategoryEntity> categoryEntityStream = all.stream().filter(entity -> (long)entity.getParentCid() == (long)root.getCatId()); //出bug语句
        Stream<CategoryEntity> categoryEntityStream = all.stream().filter(entity -> entity.getParentCid() == root.getCatId());

        Stream<CategoryEntity> mapEntityStream = categoryEntityStream.map(item -> {
    
    
            item.setChildren(getChildrens(item,all));
            return item;
        });

        List<CategoryEntity> children = mapEntityStream.sorted((menu1,menu2)->{
    
    
            return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
        }).collect(Collectors.toList());
        return  children;

solution:

Tip: Second-level directories with CatIDs after 128 will not display the third-level directories in the database.

1 Database serial number problem

DROP TABLE IF EXISTS `pms_category`;

CREATE TABLE `pms_category` (
  `cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',
  `name` char(50) DEFAULT NULL COMMENT '分类名称',
  `parent_cid` bigint(20) DEFAULT NULL COMMENT '父分类id',
  `cat_level` int(11) DEFAULT NULL COMMENT '层级',
  `show_status` tinyint(4) DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  `icon` char(255) DEFAULT NULL COMMENT '图标地址',
  `product_unit` char(50) DEFAULT NULL COMMENT '计量单位',
  `product_count` int(11) DEFAULT NULL COMMENT '商品数量',
  PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1424 DEFAULT CHARSET=utf8mb4 COMMENT='商品三级分类';

AUTO_INCREMENT=1424 The original database was 1434, but it was changed to 1424 to allow cat_id to increase automatically. The serial number continued to increase, and the problem was still solved. At first I thought it was because there were many garbled serial numbers in the database, but later I discovered that there was a problem with the 128 secondary directory.

2 JAVA level

1 Change recursive to non-recursive writing

        //原版代码
//        List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
    
    
//            return categoryEntity.getParentCid() == root.getCatId();
//        }).map(categoryEntity->{
    
    
//            //2.利用映射递归查找 子菜单的子菜单
//            categoryEntity.setChildren(getChildrens(categoryEntity,all));
//            return categoryEntity;
//        }).sorted((menu1,menu2)->{
    
    
//            //3.对当前菜单进行排序,升序排序
//            return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
//        }).collect(Collectors.toList());
//
//        return children;

        //非递归写法
//        List<CategoryEntity> result = new ArrayList<>();
//        for (int i = 0; i < all.size(); i++){
    
    
//            CategoryEntity entity = all.get(i);
//            if (entity.getParentCid() == root.getCatId()) {
    
    
//                result.add(entity);
//            }
//        }
//        System.out.println(result);
//
//        for (int i = 0; i < result.size(); i++){
    
    
//            CategoryEntity current = result.get(i);
//            List<CategoryEntity> sub = new ArrayList<>();
//            for (int j = 0; j < all.size(); j++){
    
    
//                CategoryEntity entity = all.get(j);
//                if (entity.getParentCid() == current.getCatId()) {
    
    
//                    List<CategoryEntity> subsub = new ArrayList<>();
//                    for (int k = 0; k < all.size(); k++){
    
    
//                        CategoryEntity subEntity = all.get(k);
//                        if (subEntity.getParentCid() == entity.getCatId()){
    
    
//                            subsub.add(subEntity);
//                        }
//                    }
//                    entity.setChildren(subsub);
//                    sub.add(entity);
//                }
//            }
//            current.setChildren(sub);
//        }
//
//        return result;

Or not

2 Rewrite the interface: Query the subdirectory with cat_id 128

//Controller层
    /**
     * 信息
     */
    @RequestMapping("/info/{catId}")
    //@RequiresPermissions("product:category:info")
    public R info(@PathVariable("catId") Long catId) {
    
    

        CategoryEntity category = categoryService.getById(catId);
        return R.ok().put("data", category);
    }

//Service层
    List<CategoryEntity> getSubtreeById(long catId);

Interface implementation function

    @Override
    public List<CategoryEntity> getSubtreeById(long catId) {
    
    
        List<CategoryEntity> entities = baseMapper.selectList(null);

        List<CategoryEntity> filterList = entities.stream().filter(item -> item.getParentCid() == catId)
                .map(item -> {
    
    
                    item.setChildren(getSubtreeById(item.getCatId()));
                    return item;})
                .collect(Collectors.toList());
        return filterList;
    }

Front-end port test: All directories with a parent ID of 128 can be queried directly through the id, that is, the parent directory of the stroller has been found.
Insert image description here
Later, rewriting the program according to this idea can realize the function of displaying all subdirectories in three-level classification, but the cause of the bug is not clear! ! !

Solution: Add (long) downward transformation to automatically unbox

Change a line of code
Insert image description here
It is because the recursive call is made too many times and it is automatically boxed into a Long object. However, the source code implementation of Long object boxing has a lot to do with 128! ! The Integer in the explanation below is the same. (Integer) 128 == (Integer) 128 is false, so the second-level directories after 128 do not satisfy this judgment, so their third-level directories cannot be loaded! ! !
Please see the reference for specific code implementation! ! !

Integer class, the values ​​between -128~127 are taken directly from the cache. (Integer)127 == (Integer)127 After boxing on both sides, it actually points to the same object in the heap memory, which is greater than 127 Then a new object is returned. (Integer)128 == (Integer)128. After boxing as a reference type, there is no caching and it points to different objects in the heap memory, so the comparison result is false. As for why it is necessary to cache, if it is not cached, a new object will be created every time, which consumes a lot of resources, so some commonly used numbers are cached to reduce resource consumption.
————————————————
Copyright statement: This article is written by the CSDN blogger "Sometimes I do it too" This original article follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this statement when reprinting.
Original link: https://blog.csdn.net/weixin_43849277/article/details/108275997

Summary: Use recursion with caution, and be familiar with the hidden mechanism of autoboxing.

Don’t use recursion casually during development! ! ! Debug is difficult to adjust, and when combined with other problems, it really makes my scalp numb! ! ! This article only briefly describes the process of finding core bugs, but Debug sets various conditional breakpoints, checks Tomcat source code, StackFlow looks at English, etc. The bugs that bothered me for a day were finally solved reasonably by Brother Guan! ! !

It is recommended to read the Alibaba Development Manual’s suggestions on the use of recursion! ! !

Guess you like

Origin blog.csdn.net/qq_41398619/article/details/133897704