当前位置: 首页 > article >正文

苍穹外卖零碎知识点学习记录

Swagger

swagger可以自动根据代码接口生成接口文档,还可以在里面测试接口

**思考:**通过 Swagger 就可以生成接口文档,那么我们就不需要 Yapi 了?
1、Yapi 是设计阶段使用的工具,管理和维护接口
2、Swagger 在开发阶段使用的框架,帮助后端开发人员做后端的接口测试

通过以下注解,会影响最终的接口文档。在编写代码的过程中,随手加上这些注解,增加文档的可读性

写在xml里的sql

所实现的功能不止是对员工启用或禁用,而是可以对员工信息的多个字段进行动态更新。

为什么能适用多个功能呢?

因为<set> 标签里使用了多个 <if> 标签来进行条件判断。对于每个字段,只有当传入的 Employee 对象中对应的属性不为 null 时,才会将该字段的更新语句添加到 SET 子句中

<update id="update" parameterType="com.sky.entity.Employee">
        update employee
        <set>
            <if test="name != null">name = #{name},</if>
            <if test="username != null">username = #{username},</if>
            <if test="password != null">password = #{password},</if>
            <if test="phone != null">phone = #{phone},</if>
            <if test="sex != null">sex = #{sex},</if>
            <if test="idNumber != null">id_Number = #{idNumber},</if>
            <if test="updateTime != null">update_Time = #{updateTime},</if>
            <if test="updateUser != null">update_User = #{updateUser},</if>
            <if test="status != null">status = #{status},</if>
        </set>
        where id = #{id}
    </update>

前端调试技巧

在这里可以看到请求URL等

关于DTO的编程规范

像这样,虽然传进来的是DTO,但用mapper访问数据层的时候,最好还是用原来的实体去访问

关于static关键字在线程中的应用

static的作用

这个 BaseContext 类的作用是 使用 ThreadLocal 在当前线程内存储和获取 id,通常用于存储当前登录用户的 ID,确保在同一请求线程内可以随时访问该 ID,而不会被其他线程干扰。


代码解析

public class BaseContext {

    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    public static void setCurrentId(Long id) {
        threadLocal.set(id);
    }

    public static Long getCurrentId() {
        return threadLocal.get();
    }

    public static void removeCurrentId() {
        threadLocal.remove();
    }

}

BaseContext.setCurrentId(1001L); // 线程 A 存储 ID 1001 BaseContext.setCurrentId(1002L); // 线程 B 存储 ID 1002 System.out.println(BaseContext.getCurrentId());

  • 线程 A 获取的是 1001
  • 线程 B 获取的是 1002
  • 互不影响

static 的作用

BaseContext 这个类里,static 主要有两个作用:

  1. 保证 threadLocal 变量在整个类中共享

    public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    • static 使得 threadLocal 属于类级别的变量,所有方法都能访问它。
    • 每个线程有自己的 ThreadLocal 副本,不会影响其他线程。
  2. setCurrentId()getCurrentId() 这些方法是静态方法

    public static void setCurrentId(Long id) { threadLocal.set(id); }

    • 这些方法不需要创建 BaseContext 对象,可以直接 BaseContext.setCurrentId(id) 调用。
    • 方便全局使用,尤其是在拦截器、过滤器等地方。

总结

  1. ThreadLocal 让每个线程有自己独立的 id,避免线程安全问题
  2. staticthreadLocal 变量和方法可以直接使用,不需要创建对象
  3. 常用于存储当前用户 ID,便于在同一线程内访问(如在拦截器中存 ID,在后续业务逻辑中获取 ID)。

Serializable 序列化

Serializable 是什么?

Serializable 是 Java 序列化接口,用于 将对象转换为字节流,以便存储或传输。
EmployeePageQueryDTO 类中,它的作用是 让该类的对象支持序列化,方便网络传输、文件存储、缓存等操作


为什么需要 Serializable

Java 的对象通常是存储在内存中的,但有时需要:

  1. 将对象保存到文件(持久化存储)。
  2. 在网络中传输对象(如远程调用 RMI、RPC、Web API)。
  3. 存入 Redis、数据库(如 MyBatis、JPA)。
  4. 跨 JVM 传输数据(分布式系统中)。

Java 无法直接存储对象,必须转换成 字节流,这就是序列化的作用。

消息转换器

/**
     * 扩展Spring MVC框架的消息转化器
     * @param converters
     */
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转化器加入容器中
        converters.add(0,converter);
    }

Spring MVC 消息转换器(MessageConverter)

在 Spring MVC 中,消息转换器HttpMessageConverter)用于将 Java 对象转换为 HTTP 响应体(比如 JSON)或者从 HTTP 请求体解析 Java 对象

Spring 默认提供了一些消息转换器,如:

  • MappingJackson2HttpMessageConverter(用于 JSON 转换)
  • StringHttpMessageConverter(用于 String 类型)
  • ByteArrayHttpMessageConverter(用于 byte[]

为什么要自定义 ObjectMapper

Spring 默认的 Jackson 配置可能不符合业务需求,所以可以自定义 ObjectMapper,比如:

  1. 统一时间格式 yyyy-MM-dd HH:mm:ss
  2. 忽略 null 值字段
  3. 处理 BigDecimal 精度问题

以下是JacksonObjectMapper 代码

package com.sky.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

总结

extendMessageConverters 作用: 自定义消息转换器,优先使用自定义 JSON 处理规则
MappingJackson2HttpMessageConverter 基于 Jackson 进行 JSON 转换
自定义 JacksonObjectMapper 作用: 统一 JSON 处理规则,例如时间格式、忽略 null
修改默认 converters 列表: converters.add(0, converter) 确保 Spring MVC 优先使用 该转换器


http://www.kler.cn/a/573661.html

相关文章:

  • 深入解析:使用Java爬虫获取淘宝商品详情高级版API接口
  • java常用注解(持续更新)
  • XS9935 ,4通道模拟复合视频解码芯片,双向音频数据同轴共缆传输
  • 二、QT和驱动模块实现智能家居-----4、编译Qt程序并运行
  • conda 更换镜像究极方法
  • Django实现接口token检测的实现方案
  • 计算机网络数据传输探秘:包裹如何在数字世界旅行?
  • 海康摄像头接入流媒体服务器实现https域名代理播放
  • 优选算法的智慧之光:滑动窗口专题(二)
  • 自然语言转SQL之Vanna.ai:AI集成数据库
  • Ansys Zemax | 使用衍射光学器件模拟增强现实 (AR) 系统的出瞳扩展器 (EPE):第 4 部分
  • 报错The default superclass, “jakarta.servlet.http.HttpServlet“(已经配置好tomcat)
  • 理解 React Portal:让你的组件跳出层级限制
  • JSONP解决跨域问题:原理、实现与局限
  • 家政保洁维修行业有没有必要做小程序?
  • MWC 2025 | 紫光展锐联合移远通信推出全面支持R16特性的5G模组RG620UA-EU
  • 【五.LangChain技术与应用】【10.LangChain ChatPromptTemplate(下):复杂场景下的应用】
  • centos8 虚拟机重启后无法识别网卡 ens33 问题原因总结
  • Exoplayer2源码编译FFmpeg拓展模块实现音频软解码
  • Python在NFT市场中的应用:从创建到交易的完整指南