记录新增修改时间/全局异常处理/父子级查询

 修改时间和新增时间

package com.jt.pojo;
//pojo基类,完成2个任务,2个日期,实现序列化
@Data
@Accessors(chain=true)
public class BasePojo implements Serializable{
	@TableField(fill = FieldFill.INSERT)
	private Date created;	//表示入库时需要赋值
	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date updated;	//表示入库/更新时赋值.
}



package com.jt.config;
@Component//将对象交给spring容器管理
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        Date date = new Date();
        this.setFieldValByName("created",date,metaObject);
        this.setFieldValByName("updated",date,metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Date date = new Date();
        this.setFieldValByName("updated",date,metaObject);
    }
}

spring整合全局异常处理

package com.jt.advice;

/**
 * Spring为了整合全局异常的处理  开发了如下的注解
 *  1.@RestControllerAdvice //定义全局异常的处理类 返回值JSON串
 *  2.@ExceptionHandler     标识拦截的异常的类型,如果类型匹配,则执行方法
 */
@RestControllerAdvice   //只对Controller层有效
public class MyExceptionAdvice {

    //写法:1.运行时异常(通用)  2.自定义异常信息  3.拦截所有异常Exception.class
    @ExceptionHandler(RuntimeException.class)
    public Object exception(Exception e){
        e.printStackTrace();    //输出异常信息
        //需求: 如果遇到异常,应该提示用户201/失败信息.
        return SysResult.fail();
    }
}

本父子级关系(商品分类),查询次数太多淘汰

/**
         * 业务: 查询3级商品分类信息
         *      1. 一级中嵌套二级集合
         *      2. 二级菜单嵌套三级集合.
         *
         * 1.0版本: for循环嵌套结构  暂时不考虑level 最好理解的
         * 常识:
         *      1.用户第一次查询数据库 需要建立链接.
         *      2.第二次查询 从链接池中动态获取链接 所以速度更快!!!
         *
         *  思考: 该业务查询了多少次数据库??? 第一层循环10个  第二层循环10 总查询数=10*10=100次
         *       如何优化查询策略!!!!
         * @param level
         * @return
         */
    /*@Override
    public List<ItemCat> findItemCatList(Integer level) {
        //性能问题:!!!!!
        long startTime = System.currentTimeMillis();

        //1.查询一级商品分类信息
        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", 0);
        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);

        //2.查询二级商品分类信息  遍历一级集合
        for(ItemCat oneItemCat : oneList){
            queryWrapper.clear();   //清空条件
            queryWrapper.eq("parent_id", oneItemCat.getId());
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);

            //3.查询三级商品分类信息  遍历
            for(ItemCat twoItemCat : twoList){
                queryWrapper.clear();
                queryWrapper.eq("parent_id", twoItemCat.getId());
                List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
                //将三级封装给二级
                twoItemCat.setChildren(threeList);
            }
            //3.将二级记录封装给一级
            oneItemCat.setChildren(twoList);
        }

        //记录程序的结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("查询耗时:"+(endTime - startTime)+"毫秒");
        return oneList;
    }*/

父子级关系(商品分类)优化版

@Service
public class ItemCatServiceImpl implements ItemCatService {
    @Autowired
    private ItemCatMapper itemCatMapper;

    /**
     * 1.封装Map集合   Map<Key=父级ID,value=List<ItemCat对象>>
     * 2.说明:  将所有的数据库的父子关系,进行封装.(没有嵌套!!!!)
     * 3.优势:  只查询一次数据库,就可以完成父子关系的封装.
     策略:
     *      1. key不存在, 准备一个新List集合,将自己当作第一个元素追加
     *      2. key存在,  获取原有list集合,将自己追加.
     *
     */
    public Map<Integer,List<ItemCat>> initMap(){
        //Map中包含了所有的父子级关系.
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //1.查询item_cat表中的所有的记录(1/2/3级菜单)
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //2.实现数据的封装
        for(ItemCat itemCat : itemCatList){
            int key = itemCat.getParentId();
            if(map.containsKey(key)){ //存在
                List<ItemCat> list = map.get(key);
                //将自己追加到其中
                list.add(itemCat);
            }else{  //不存在: 准备List集合,将自己作为第一个元素封装
                List<ItemCat> list = new ArrayList<>();
                list.add(itemCat);
                map.put(key,list);
            }
        }
        //将封装的数据进行返回.
        return map;
    }

    /**
     * level 1 只查询一级商品分类
     *       2 查询一级/二级  嵌套封装
     *       3 查询一级/二级/三级   嵌套封装
     * @param level
     * @return
     */
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //Map集合里边封装的是所有的父子级关系.
        Map<Integer,List<ItemCat>> map = initMap();
        if(level == 1){ //只获取1级菜单. parent_id = 0
            return map.get(0);
        }
        //用户查询1/2级商品分类信息
        if(level == 2){
            return getLevel2List(map);
        }

        //如果程序执行到这里,则说明用户查询的是1-2-3级菜单
        List<ItemCat> list = getLevel3List(map);
        long endTime = System.currentTimeMillis();
        System.out.println("耗时:"+(endTime-startTime)+"毫秒");
        return list;
    }

public List<ItemCat> getLevel3List(Map<Integer, List<ItemCat>> map) {
        //1.先查询1-2级
        List<ItemCat> oneList = getLevel2List(map);

        //2.遍历集合
        for(ItemCat oneItemCat : oneList){
            //获取二级集合信息
            List<ItemCat> twoList = oneItemCat.getChildren();
            if(twoList == null || twoList.size() ==0){
                //当前一级菜单没有二级元素.结束本次循环,开始下一次!!!
                continue;
            }
            //该元素有二级,应该查询三级.
            for(ItemCat twoItemCat : twoList){
                List<ItemCat> threeList = map.get(twoItemCat.getId());
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    //查询一级和二级信息
    public List<ItemCat> getLevel2List(Map<Integer, List<ItemCat>> map) {
        //思路: 先查询一级,之后循环遍历,再次封装2级
        //1.获取一级
        List<ItemCat> oneList = map.get(0);
        for(ItemCat oneItemCat : oneList){
            //2.如何根据一级查询二级? 通过Map集合获取
            List<ItemCat> twoList = map.get(oneItemCat.getId());
            //3.实现了一级二级的封装
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值