Sky Takeaway

软件开发整体介绍

软件开发流程

角色分工

软件环境

苍穹外卖

项目介绍

定位:专门为餐饮企业定制的一款软件产品

技术选型

前端环境搭建

阅读readme文档

nginx.exe放入无中文目录运行并启动

后端环境搭建

项目结构

Nginx反向代理

优点

配置

Nginx反向代理

负载均衡

Nginx负载均衡策略

完善登录功能

导入接口文档

使用Apifox或者Yapi,导入管理层和用户层的json接口文档

Swagger

介绍

使用方式

Swagger和Yapi

常用注解

公共字段自动填充

项目完成技术整理:

做了三周。。。
开始的比较迟了。。

整理一下:

  1. 分页查询:
    Controller返回:PageResult
    Service:
    PageHelper.startPage(页码,每页记录数)
     封装PageResult并返回
  2. 公共字段自动填充
    对于insertupdate操作类型,可以使用切面进行统一拦截mapper并自动填充(注解)
    实现思路:(枚举、注解、AOP、反射)
  • 自定义注解AutoFill,用于标识需要进行公共字段自动填充的方法
  • 自定义切面类AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
  • 在Mapper方法上加入AutoFill注解
  • 具体步骤:
    1. 创建annotation:AutoFill
    1. 加注解:
     @Target(ElementType.METHOD)//指定注解只能加在方法上
     @Retention(RetentionPolicy.RUNTIME)
    1. 通过枚举方式指定加注解的当前数据库操作类型
public @interface AutoFill {
    //数据库操作类型:UPDATE,INSERT
    OperationType value();
}
    1. 切面类aspect.AutoFillAspect--自定义切面,实现公共字段自动填充
    • 加入注解:
@Aspect //定义切面
@Component //Bean
    • 指定切入点:autoFillPointCut
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
public void autoFillPointCut(){}

    execution(所有返回类型 包.类.方法.(匹配参数类型)) && 加入AutoFill注解@annotation(自定义注解)

    1. 前置通知:通知中给公共字段赋值
       注解:@Before("autoFillPointCut()")
       例子:
@Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        log.info("开始进行公共字段自动填充...");

        //获取当前被拦截的方法上的数据库操作类型
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();//方法签名对象
        AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
        OperationType operationType = annotation.value();//获得数据库操作类型

        //获取到当前被拦截的方法的参数--实体对象
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0){
            return;
        }

        Object entity = args[0];

        //准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        //根据当前不同的操作类型,为对应的属性赋值
        if (operationType == OperationType.INSERT){
            //为四个公共字段赋值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME,LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setCreateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
  •    JoinPoint joinPoint 在AOP中,我们知道描述切面的术语有通知(advice),切点(pointcut),连接点(join point)。
       连接点(joinPoint)就是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。
       这个类的主要作用就是可以让我们在Advice中获取被增强方法相关的所有信息。通过JoinPoint可以获取被代理方法的各种信息,如方法参数,方法所在类的class对象,然后执行反射操作
  •    getSignature():返回一个 Signature 对象,此接口通常用于跟踪或记录应用程序以获取有关连接点的反射信息
  1. redis 设置店铺状态
    Spring Data Redis
    1. 导入maven
    1. 配置数据源:application.yml
  redis:
    port: 8080  
    host: localhost
    database: 0
    1. 编写配置类,创建RedisTemplate对象
@Configuration
@Slf4j
public class RedisConfiguration {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        log.info("开始创建redis模版对象...");
        RedisTemplate redisTemplate = new RedisTemplate();
        //设置redis的连接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;

    }
}
    1. 通过RedisTemplate对象操作Redis
ValueOperations valueOperations = redisTemplate.opsForValue();
Integer status = (Integer) valueOperations.get(KEY);
  1. cpolar实现内网穿透,获得临时网址
    cmd进入cpolar.exe所在文件夹,执行:cpolar.exe http 80
  2. Spring Cache 缓存
    启动类加入注解:@EnableCaching
    @Cacheable:在方法执行前查看是否有缓存对应的数据,如果有直接返回数据,如果没有调用方法获取数据返回,并缓存起来。
    @CacheEvict:将一条或多条数据从缓存中删除。
    @CachePut:将方法的返回值放到缓存中
    @EnableCaching:开启缓存注解功能
    • (cacheNames = " ", key = "#user.id")
    • cacheNames 指定要放到哪个名字的缓存
    • key :
      • #result.id:result 表示返回值
      • #p0.id#a0.id#root.args[0].id表示第一个参数的 id
    • allEntries = true:选定所有键
  1. Spring Task 定时任务处理
  • 启动类加入注解:@EnableScheduling -- 开启任务调度
  • task类编写定时任务处理方法,方法前编写cron表达式:表示多久触发一次方法
    /**
     * 处理超时订单的方法
     */
    @Scheduled(cron = "0 * * * * ?")//每分钟触发一次
    public void processTimeoutOrder(){
        log.info("定时处理超时订单:{}", LocalDateTime.now());

        //查找超时订单
        LocalDateTime time = LocalDateTime.now().plusMinutes(-15);

        //select * from orders where status = ? and order_time < (当前时间 - 15分钟)
        List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time);
    }
  1. WebSocket 实现双向交互
    websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信
    在websocket出现之前,web交互一般是基于http协议的短连接或者长连接
    websocket是一种全新的协议,不属于http无状态协议,协议名为"ws"
  2. Apache POI 执行文件导出
    使用POI写入数据
    Apache POI
  3. stream好用呢!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Open CASCADE学习|通过指定点的曲线

在OpenCASCADE中&#xff0c;如果你想通过一系列指定的点来创建一条曲线&#xff0c;你可以使用Geom2dAPI_Interpolate类来实现二维曲线的插值&#xff0c;或者使用GeomAPI_Interpolate类来实现三维曲线的插值。这些类允许你定义一条B样条曲线&#xff0c;这条曲线将精确地通过…

【Sceneform-EQR】通过sceneform-eqr实现一个视频播放器(使用安卓MediaPlayer实现视频播放)

在前一篇文档中介绍了如何在AR\三维场景创建几种背景 【Sceneform-EQR】scenefrom-eqr中的几种背景实现(不仅用于AR、三维场景&#xff0c;在图片、视频播放器中也适用) 本文将侧重介绍如何使用安卓MediaPlayer实现视频播放。 ↓↓↓↓↓↓↓↓↓↓↓↓ 以下正文 ↓↓↓↓↓↓…

艺术体操与骑行的完美协奏:维乐Angel Rise+坐垫,激情与力量的展现!

在艺术体操的赛场上&#xff0c;每一次旋转、每一次跳跃&#xff0c;都凝聚着运动员的力量与技巧。这不仅是一场速度与激情的碰撞&#xff0c;更是一次力量与技巧的交融。正如在骑行的领域里&#xff0c;VELO Angel Rise坐垫以它独特的一体成型设计和技术&#xff0c;为骑行者们…

windows通过wsl2安装linux系统之Ubuntu,傻瓜式安装

期望通过每一次分享&#xff0c;让技术的门槛变低&#xff0c;落地更容易。 —— around 目录 1.基础环境和要求2.安装wsl23.安装linux系统4.迁移linux系统挂载5.配置linux账号密码6.配置ssh登录方式待续… 前言 为什么要在windows上安装linux&#xff0c;这个问题当你是研发…

rancher搭建k8s及jenkins自动化部署

1、准备环境 角色IP用途k8s-rancher-master192.168.3.63master节点k8s-rancher-node01192.168.3.64node节点k8s-rancher-node02192.168.3.66node节点k8s-rancher-server192.168.2.33rancher-server节点注: 服务器名需要配置不同,相同服务器名不能加入node节点 在所有节点进行…

1万3医学考研题库医学题库ACCESS\EXCEL数据库

今天这个题库按知识点分章节模块智能练习&#xff0c;覆盖书本上所有知识点以及考点&#xff0c;在真#题的解析里边也有详细的展示&#xff1b;另外&#xff0c;这份数据库与《4820道西#医综合真题西#医真#题ACCESS数据库》、《4170条中#医综合真#题中医真#题ACCESS\EXCEL数据库…

Android V 广播注册和配置注意事项问题

现象 在Android V平台上&#xff0c;应用注册非Protected广播时&#xff0c;如果没有加导出flag会抛出异常导致进程crash。 E/AndroidRuntime: FATAL EXCEPTION: main java.lang.SecurityException: com.demo.myapplication: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORT…

如何用3个月零基础入门网络安全?_网络安全零基础怎么学习

前 言 写这篇教程的初衷是很多朋友都想了解如何入门/转行网络安全&#xff0c;实现自己的“黑客梦”。文章的宗旨是&#xff1a; 1.指出一些自学的误区 2.提供客观可行的学习表 3.推荐我认为适合小白学习的资源.大佬绕道哈&#xff01; →点击获取网络安全资料攻略← 一、自学…

k8s的配置管理

一、配置管理分为两种&#xff1a; 1. 加密配置&#xff1a;用来保存密码和token密钥对以及其它敏感的k8s资源。 2.应用配置&#xff1a;我们需要定制化的给应用进行配置&#xff0c;我们需要把定制好的配置文件同步到pod当中的容器。 二、加密配置 1.secret三种类型&#xf…

YOLOv8改进 | 模块缝合 | C2f 融合RVB + EMA注意力机制【二次融合 + 结构图】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

《垃圾回收的算法与实现》-算法-摘抄

本文是书籍《垃圾回收的算法与实现》的摘抄&#xff0c;不涉及算法源码及步骤讲解模块。 预备 对象由头(header)和域(field)构成。 头&#xff1a;对象中保存对象本身信息的部分&#xff0c;主要含有以下信息&#xff1a;对象的大小和种类。 域&#xff1a;对象使用者在对象…

图结构详解

概述 图是由有穷非空集合的顶点和顶点之间的边组成的集合&#xff0c;通常表示为 G(V,E)。G 表示一个图&#xff0c;V 是 图 G 顶点的集合&#xff0c;E 是图 G 边的集合。在图形结构中&#xff0c;数据之间具有任意联系&#xff0c;任意两个数据之间都可能相关&#xff0c;可…

彻底解决 node/npm, Electron下载失败相关问题, 从底层源码详解node electron 加速配置

最近玩了一下electron项目, 总是会遇到electron的下载失败问题, 于是看了一下node源码, 做一个记录. node/npm 加速配置 这个配置通过设置node配置里面的registry 这个配置项来完成加速. 配置方法 npm config set registry https://registry.npmmirror.com上面的命令就是将当…

打破界限,自闭症寄宿学校带给孩子的改变

在社会的广阔画卷中&#xff0c;有一群特别的孩子&#xff0c;他们以独特的视角感知世界&#xff0c;以非凡的方式表达情感&#xff0c;他们就是自闭症儿童。自闭症&#xff0c;这个听起来略带神秘色彩的词汇&#xff0c;实则承载着无数家庭的期盼与挑战。在这片充满爱的土地上…

C++设计模式——Iterator迭代器模式

一&#xff0c;迭代器模式的定义 迭代器模式是一种行为型设计模式&#xff0c;它使得遍历一个容器对象中的元素变得更加简单。 迭代器模式将遍历操作从容器对象&#xff08;如集合、列表&#xff09;中分离出来&#xff0c;它通过迭代器对象来遍历容器对象中的元素&#xff0…

RK3568平台开发系列讲解(PWM篇)使用 sysfs 接口操作 pwm

🚀返回专栏总目录 文章目录 一、查看 pwm 设备信息二、使用 sysfs 操作 PWM沉淀、分享、成长,让自己和他人都能有所收获!😄 PWM 子系统被划分为了三个层次, 分别为用户空间、 内核空间和硬件层, 内核空间包括 PWM 设备驱动层、 PWM 核心层和 PWM 适配器驱动层 一、查看…

JS面试真题 part3

JS面试真题 part3 11、bind、call、apply区别&#xff1f;如何实现一个bind12、JavaScript中执行上下文和执行栈是什么13、说说JavaScript中的事件模型14、解释下什么是事件代理&#xff1f;应用场景&#xff1f;15、说说你对闭包的理解&#xff1f;闭包使用场景 11、bind、cal…

分布式技术概览

文章目录 分布式技术1. 分布式数据库&#xff08;Distributed Databases&#xff09;2. 分布式文件系统&#xff08;Distributed File Systems&#xff09;3. 分布式哈希表&#xff08;Distributed Hash Tables, DHTs&#xff09;4. 分布式缓存&#xff08;Distributed Caching…

面向对象需求分析

1. 面向对象分析概述 1.1 面向对象基本概念 以对象为中心&#xff0c;以类为构造机制&#xff0c;来认识、理解、刻画客观世界和设计、构建相应的软件系统。 1.2 UML统一建模语言 为什么要使用UML UML基本概念 统一建模语言&#xff08;UML&#xff09;是一个支持模型化和软…

【电子通识】半导体工艺——刻蚀工艺

在文章【电子通识】半导体工艺——光刻工艺中我们讲到人们经常将 Photo Lithography&#xff08;光刻&#xff09;缩写成 Photo。光刻工艺是在晶圆上利用光线来照射带有电路图形的光罩&#xff0c;从而绘制电路。光刻工艺类似于洗印黑白照片&#xff0c;将在胶片上形成的图像印…