苍穹外卖项目---------收获以及改进(1-2天)

news2024/11/24 2:06:32

①Nginx反向代理

 概念:

优点:

 反向代理配置方式:

 负载均衡配置方式:

 ②MD5加密,使用Hutool工具

 ③ThreadLocal

 封装线程操作的类:
//线程操作封装类
public class BaseContext {

    public 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();
    }

}

 只需要在拦截器中拦截的时候把数据放到线程中,在之后的Controller层和Service层中都可以直接在线程中取数据

④使用Mybatis-plus实现分页查询

 mpConfig.java
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class mpConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){

        //定义分页查询拦截器
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        //添加拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());

        return interceptor;
    }
}



 service层:
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {

        //1.创建Ipage对象
        IPage page = new Page(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
        
        //2.Mapper层对象去进行查询
        //2.1 wapper对象去条件查询
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.likeRight("name",employeePageQueryDTO.getName());
        //2.2 如果没输入模糊查询
        if(employeePageQueryDTO.getName() == null){
            employeeMapper.selectPage(page,null);
        }
        //2.3 如果模糊查询
        else
            employeeMapper.selectPage(page,wrapper);
        
        //3. 此时Page中已经存了我们所要的数据

        //显示第几页
        System.out.println(page.getCurrent());
        //显示每页大小
        System.out.println(page.getSize());
        //显示一共有多少页
        System.out.println(page.getPages());
        //显示一共用多少条数据
        System.out.println(page.getTotal());
        //显示该页的数据
        System.out.println(page.getRecords());
            
        //返回我们所需的数据
        return new PageResult(page.getTotal(),page.getRecords());
    }

⑤有关日期的显示格式的统一

第一种方式:添加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解

第二种方式:全局配置一下

/**
 * 对象映射器:基于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)))
                
                .addSerializer(BigInteger.class, ToStringSerializer.instance)
                .addSerializer(Long.class, ToStringSerializer.instance);
        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}
/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {


    /**
     * 扩展Spring MVC框架的消息转换器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器");

        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

        //为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());

        //将消息转换器加入容器中
        converters.add(0,converter);
    }
}

 ⑥雪花算法会导致前后端数据精度丢失

 解决方法一:加@JsonSerialize(using = ToStringSerializer.class)注解

 解决方法二:引入工具类
/**
 * 对象映射器:基于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)))
                
                //在这里是解决雪花算法导致前后端精度丢失
                .addSerializer(BigInteger.class, ToStringSerializer.instance)
                .addSerializer(Long.class, ToStringSerializer.instance);


        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}
/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    /**
     * 扩展Spring MVC框架的消息转换器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器");

        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

        //为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());

        //将消息转换器加入容器中
        converters.add(0,converter);
    }
}

 ⑦对象的拷贝BeanUtil.copyProperties(old,new)

 public void updateEm(EmployeeDTO employeeDTO) {
        
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO,employee);

        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(BaseContext.getCurrentId());

        updateById(employee);
    }

⑧自己打代码学到了一个知识点

就是wapper的判断条件:因为不知道前端传来的对象中是否有模糊查询,所以之前写的时候就在外面加判断条件,十分不美观。

//2.1 wapper对象去条件查询
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.likeRight("name",employeePageQueryDTO.getName());

        //2.2 如果没输入模糊查询
         if(employeePageQueryDTO.getName() == null){
            employeeMapper.selectPage(page,null);
        }
        //2.3 如果模糊查询
        else {
            employeeMapper.selectPage(page, wrapper);
        }

在看like以及eq的源码后发现其实他第一个参数也是可以给一个判断条件,改进:

QueryWrapper wrapper = new QueryWrapper();
        wrapper.like(employeePageQueryDTO.getName() != null,"name",employeePageQueryDTO.getName());

        employeeMapper.selectPage(page, wrapper);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1644169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EasyImage2.0 简单图床开源源码

特点 支持API 支持仅登录后上传 支持设置图片质量 支持压缩图片大小 支持文字/图片水印 支持设置图片指定宽/高 支持上传图片转换为指定格式 支持限制最低宽度/高度上传 支持上传其他文件格式 在线管理图片 支持网站统计 支持设置广告 支持图片鉴黄 支持自定义代码 支持上传IP…

CI/CD笔记.Gitlab系列.新用户管理

CI/CD笔记.Gitlab系列 新用户管理 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_285502…

Linux —— 信号初识

Linux —— 信号初识 什么是信号测试几个信号signal函数函数原型参数说明返回值注意事项示例 后台程序前台转后台检测输入中断向量表 我们今天来继续学习Linux的内容&#xff0c;今天我们要了解的是Linux操作系统中的信号&#xff1a; 什么是信号 信号是操作系统内核与进程之…

45. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

Mac基于Docker-ubuntu构建c/c++编译环境

编译环境安装和使用被充分验证&#xff0c;如有期望补充的内容欢迎留言评论。 目录 前言 Docker desktop下载安装 修改镜像源 选择ubuntu镜像 docker容器启动 参数说明: 宿主机与docker容器文件共享 宿主机与docker容器拷贝文件 为 Ubuntu 配置 ssh、vim、make 相关工…

基于Springboot的校园生活服务平台(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园生活服务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

Maven 在项目的 pom.xml 文件中 指定 阿里云的景象仓库

配置 在 项目的 pom.xml 文件中添加如下配置即可 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&…

计数排序,基数排序,桶排序

目录 计数排序: 基数排序&#xff1a; 桶排序: 计数排序: 计数排序是一种非比较型整数排序算法&#xff0c;特别适用于一定范围内的整数排序。它的核心思想是使用一个额外的数组&#xff08;称为计数数组&#xff09;来计算每个值的出现次数&#xff0c;然后根据这些计数信…

Nginx 从入门到实践(2)——Rewrite重写

Nginx Rewrite Rewrite重写 Nginx Rewriteurl组成说明Rewrite基本概述Rewrite使⽤场景rewrite优点 Rewrite配置语法location匹配概述 if指令if 判断指令语法nginx以及if 判断可使用的全局变量 set命令return指令 url组成说明 https://cn.bing.com/search?qNginxRewrite&P…

VMware虚拟机忘记密码重置--centos7x

centos7虚拟机重置root密码 操作流程 操作流程 重启虚拟机&#xff0c;在如下页面键入e键&#xff1a; 2. 在如下位置添加&#xff1a;init/bin/sh&#xff0c;添加完成后键入Ctrlx启动 依次键入下列命令&#xff1a; mount -o remount,rw / #重新挂载/目录 passwd root #修改…

【微服务】分布式事务(通过Seata解决分布式事务问题)

分布式事务 分布式事务Seata微服务集成SeataXA模式XA模式使用 AT模式AT模式实现 分布式事务 在分布式系统中&#xff0c;如果一个业务需要多个服务合作完成&#xff0c;而且每一个服务都有事务&#xff0c;多个事务必须同时成功或失败&#xff0c;这样的事务就是分布式事务&am…

选择深度学习框架:TensorFlow 2 vs PyTorch

TensorFlow 2 vs PyTorch 选择深度学习框架&#xff1a;TensorFlow 2 vs PyTorchTensorFlow 2概述TensorFlow 2的优点TensorFlow 2的缺点 PyTorch概述PyTorch的优点PyTorch的缺点 选择建议对于选择困难症的人&#xff0c;我给你们的答案——PyTorch选择理由&#xff1a;结论&am…

Mac 电脑安装 Raptor 流程图软件的方法

0. 安装逻辑 &#xff08;1&#xff09;运行 raptor&#xff0c;本质上需要 mac 能够运行 windows 程序&#xff0c;因此需要安装 .NET Runtime 7.0&#xff0c;这是微软程序运行必须的文件。 &#xff08;2&#xff09;运行 raptor 还需要安装依赖文件 mono-libgdiplus。 &am…

python从0开始学习(三)

目录 前言 1、类型转换 1.1 隐式类型转换 1.2 显式类型转换 2、eval函数 总结 前言 上篇我们讲了python中的变量与常量&#xff0c;以及变量类型。本篇文章将接着往下讲。 1、类型转换 python中的数据类型转换包括两种&#xff1a;隐式类型转换和显式类型转换。 1.1 隐式…

微信IDE vscode插件:获取插件位置,并打开文件

背景 有没有觉得在微信开发工具里面添加一些插件可以很方便。因为微信IDE的编辑本身是依赖vscode开发&#xff0c;所以编写vscode插件自然可以在微信IDE使用。这样做好处就是可以满足到自己一些开发使用习惯。 1.获取插件的目录位置 那么如何获取插件里面的目录&#xff0c;…

分布式领域计算模型及SparkRay实现对比

目录 一、分布式计算领域概览 二、Spark计算模型分析 三、Ray计算模型分析 3.1 需求分析 3.2 系统设计 3.3 系统实现 四、总结 一、分布式计算领域概览 当前分布式计算模型主要分为以下4种&#xff1a; Bulk Synchronous Parallel Model&#xff08;块同步并行模型&…

常用语音识别开源四大工具:Kaldi,PaddleSpeech,WeNet,EspNet

无论是基于成本效益还是社区支持&#xff0c;我都坚决认为开源才是推动一切应用的动力源泉。下面推荐语音识别开源工具&#xff1a;Kaldi&#xff0c;Paddle&#xff0c;WeNet&#xff0c;EspNet。 1、最成熟的Kaldi 一个广受欢迎的开源语音识别工具&#xff0c;由Daniel Pove…

开发体育赛事直播平台,研发技术选型与架构设计实现方案

本文将深入探讨“东莞梦幻网络科技”现成体育直播源码的技术实现方案&#xff0c;如何为用户提供流畅、互动、个性化的观赛体验。 一、技术栈选择&#xff1a;强强联合的基石1、后端开发&#xff1a;采用Java与PHP作为主要开发语言。Java以其强大的企业级应用支持&#xff0c;保…

C++证道之路第十七章输入输出和文件

一、C输入和输出概述 C 提供了丰富的输入/输出&#xff08;I/O&#xff09;功能&#xff0c;这些功能主要通过 <iostream> 头文件中的类和对象来实现。 1.流和缓冲区 C把程序输入和输出看作字节流。输入时&#xff0c;程序从输入流中抽取字节&#xff1b;输出时&#…

使用 FFmpeg 从音视频中提取音频

有时候我们需要从视频文件中提取音频&#xff0c;并保存为一个单独的音频文件&#xff0c;我们可以借助 FFmpeg 来完成这个工作。 一、提取音频&#xff0c;保存为 mp3 文件: 要使用 FFmpeg 从音视频文件中提取音频&#xff0c;并将 ACC 编码的音频转换为 MP3 格式&#xff0…