Java项目 苍穹外卖 黑马程序员

目录

  • day1
    • 一、项目效果展示
    • 二、项目开发整体介绍
    • 三、项目介绍
      • 3.1 定位
      • 3.2 功能架构
      • 3.3 产品原型
      • 3.4 技术选型
    • 四、开发环境搭建
      • 4.1 前端环境
      • 4.2 后端环境
    • 五、导入接口文档
    • 六、Swagger
      • 6.1 介绍
      • 6.2 使用方式
      • 6.3 常用注解
  • day2
    • 一、新增员工
    • 二、员工分页查询
    • 三、启用禁用员工账号
    • 四、编辑员工
    • 五、导入分类模块功能代码
  • day3

来源: 黑马程序员Java项目实战《苍穹外卖》,最适合新手的SpringBoot+SSM的企业级Java项目实战

day1

一、项目效果展示

二、项目开发整体介绍

在这里插入图片描述

三、项目介绍

3.1 定位

在这里插入图片描述

3.2 功能架构

在这里插入图片描述

3.3 产品原型

html页面,包括管理端和用户端两种

3.4 技术选型

在这里插入图片描述

四、开发环境搭建

在这里插入图片描述

4.1 前端环境

前端工程是基于nginx运行的,已经是打包好的程序,直接双击执行exe文件,接着在浏览器访问localhost即可。
在这里插入图片描述
在这里插入图片描述

4.2 后端环境

后端工程是基于maven进行构建的,并且进行分模块开发
导入的时候,需要配置maven的settings文件中阿里云镜像
在这里插入图片描述
在这里插入图片描述

  1. 使用git进行版本控制:本地创建仓库,远程创建仓库,将本地仓库推送到远程
  2. 数据库环境搭建:导入数据库文件即可
  3. 前后端联调:通过断点调试,一步步理清登录功能。
1.获取前端对象(employeeLoginDTO)
2.使用DTO中username属性通过EmployeeMapper查询数据库,得到emplyee对象
3.判断密码是否一致,且用户状态是否为‘启用’,都是则登录成功
4.生成JWK令牌,通过配置文件获取密钥和过期时间,令牌名称为token
5.通过Builder注解的方法生成employeeLoginVO对象,包括主键值、用户名、姓名和jwt令牌
6.后端统一返回结果为Result<T>,封装了错误信息msg和返回的VO对象
7.另外,文件中定义了各种异常,继承自BaseException,它的父类为RuntimeException。通过全局处理器handler来捕获全部的异常,进行处理

在这里插入图片描述

  1. 前端发送的请求,如何请求到后端服务的?
    是通过nginx方向代理,将前端发送的动态请求有nginx转发到后端服务器
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. 完善登录功能
    在数据库中加密存储密码—> 在server登录功能处,将明文密码先加密在进行对比

五、导入接口文档

接口设计能力
前后端分离开发流程。使用apifox导入接口json文件。划分了两个文件,包括管理端和用户端。
在这里插入图片描述

六、Swagger

6.1 介绍

在这里插入图片描述

6.2 使用方式

在这里插入图片描述
在这里插入图片描述
最后去网页访问http://localhost:8080/doc.html,会出现下面的界面
在这里插入图片描述
在这里插入图片描述

6.3 常用注解

在这里插入图片描述

day2

一、新增员工

  1. 根据接口文档,写service。EmployeeController.java
	/**
     * 新增员工
     * @param employeeDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增员工")
    public Result save(@RequestBody EmployeeDTO employeeDTO){
        log.info("新增员工:{}", employeeDTO);
        employeeService.save(employeeDTO);
        return  Result.success();
    }
  1. 完善EmployeeService接口和EmployeeServiceImpl接口实现类的save方法。EmployeeServiceImpl.java
    /**
     * 新增员工
     * @param employeeDTO
     */
    public void save(EmployeeDTO employeeDTO) {
        // 对象的转换,将DTO转为实体对象
        Employee employee = new Employee();
        // 对象属性拷贝,将dto对象拷贝给entity。DTO和entity对象的属性名有一部分一致
        BeanUtils.copyProperties(employeeDTO,employee);

        // 对entity的其他属性初始化
        employee.setStatus(StatusConstant.ENABLE); //状态
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes())); //密码
        employee.setCreateTime(LocalDateTime.now()); //创建时间
        employee.setUpdateTime(LocalDateTime.now()); //修改时间
        // todo 后期需要改为当前用户的属性
        employee.setCreateUser(10L); //创建人
        employee.setUpdateUser(10L); //修改人

        employeeMapper.insert(employee);
    }
  1. 完善EmployeeMapper接口中的sql。EmployeeMapper.java
    /**
     * 插入员工数据
     * @param employee
     */
    @Insert("insert into employee (name, username, password, phone, sex, id_number, status, create_time, update_time, " +
            "create_user, update_user) values (#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, " +
            "#{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
    void insert(Employee employee);
  1. 通过接口文档测试功能(常用)或者是前后端联调测试。
    通过接口文档测试的时候,发出的请求需要带上token令牌。因此需要添加一个全局变量,名称为token。
    在这里插入图片描述
  2. 完善登录功能。重复录入,抛出异常没有处理;新增员工,创建人和修改人设置的是固定值。完善好仍要进行测试。
    在这里插入图片描述
    在这里插入图片描述
//1.重复录入,异常处理即可
//GlobalExceptionHandler.java
    /**
     * 处理sql异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String username = message.split(" ")[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }else{
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }


//2.使用threadLocal方法解决获取当前用户id
//BaseContext.java
package com.sky.context;

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

}
//JwtTokenAdminInterceptor.java
BaseContext.setCurrentId(empId);
//EmployeeServiceImpl.java
employee.setCreateUser(BaseContext.getCurrentId()); //创建人
employee.setUpdateUser(BaseContext.getCurrentId()); //修改人

二、员工分页查询

//EmployeeController.java
	/**
     * 员工分页查询
     * @param employeePageQueryDTO
     * @return
     */
    @GetMapping
    @ApiOperation("员工分页查询")
    public Result<PageResult> pageQuery(EmployeePageQueryDTO employeePageQueryDTO){
        log.info("员工分页查询,参数为:{}", employeePageQueryDTO);
        PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);
        return Result.success(pageResult);
    }

//EmployeeServiceImpl.java
    /**
     * 员工分页查询
     * @param employeePageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        //select * from employee limit 0,10
        //开始分页查询
        PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
        Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);
        long total = page.getTotal();
        List<Employee> records = page.getResult();
        return new PageResult(total, records);
    }
  
//EmployeeMapper.java
    /**
     * 员工分页查询
     * @param employeePageQueryDTO
     * @return
     */
    Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);

//EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.EmployeeMapper">
    <select id="pageQuery" resultType="com.sky.entity.Employee">
        select * from
        <where>
            <if test="name != null and name != ''">
                and name like concat('%',#{name},'%')
            </if>
        </where>
        order by create_time desc
    </select>
</mapper>

完善代码:1时间的问题
在这里插入图片描述

    /**
     * 扩张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);
    }

三、启用禁用员工账号

//EmployeeController.java
    /**
     * 启用禁用员工账号
     * @param status
     * @param id
     * @return
     */
    @PostMapping("/status/{status}")
    @ApiOperation("启用禁用员工账号")
    public Result startOrStop(@PathVariable Integer status, Long id){
        log.info("启用禁用员工账号:{},{}", status, id);
        employeeService.startOrStop(status,id);
        return Result.success();
    }

//EmployeeServiceImpl.java
    /**
     * 启用禁用员工账号
     * @param status
     * @param id
     * @return
     */
    public void startOrStop(Integer status, Long id) {
        //update employee set status=? where id = ?
        //为了更通用的使用update方法,在mapper中定义的是通用的update方法,每次传递一个实体对象,而不是修改的属性

//        Employee employee = new Employee();
//        employee.setStatus(status);
//        employee.setId(id);

        Employee employee = Employee.builder()
                .status(status)
                .id(id)
                .build();
        employeeMapper.update(employee);
    }

//EmployeeMapper.xml
    <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="status != null">status = #{status},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateUser != null">update_user = #{updateUser},</if>
        </set>
        where id = #{id}
    </update>

四、编辑员工

两个接口,根据id查询员工,修改员工信息

//EmployeeController.java
    /**
     * 根据id查询员工
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询员工")
    public Result<Employee> getById(@PathVariable Long id){
        Employee employee = employeeService.getById(id);
        return Result.success(employee);
    }

    /**
     * 编辑员工信息
     * @param employeeDTO
     * @return
     */
    @PutMapping
    @ApiOperation("编辑员工信息")
    public Result update(@RequestBody EmployeeDTO employeeDTO){
        log.info("编辑员工信息:{}", employeeDTO);
        employeeService.update(employeeDTO);
        return Result.success();
    }

//EmployeeServiceImpl.java
    /**
     * 根据id查询员工
     * @param id
     * @return
     */
    public Employee getById(Long id) {
        Employee employee = employeeMapper.getById(id);
        employee.setPassword("****"); // 将传给前端的密码设置为*
        return employee;
    }

    /**
     * 编辑员工信息
     * @param employeeDTO
     */
    public void update(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO,employee);
        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(BaseContext.getCurrentId());
        employeeMapper.update(employee);
    }

//EmployeeMapper.java
    /**
     * 根据id查询员工
     * @param id
     * @return
     */
    @Select("select  * from employee where id = #{id}")
    Employee getById(Long id);

五、导入分类模块功能代码

在这里插入图片描述

day3

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

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

相关文章

【无标题】PHP-parse_str变量覆盖

[题目信息]&#xff1a; 题目名称题目难度PHP-parse_str变量覆盖1 [题目考点]&#xff1a; 变量覆盖指的是用我们自定义的参数值替换程序原有的变量值&#xff0c;一般变量覆盖漏洞需要结合程序的其它功能来实现完整的攻击。 经常导致变量覆盖漏洞场景有&#xff1a;$$&…

paddle gpu install

官方教程 https://www.paddlepaddle.org.cn/documentation/docs/zh/install/pip/linux-pip.html#sanyanzhenganzhuang 创建一个新的环境安装 python3 -m pip install paddlepaddle-gpu2.6.1.post112 -f https://www.paddlepaddle.org.cn/whl/linux/cudnnin/stable.htmlpython …

网络基础-TCP和UDP协议区别

什么是 TCP 协议&#xff1f; TCP 全称是 Transmission Control Protocol&#xff08;传输控制协议&#xff09;&#xff0c;它由 IETF 的 RFC 793 定义&#xff0c;是一种面向连接的点对点的传输层通信协议。 TCP 通过使用序列号和确认消息&#xff0c;从发送节点提供有关传输…

请陪伴Kimi和GPT成长

经验的闪光汤圆 但是我想要写实的 你有吗&#xff1f; 岁数大了&#xff0c;希望如何学习新知识呢&#xff1f;又觉得自己哪些能力亟需补强呢&#xff1f; 看论文自然得用Kimi&#xff0c;主要是肝不动了&#xff0c;眼睛也顶不住了。 正好昨天跟专业人士学会了用工作流的办法跟…

【动态规划 状态机dp】3082. 求出所有子序列的能量和

算法可以发掘本质&#xff0c;如&#xff1a; 一&#xff0c;若干师傅和徒弟互有好感&#xff0c;有好感的师徒可以结对学习。师傅和徒弟都只能参加一个对子。如何让对子最多。 二&#xff0c;有无限多1X2和2X1的骨牌&#xff0c;某个棋盘若干格子坏了&#xff0c;如何在没有坏…

idea连接Docker数据库

我们在docker下创建了数据库&#xff0c;想要更方便的查看和操作该数据库&#xff0c;idea和DataGrip或者其他人家都可以。在数据库连接时需要填写数据库名字&#xff0c;主机&#xff0c;端口&#xff0c;数据库用户名和密码。 输入之后先不要点击OK和按Enter键&#xff0c;我…

vue+springboot实验个人信息,修改密码,忘记密码功能实现

前端部分 新增Person&#xff08;个人页面&#xff09;&#xff0c;Password&#xff08;修改密码页面&#xff09;&#xff0c;还需要对Manager&#xff0c;login页面进行修改 router文件夹下的index.js&#xff1a; import Vue from vue import VueRouter from vue-router i…

【运输层】TCP 的流量控制和拥塞控制

目录 1、流量控制 2、TCP 的拥塞控制 &#xff08;1&#xff09;拥塞控制的原理 &#xff08;2&#xff09;拥塞控制的具体方法 1、流量控制 一般说来&#xff0c;我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快&#xff0c;接收方就可能来不及接收&#x…

Ubuntu20.04无法连接蓝牙

连接蓝牙的时候一直转圈显示搜索中&#xff0c;但是搜索不出来任何设备。 在终端输入 dmesg | grep -i blue 可看到有以下信息 可以看到无法识别蓝牙&#xff0c;处于一个unknow的状态 Bluetooth: hci0: RTL: unknown IC info, lmp subver 8852, hci rev 000b, hci ver 000b…

云轴科技ZStack入选中国信通院《高质量数字化转型产品及服务全景图(2023年度)》

近日&#xff0c;由中国互联网协会主办、中国信通院承办的“2024高质量数字化转型创新发展大会”暨“铸基计划”年度会议在北京成功召开。 本次大会发布了2024年度行业数字化转型趋势&#xff0c;总结并展望了“铸基计划”2023年取得的工作成果及2024年的工作规划。同时&#…

支付宝支付之SpringBoot整合支付宝创建自定义支付二维码

文章目录 自定义支付二维码pom.xmlapplication.yml自定义二维码类AlipayService.javaAlipayServiceImpl.javaAlipayController.javaqrCode.html 自定义支付二维码 继&#xff1a;SpringBoot支付入门 pom.xml <dependency><groupId>org.springframework.boot<…

大语言模型微调技术

Adapter 参考资料&#xff1a;《Parameter-efficient transfer learning for nlp》 adpater首先将原始的d维特征映射到较小的维度m&#xff0c;应用非线性函数&#xff0c;然后再重新映射回d维。总的参数量&#xff08;包含biases&#xff09;为 2mddm&#xff0c; 当m远小于d…

算法打卡day38

今日任务&#xff1a; 1&#xff09;完全背包理论基础(卡码网52. 携带研究材料) 2&#xff09;518.零钱兑换II 3&#xff09;377. 组合总和 Ⅳ 4&#xff09;复习day13 完全背包理论基础(卡码网52. 携带研究材料) 题目链接&#xff1a;52. 携带研究材料&#xff08;第七期模拟…

以大学生活为主题的演讲稿(3篇)

以大学生活为主题的演讲稿&#xff08;3篇&#xff09; 以下是三篇以大学生活为主题的演讲稿范文&#xff0c;供您参考&#xff1a; 演讲稿一&#xff1a;拥抱大学生活&#xff0c;绽放青春梦想 尊敬的老师、亲爱的同学们&#xff1a; 大家好&#xff01; 今天&#xff0c;我…

VLAN知识点总结

首先对交换机等设备进行了解 中继器&#xff1a;物理层设备 只能提供电流信息的电压恢复&#xff0c;但无法恢复波形&#xff0c;所以无法理论无限延长传输距离 集线器&#xff1a;物理层设备 多接口的中继器 二层交换机的作用&#xff1a; 区别集线器&#xff08;HUB&#…

【问题处理】银河麒麟操作系统实例分享,服务器操作系统VNC远程问题分析

1.服务器环境以及配置 【内核版本】 4.19.90-23.8.v2101.ky10.aarch64 【OS镜像版本】 0518-server 2.问题现象描述 服务器通过vncserver:1.service服务启动的vnc服务后&#xff0c;普通用户用vnc连接时&#xff0c;锁屏后&#xff0c;然后输入登陆密码会报密码错误&…

五款3dmax常用插件推荐(含云渲染工具)

在三维建模和动画设计领域&#xff0c;3ds Max软件因其强大功能和灵活性而广受欢迎。为了进一步提升工作效率和创作质量&#xff0c;有许多插件可供选择。本文推荐五款常用3ds Max插件&#xff0c;帮助你更好实现复杂的模型和动效创作。 五款3dmax常用插件推荐 1、Kitchen Cab…

RocketMQ并发消息消费重试DEMO

无序消息的重试只针对集群消费模式生效&#xff1b;广播消费模式不提供失败重试特性 Producer 发了100个对象消息 public class AddProducer {public static void main(String[] args) throws Exception {DefaultMQProducer producer new DefaultMQProducer("a-group&q…

计算机视觉入门:探索机器如何“看见”世界

计算机视觉是人工智能领域的一个令人兴奋的分支&#xff0c;它使计算机能够从图像和视频中“看见”和理解世界。这项技术已经渗透到我们生活的方方面面&#xff0c;从智能手机的面部识别到自动驾驶汽车的导航系统。但是&#xff0c;计算机视觉是如何工作的呢&#xff1f;让我们…

U盘管理软件 设置U盘权限的软件

U盘管理软件 设置U盘权限的软件 我们都知道U盘的功能很强大&#xff0c;携带也很方便&#xff0c;但是它的危险指数也是相当高的&#xff0c;既容易携带病毒&#xff0c;又可以拷贝公司里的保密文件。所以很多企业都很关注对U盘使用的管理&#xff0c;而方法&#xff0c;最好的…
最新文章