Java文件上传和多级数据操作

目录

一、数据封装(获取多级数据优化代码)

  1).获取一、二级数据信息  

  2).获取全部数据信息 

  3).调用

二、多级数据删除(子父级关系)

三、文件上传

四、分页工具类


一、数据封装(获取多级数据优化代码)

多级分类一次性查询,利用map集合封装,使用时直接调用map集合,减少查询数据库的次数,优化性能

/**
     * 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;
    }

  1).获取一、二级数据信息  

private List<ItemCat> getTwoList(Map<Integer, List<ItemCat>> map) {
        //1.先获取一级列表
        List<ItemCat> oneList = map.get(0);
        //2.根据一级查询二级
        for(ItemCat oneItemCat :oneList){
            //查询二级,所以parentId是一级的Id
            int parentId = oneItemCat.getId();
            List<ItemCat> twoList = map.get(parentId);
            //封装数据
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

  2).获取全部数据信息 

 private List<ItemCat> getThreeList(Map<Integer, List<ItemCat>> map) {
        //获取一级和二级
        List<ItemCat> oneList = getTwoList(map);
        //封装三级,遍历二级菜单,之后封装.
        for(ItemCat oneItemCat : oneList){
            //获取二级集合
            List<ItemCat> twoList = oneItemCat.getChildren();
            if(twoList == null || twoList.size() == 0){
                System.out.println("执行跳过循环操作");
                //由于业务数据不合理,跳过本次循环,执行下一次
                continue;
            }
            for (ItemCat twoItemCat : twoList){
                //查询三级列表,需要parentId=二级Id
                int parentId = twoItemCat.getId();
                List<ItemCat> threeList = map.get(parentId);
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

  3).调用

 /**
     * level 1 只查询一级商品分类
     *       2 查询一级/二级  嵌套封装
     *       3 查询一级/二级/三级   嵌套封装
     * @param level
     * @return
     */
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        //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);

        return list;
    }

二、多级数据删除(子父级关系)

如果删除的是数据有子级,需要把子级数据同时删除,否则数据库会存下死数据。

/**
     * 需求: 删除分类信息
     * 条件: 如果有子级,应该先删除子级.
     * Sql: DELETE FROM item_cat WHERE (parent_id IN (?,?) OR parent_id = ? OR id = ?)
     * @param itemCat
     */
    @Transactional
    public void deleteItemCats(ItemCat itemCat) {
        int level = itemCat.getLevel();
        if(level == 3){
            //表示需要删除的数据是三级菜单,可以直接删除
            itemCatMapper.deleteById(itemCat.getId());
        }

        if(level == 2){
            QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id",itemCat.getId())
                        .or()
                        .eq("id",itemCat.getId());
            itemCatMapper.delete(queryWrapper);
        }

        if(level == 1){
            //1.必须获取二级ID
            QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id",itemCat.getId());
            //2获取结果的第一列字段(主键)  二级Id
            List twoIdsList = itemCatMapper.selectObjs(queryWrapper);

            //3.删除三级的数据
            queryWrapper.clear();
            //删除parent_id中包含二级Id的数据,实则删除的是三级数据
            queryWrapper.in(twoIdsList.size()>0,"parent_id",twoIdsList)
                        .or()
                        //删除parent_id 等于一级ID的,实则删除的是二级数据
                        .eq("parent_id",itemCat.getId())
                        .or()
                        //删除id=一级Id  则删除一级数据.
                        .eq("id",itemCat.getId() );
            itemCatMapper.delete(queryWrapper);
        }
    }

三、文件上传

@Service
public class FileServiceImpl implements FileService{

    /**
     * 规则说明:
     *   文件磁盘地址:  F:/images/yyyy/MM/dd/uuid.jpg
     *   网络访问地址:  http://xxx.com/yyyy/MM/dd/uuid.jpg
     */
    //private String localDir = "D:/images";            //本地磁盘前缀
    private String localDir = "/usr/local/src/images";  //设定Linux目录
    private String preURLPath = "http://xxx.com";  //网络访问域名


    /**
     * 1.校验文件上传的类型   jpg|png|gif
     * 2.应该校验文件是否为恶意程序.   木马.exe.jpg
     * 3.为了提高检索效率  应该分目录存储.  1.hash方式  xx/xx/xx/xx 分布不均
     *                                   2.日期格式   yyyy/MM/dd  目录不断增长
     * 4.防止文件重名        UUID.jpg
     * @param file
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile file) {
        //1.获取图片名称    demo: abc.jpg  abc.JPG
        String fileName = file.getOriginalFilename();
        //bug说明: 由于windows系统不区分大小写,所以将字母全部转化为小写
        fileName = fileName.toLowerCase();
        //利用正则判断是否为图片.
        if(!fileName.matches("^.+\\.(jpg|png|gif)$")){
            //如果不是图片,则返回null
            return null;
        }

        //2.检查文件是否为恶意程序.
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if(width == 0 || height == 0){
                //说明文件不是图片.
                return null;
            }

            //3.根据时间实现目录的创建 时间--yyyy/MM/dd
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                            .format(new Date());
            // "G:/images/2021/11/11
            String localDirPath = localDir + dateDir;
            //创建目录
            File dirFile = new File(localDirPath);
            if(!dirFile.exists()){
                dirFile.mkdirs();
            }

            //4. 使用uuid替换文件名称 唯一:系统内部唯一
            String uuid = UUID.randomUUID().toString()
                    .replace("-","");
            //截取文件的后缀  aa.bb.cc.jpg
            int index = fileName.lastIndexOf(".");
            //获取类型  .jpg
            String fileType = fileName.substring(index);
            String newFileName = uuid + fileType;

            //5.实现文件上传操作  目录/文件名称
            String realFilePath = localDirPath + newFileName;
            file.transferTo(new File(realFilePath));
            System.out.println("文件上传成功!!!");

            /*
             *  6.封装返回值
             *  封装虚拟路径 在各个系统之间可以灵活切换,只保存动态变化的目录
             *  path = 时间/uuid.type
             *  网络地址://http://image.jt.com/2021/11/11/a.jpg
             */
            String virtualPath = dateDir + newFileName;
            String url = preURLPath+ virtualPath;
            System.out.println("磁盘地址:"+realFilePath);
            System.out.println("网络地址:"+url);
            return new ImageVO(virtualPath,url,newFileName);

        } catch (IOException e) {
            e.printStackTrace();
            return null;    //表示程序有问题
        }
    }

    /**
     * 实现思路:
     *      1.根据虚拟地址,拼接磁盘地址
     *      2.判断文件是否存在
     *      3.实现文件删除
     * @param virtualPath
     */
    @Override
    public void deleteFile(String virtualPath) {
        //1.生成本地磁盘地址
        String path = localDir + virtualPath;
        System.out.println(path);
        File file = new File(path);
        if(file.exists()){
            file.delete();
        }
    }
}

四、分页工具类

public class PageUtil {
    public static List startPage(List list, Integer pageNum,Integer pageSize) {
        if (list == null) {
            return null;
        }
        if (list.size() == 0) {
            return null;
        }

        Integer count = list.size(); // 记录总数
        Integer pageCount = 0; // 页数
        if (count % pageSize == 0) {
            pageCount = count / pageSize;
        } else {
            pageCount = count / pageSize + 1;
        }

        int fromIndex = 0; // 开始索引
        int toIndex = 0; // 结束索引

        if (pageNum != pageCount) {
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = fromIndex + pageSize;
        } else {
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = count;
        }

        List pageList = list.subList(fromIndex, toIndex);

        return pageList;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值