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

目录

来源: 黑马程序员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. 前后端联调:通过断点调试,一步步理清登录功能。
bash 复制代码
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
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
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
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. 完善登录功能。重复录入,抛出异常没有处理;新增员工,创建人和修改人设置的是固定值。完善好仍要进行测试。

java 复制代码
//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()); //修改人

二、员工分页查询

java 复制代码
//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时间的问题

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

三、启用禁用员工账号

java 复制代码
//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查询员工,修改员工信息

java 复制代码
//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

相关推荐
Themberfue5 分钟前
基础算法之双指针--Java实现(下)--LeetCode题解:有效三角形的个数-查找总价格为目标值的两个商品-三数之和-四数之和
java·开发语言·学习·算法·leetcode·双指针
深山夕照深秋雨mo14 分钟前
在Java中操作Redis
java·开发语言·redis
努力的布布19 分钟前
SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器
java·后端·spring
xujinwei_gingko19 分钟前
Spring MVC 常用注解
java·spring·mvc
PacosonSWJTU24 分钟前
spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)
java·后端·springmvc
PacosonSWJTU26 分钟前
spring揭秘26-springmvc06-springmvc注解驱动的web应用
java·spring·springmvc
原野心存1 小时前
java基础进阶——继承、多态、异常捕获(2)
java·java基础知识·java代码审计
进阶的架构师1 小时前
互联网Java工程师面试题及答案整理(2024年最新版)
java·开发语言
黄俊懿1 小时前
【深入理解SpringCloud微服务】手写实现各种限流算法——固定时间窗、滑动时间窗、令牌桶算法、漏桶算法
java·后端·算法·spring cloud·微服务·架构
木子02041 小时前
java高并发场景RabbitMQ的使用
java·开发语言