苍穹外卖知识点汇集

  1. 密码加密
    学习了使用 MD5 加密密码,避免明文存储,但了解到 MD5 不够安全,后续可以尝试更安全的算法,比如 bcrypt。

  2. 配置文件
    掌握了在 Spring Boot 的 yml 文件中使用占位符 ${} 来配置不同环境的变量。

  3. 日志记录
    学会了使用 SLF4J 的占位符 {} 来高效记录日志,避免字符串拼接。

  4. 异常处理
    使用 @ExceptionHandler 处理特定异常(如重复条目异常),提取关键信息返回给前端,但意识到直接暴露异常信息可能不安全,需要更全面的异常处理策略。

  5. 文件上传
    学习了通过 MultipartFile 处理文件上传,使用 UUID 生成唯一文件名,改进了文件扩展名的处理方式,但需要注意文件名为空或格式异常的情况。

  6. MyBatis 动态 SQL
    掌握了 useGeneratedKeyskeyProperty 获取自增主键,以及使用 foreach 实现批量插入,但要注意性能和 SQL 长度问题。

  7. 代码简化
    使用 Lombok 的 @Data@Builder 注解简化了 setter 和 getter,减少了样板代码。

  8. 占位符使用
    理解了 SLF4J 的 {} 和 MyBatis 的 ${}#{} 的区别,避免 SQL 注入问题。

对密码进行md5加密

  password = DigestUtils.md5DigestAsHex(password.getBytes());

使用了DigestUtils工具类

学会了如何分文件写yml文件,占位符¥{}  

slf4j的占位符{}

mybatis的占位符号#{}

 全局错误处理

  @ExceptionHandler //标记方法为异常处理器,指定该方法可以处理特定类型的异常。

    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){

        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }else{
         return Result.error("未知错误");
        }
    }
}

 @RestController 和 @RequestMapping 注解的作用
在 Spring 框架中,@RestController 和 @RequestMapping 是两个常用的注解,用于定义和配置 RESTful Web 服务的控制器。下面是这两个注解的详细解释及其在你的代码中的作用。
 
1. @RestController
定义 @RestController 是 Spring 提供的一个组合注解,用于简化控制器类的定义。
作用
@Controller:标记一个类为 Spring MVC 控制器。******
@ResponseBody:默认将方法的返回值直接写入 HTTP 响应体中,而不是解析为视图。
 

2. @RequestMapping
定义 @RequestMapping 是 Spring 提供的一个注解,用于映射 HTTP 请求到特定的处理方法或控制器类。
作用
类级别:定义控制器类处理的请求的基本路径。*************
方法级别:定义具体方法处理的请求路径、请求方法(如 GET、POST 等)、请求参数等。

如何格式化日期

在系统当中如何上传图片

 public Result<String> upload(MultipartFile file){
        log.info("文件上传:{}",file);
        try {
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String objectName = UUID.randomUUID().toString() + extension;

            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败:{}",e);
        }
        return null;
    }

MultipartFile (是 Spring 框架提供的一个接口,位于 org.springframework.web.multipart.MultipartFile 包中。
它用于处理 HTTP 请求中的文件上传功能)

常用方法
 

String getOriginalFilename():获取文件的原始名称(包括扩展名)。
String getName():获取表单字段的名称。
String getContentType():获取文件的内容类型(如 image/jpeg)。
long getSize():获取文件的大小(以字节为单位)。
byte[] getBytes():将文件内容读取为字节数组。
InputStream getInputStream():获取文件的输入流。
void transferTo(File dest):将文件保存到指定的目标路径

在上述代码当中就使用了getOriginalFilename(),方法来获取原始名称然后通过substring(originalFilename.lastIndexOf("."))获取到了文件的extension(文件拓展名)

定义 substring(int beginIndex) 是 Java 中 String 类的一个方法,用于从指定的起始索引位置提取子字符串。
返回值 返回从 beginIndex 开始到字符串末尾的子字符串

定义 lastIndexOf(String str) 是 Java 中 String 类的一个方法,用于查找指定字符或子字符串在字符串中最后一次出现的位置。
返回值 返回指定字符或子字符串最后一次出现的索引位置(从 0 开始)。如果未找到,则返回 -1。

<思考>

可以使用String方法当中的split()方法来获得文件的后缀名字但是极其不方便

public Result<String> upload(MultipartFile file) {
    log.info("文件上传:{}", file);
    try {
        String originalFilename = file.getOriginalFilename();
        String[] parts = originalFilename.split("\\.");
        String extension = parts.length > 1 ? "." + parts[parts.length - 1] : "";

        String objectName = UUID.randomUUID().toString() + extension;

        String filePath = aliOssUtil.upload(file.getBytes(), objectName);
        return Result.success(filePath);
    } catch (IOException e) {
        log.error("文件上传失败:{}", e);
    }
    return null;
}

aliOssUtil是一个自定义工具类里面封装的使用阿里OSS的基本配置

UUID (用于生成唯一标识符)

UUID.randomUUID() 返回的是一个 java.util.UUID 类型的对象

<思考>

try-catch 中是否需要 throw
写了 log.error 并不意味着不需要 throw。
是否需要 throw 取决于业务需求:
如果希望将异常继续向上抛出,让调用方处理,则需要使用 throw。
如果异常已经被处理(例如返回了友好的错误响应),则可以不抛出异常

总结
log.error 仅用于记录错误信息,不会影响异常的传播。
是否需要 throw 取决于业务逻辑:如果需要调用方感知异常,则应抛出;否则可以通过返回值明确告知结果。

1. 定义
类:BeanUtils 是 Spring 框架中的一个工具类,位于 org.springframework.beans 包中。
方法:copyProperties(Object source, Object target) 是 BeanUtils 类中的一个静态方法。
2. 作用
复制属性:将源对象(source)中的属性值复制到目标对象(target)中。
自动匹配:根据属性名称和类型自动匹配并复制属性。

<大量简化了 setter和getter的调用,和Builder有异曲同工之妙>

 下面是关于useGeneratedKeys和keyProperty的代码以及相关介绍

useGeneratedKeys 属性: 指定是否使用数据库自动生成的主键。
keyProperty 属性: 指定将生成的主键值赋给 Java 对象的哪个属性。如下代码就是赋值给类中的id属性

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
    insert into dish(name,category_id,price,image,description,create_time,update_time,create_user,update_user,status)
    values
        (#{name},#{categoryId},#{price},#{image},#{description},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})
</insert>

 MYBATIS中的动态SQL<foreach>

直接传入list集合而不用大量重复传入集合当中的元素
  void insertBatch(List<DishFlavor> flavors);



xml映射文件的写法

    <insert id="insertBatch">
        insert into dish_flavor (dish_id, name, value) values
        <foreach collection="flavors" item="df" separator=",">
            (#{df.dishId},#{df.name},#{df.value})
        </foreach>
    </insert>


//separator=",
"separator: 指定每个元素之间的分隔符,这里使用逗号 , 来分隔不同的 VALUES 子句。

//SQL
INSERT INTO dish_flavor (dish_id, name, value) VALUES
(1, 'Flavor1', 'Value1'),
(2, 'Flavor2', 'Value2'),
(3, 'Flavor3', 'Value3');

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值