项目实用方法

一、实现商品分类查询

1、将数据导入Map集合

    /**
     * 实现商品分类查询
     * Map<Integer,List<ItemCat>>
     *      0,一级菜单集合
     *      一级Id,二级菜单集合
     *      二级Id,三级菜单集合
     * 业务思路:
     *      判断是否已经存在parentId
     *      不存在: 我是第一个元素 封装到list中 之后保存到Map中
     *      存在: 获取list集合,将自己追加到其中
     * 扩展知识: map每次都需要查询数据库,如果采用redis缓存,则性能极大的提升 2ms完成查询
     */
    public Map<Integer,List<ItemCat>> getMap(){
        //1.查询全部数据库记录
        List<ItemCat> list = itemCatMapper.selectList(null);
        //2.将list集合数据,封装到Map集合中
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        for (ItemCat itemCat : list) { //遍历所有的数据
            int parentId = itemCat.getParentId();

            //containsKey: 检查key值存不存在
            if (map.containsKey(parentId)) { //key存在,将数据追加即可
                map.get(parentId).add(itemCat);
            } else {//key不存在  我是当前parentId的第一个子级
                List<ItemCat> temp = new ArrayList<>();
                temp.add(itemCat);
                map.put(parentId,temp);
            }
        }
        return map;
    }

2、获取一级、二级、三级菜单

    //Map<parentId,List<ItemCat>子级>
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        Map<Integer,List<ItemCat>> map = getMap();
        if (level == 1){
            return map.get(0);
        }
        if (level == 2){ //查询一级和二级
            return getTwoList(map);
        }
        return getThreeList(map);
    }


    //获取一级 / 二级 / 三级菜单
    private List<ItemCat> getThreeList(Map<Integer, List<ItemCat>> map) {
        //1.获取一级和二级
        List<ItemCat> oneList = getTwoList(map);//一级数据不可能为空
        //2.遍历一级集合 获取二级的数据
        for (ItemCat oneItemCat : oneList){
            //二级数据可能为null
            List<ItemCat> twoList = oneItemCat.getChildren();
            if (twoList == null || twoList.size() == 0){
                //表示数据没有二级 本次循环应该终止,开始下一次循环
                continue;
            }
            //二级列表一定有值,可以查询三级列表
            for (ItemCat twoItemCat : twoList){
                //获取二级Id 查询三级数据
                int parentId = twoItemCat.getId();
                List<ItemCat> threeList = map.get(parentId);
                //将三级数据保存到二级数据中
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    //获取二级菜单
    private List<ItemCat> getTwoList(Map<Integer, List<ItemCat>> map) {
        //1.获取一级菜单
        List<ItemCat> oneList = map.get(0);
        //2.遍历数据
        for (ItemCat oneItemCat : oneList){
            //key
            int parentId = oneItemCat.getId();
            //根据父级查询子级
            List<ItemCat> twoList = map.get(parentId);
            //封装子级数据
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

二、application文件

#配置端口号
server:
  port: 8091

#管理数据源
spring:
  datasource:
    #高版本驱动使用
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    #设定用户名和密码
    username: root
    password: 2323

#SpringBoot整合Mybatis-plus
mybatis-plus:
  #指定别名包
  type-aliases-package: com.jt.pojo
  #扫描指定路径下的映射文件
  mapper-locations: classpath:/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true
  # 一二级缓存默认开始 所以可以简化

#打印mysql日志
logging:
  level:
    com.jt.mapper: debug

三、自动填充操作时间

BasePojo类:数据创建时间以及修改时间

//pojo基类,完成2个任务,2个日期,实现序列化
@Data
@Accessors(chain=true)//控制是否开启链式加载结构
public class BasePojo implements Serializable{
	//新增操作时,自动填充
	@TableField(fill = FieldFill.INSERT)
	private Date created;	//表示入库时需要赋值

	//@TableField MybatisPlus注解  标识属性是否存在,及名称是否一致
	
	//新增-修改操作时,自动填充
	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date updated;	//表示入库/更新时赋值.
}

MyMetObjectHandler配置类:实现自动填充

@Component  //将当前类未来的对象交给容器管理
public class MyMetObjectHandler 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) {
        this.setFieldValByName("updated", new Date(), metaObject);
    }
}

四、商品分页展现

1、PageResult类

@Data
@Accessors(chain = true)
public class PageResult implements Serializable {
    private String query;       //用户查询的数据
    private Integer pageNum;    //查询页数
    private Integer pageSize;   //查询条数
    private Long total;         //查询总记录数
    private Object rows;        //分页查询的结果
}

2、分页步骤

   @Override
    public PageResult getItemList(PageResult pageResult) {
        //1.用户查询的where条件
        QueryWrapper<Item> queryWrapper = new QueryWrapper<>();
        boolean flag = StringUtils.hasLength(pageResult.getQuery());//判断字符串是否为空
        queryWrapper.like(flag,"title", pageResult.getQuery());

        //2.page是MP分页对象 参数1:页数 参数2:条数
        Page<Item> page =
                new Page<>(pageResult.getPageNum(),pageResult.getPageSize());
        //MP在内部自动的获取 总数和分页后的结果
        page = itemMapper.selectPage(page,queryWrapper);

        //3.获取数据之后封装
        long total = page.getTotal();
        List<Item> rows = page.getRecords();
        return pageResult.setTotal(total).setRows(rows);
    }

3、添加配置类

@Configuration //添加配置类
public class MybatisPlusConfig {

    // 最新版
    // 核心功能: 指定数据库版本,自动生成Sql
    @Bean //标识该方法的返回值交给Spring容器管理
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));
        return interceptor;
    }
}

五、商品图片上传

1、SysResult类

@Data
@Accessors(chain = true)//控制是否开启链式加载结构
@NoArgsConstructor //生成无参构造方法
@AllArgsConstructor //生成全参构造方法
public class SysResult implements Serializable {//实现了序列化的接口
    private Integer status; //200成功  201失败
    private String  msg;    //提示信息
    private Object  data;   //服务器返回值数据

    public static SysResult fail(){//失败

        return new SysResult(201,"业务调用失败!!",null);
    }

    public static SysResult success(){//成功

        return new SysResult(200,"业务调用成功!!",null);
    }


    public static SysResult success(Object data){

        return new SysResult(200,"业务调用成功!!",data);
    }

    public static SysResult success(String msg,Object data){

        return new SysResult(200,msg,data);
    }
}

2、ImageVO类

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO {
    private String virtualPath; //动态变化的路径
    private String urlPath;  //网络地址
    private String fileName; //图片名称
}

3、FileServiceImpl类

@Service
public class FileServiceImpl implements FileService{

    //定义根目录  windows系统采用该目录   Linux系统需要切换目录
    private String preFilePath = "D:/software/image";

    //定义网络地址前缀
    private String preURLPath = "http://image.jt.com";

    /**
     * 实现图片上传
     * 业务思路:
     *      1.校验图片的类型  jpg|png|gif
     *      2.校验是否为恶意程序  木马.exe.jpg
     *      3.将图片进行分目录存储  hash方式存储|时间格式存储
     *      4.防止图片重名,使用UUID.
     * @param file
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile file) {
        //1.获取文件名称  abc.jpg
        //2.bug: 文件名称大小写问题 全部转化为小写
        String fileName = file.getOriginalFilename().toLowerCase();

        if (!fileName.matches("^.+\\.(jpg|png|gif)$")){
            //如果图片不满足条件,则程序终止
            return null;
        }

        //第二步: 校验是否为恶意程序
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int height = bufferedImage.getHeight();
            int width = bufferedImage.getWidth();
            if (height==0 || width==0){
                return null;
            }

            //第三步: 分目录储存  提高检索的效率  按照时间将目录划分 /yyyy/MM/dd/
            String datePath =
                    new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            //D:/software/lsy/image/2022/01/25
            String fileDir = preFilePath + datePath;
            //创建目录
            File dirFile = new File(fileDir);
            if (!dirFile.exists()){ //目录没有的时候,应该创建目录
                dirFile.mkdirs();
            }

            //第四步: 防止文件重名
            String uuid = UUID.randomUUID().toString().replace("-", "");
            int index = fileName.lastIndexOf(".");
            //获取数据.jpg
            String fileType = fileName.substring(index);
            //新文件名称
            fileName = uuid + fileType;

            //第五步: 实现文件上传
            //D:/software/lsy/image/2022/01/25/uuid.jpg
            String filePath = fileDir + fileName;
            file.transferTo(new File(filePath));

            //第六步: 封装ImageVO返回数据  /2022/01/25/uuid.jpg
            String virtualPath = datePath + fileName;

            //第七步: 封装网络地址 http://image.jt.com/2022/01/25/uuid.jpg
            String urlPath = preURLPath + virtualPath;
            System.out.println(urlPath);
            return new ImageVO(virtualPath,urlPath,fileName);

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值