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

开始尝试从0写一个项目--后端(二)

实现学生管理

新增学生

接口设计

请求路径:/admin/student

请求方法:POST

请求参数:请求头:Headers:"Content-Type": "application/json"

请求体:Body:

id 学生id

idNumber 学生身份证

name 名字

phone 电话号码

sex 性别

username 用户名

返回数据:Result

student表设计

字段名

数据类型

说明

备注

id

bigint

主键

自增

name

varchar(32)

姓名

username

varchar(32)

用户名

唯一

password

varchar(64)

密码

phone

varchar(11)

手机号

sex

varchar(2)

性别

id_number

varchar(18)

身份证号

status

Int

账号状态

1正常 0锁定

create_time

Datetime

创建时间

update_time

datetime

最后修改时间

create_user

bigint

创建人id

update_user

bigint

最后修改人id

代码开发

设计DTO类接收前端传来的参数

sems-pojo/src/main/java/com/ljc/dto/StudentDTO.java

package com.ljc.dto;import lombok.Data;import java.io.Serializable;@Data
public class StudentDTO implements Serializable {//学生idprivate Long id;//用户名private String username;//姓名private String name;//电话private String phone;//性别private String sex;//身份证号private String idNumber;}

controller层

sems-server/src/main/java/com/ljc/controller/student/StudentController.java

package com.ljc.controller.student;import com.ljc.constant.JwtClaimsConstant;
import com.ljc.dto.StudentDTO;
import com.ljc.dto.StudentLoginDTO;
import com.ljc.entity.Student;
import com.ljc.properties.JwtProperties;
import com.ljc.result.Result;
import com.ljc.service.StudentService;
import com.ljc.utils.JwtUtil;
import com.ljc.vo.StudentLoginVO;import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
@RequestMapping("/admin/student")
@Slf4j
public class StudentController {@Autowiredprivate StudentService studentService;@Autowiredprivate JwtProperties jwtProperties;/*** 登录** @param studentLoginDTO* @return*/@ApiOperation("用户登录")@PostMapping("/login")public Result<StudentLoginVO> login(@RequestBody StudentLoginDTO studentLoginDTO) {log.info("学生登录:{}", studentLoginDTO);Student student = studentService.login(studentLoginDTO);//登录成功后,生成jwt令牌Map<String, Object> claims = new HashMap<>();claims.put(JwtClaimsConstant.EMP_ID, student.getId());String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),jwtProperties.getAdminTtl(),claims);StudentLoginVO studentLoginVO = StudentLoginVO.builder().id(student.getId()).userName(student.getUsername()).name(student.getName()).token(token).build();return Result.success(studentLoginVO);}/*** 退出** @return*/@ApiOperation("用户退出")@PostMapping("/logout")public Result<String> logout() {return Result.success();}/*** 新增学生* @param studentDTO* @return*/@PostMapping@ApiOperation("新增学生")public Result save(@RequestBody StudentDTO studentDTO){//日志,现在进行的是新增学生功能log.info("新增学生:{}", studentDTO);//调用service层(处理层)的方法进行新增studentService.save(studentDTO);return Result.success();}}

Service层

sems-server/src/main/java/com/ljc/service/StudentService.java

package com.ljc.service;import com.ljc.dto.StudentDTO;
import com.ljc.dto.StudentLoginDTO;
import com.ljc.entity.Student;public interface StudentService {/*** 学生登录* @param studentLoginDTO* @return*/Student login(StudentLoginDTO studentLoginDTO);/*** 新增学生* @param studentDTO*/void save(StudentDTO studentDTO);
}

ServiceImpl层

sems-server/src/main/java/com/ljc/service/impl/StudentServiceImpl.java

package com.ljc.service.impl;import com.ljc.constant.MessageConstant;
import com.ljc.constant.PasswordConstant;
import com.ljc.constant.StatusConstant;
import com.ljc.context.BaseContext;
import com.ljc.dto.StudentDTO;
import com.ljc.dto.StudentLoginDTO;
import com.ljc.entity.Student;
import com.ljc.exception.AccountLockedException;
import com.ljc.exception.AccountNotFoundException;
import com.ljc.exception.PasswordErrorException;
import com.ljc.mapper.StudentMapper;
import com.ljc.service.StudentService;import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.time.LocalDateTime;@Service
public class StudentServiceImpl implements StudentService {@Autowiredprivate StudentMapper studentMapper;/*** 学生登录** @param studentLoginDTO* @return*/public Student login(StudentLoginDTO studentLoginDTO) {String username = studentLoginDTO.getUsername();String password = studentLoginDTO.getPassword();//1、根据用户名查询数据库中的数据Student student = studentMapper.getByUsername(username);//2、处理各种异常情况(用户名不存在、密码不对、账号被锁定)if (student == null) {//账号不存在throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);}//密码比对// 进行md5加密,然后再进行比对password = DigestUtils.md5DigestAsHex(password.getBytes());if (!password.equals(student.getPassword())) {//密码错误throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);}if (student.getStatus() == StatusConstant.DISABLE) {//账号被锁定throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);}//3、返回实体对象return student;}/**** 新增学生* @param studentDTO*/@Overridepublic void save(StudentDTO studentDTO) {//1. 创建一个学生对象Student student = new Student();//2. 将前端传后来的参数,即就是封装在DTO里面的数据转移到学生对象中//调用对象属性拷贝,括号里面参数,前面的是需要传递的数据,后面的是接收的数据BeanUtils.copyProperties(studentDTO,student);//3. 补充student里面的数据,前端没有传递回来的//3.1 前端没有传递账号状态,现在给设置账号状态:默认为正常,正常为1,异常为0;//由于1太不美观了,创建一个常量类/*student.setStatus(1);*/student.setStatus(StatusConstant.ENABLE);//3.2 设置密码:默认为123456,进行MD5加密//密码也设置一个常量:PasswordConstant.DEFAULT_PASSWORD/*student.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));*/student.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));//3.3 设置创建时间和修改时间: 为当前时间student.setCreateTime(LocalDateTime.now());student.setUpdateTime(LocalDateTime.now());//3.4 设置创建人的idstudent.setCreateUser(BaseContext.getCurrentId());student.setUpdateUser(BaseContext.getCurrentId());//4 调用mapper层数据,连接数据库,对数据库进行操作studentMapper.insert(student);}}

mapper层

sems-server/src/main/java/com/ljc/mapper/StudentMapper.java

package com.ljc.mapper;import com.ljc.entity.Student;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface StudentMapper {/*** 根据用户名查询学生* @param username* @return*/@Select("select * from student where username = #{username}")Student getByUsername(String username);/*** 新增学生* @param student*/@Insert("insert into student (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user,status) " +"values " +"(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})")void insert(Student student);
}

补充代码

这里面有几个常量值,和一个ThreadLocal来获取jwt令牌里面的用户名

封装了 ThreadLocal 操作的工具类:

sems-common/src/main/java/com/ljc/context/BaseContext.java

package com.ljc.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();}}

常量类

密码

sems-common/src/main/java/com/ljc/constant/PasswordConstant.java

package com.ljc.constant;/*** 密码常量*/
public class PasswordConstant {public static final String DEFAULT_PASSWORD = "123456";}

补充用户名重复常量

sems-common/src/main/java/com/ljc/constant/MessageConstant.java

package com.ljc.constant;/*** 信息提示常量类*/
public class MessageConstant {public static final String PASSWORD_ERROR = "密码错误";public static final String ACCOUNT_NOT_FOUND = "账号不存在";public static final String ACCOUNT_LOCKED = "账号被锁定";public static final String UNKNOWN_ERROR = "未知错误";public static final String USER_NOT_LOGIN = "用户未登录";public static final String CATEGORY_BE_RELATED_BY_SETMEAL = "当前分类关联了套餐,不能删除";public static final String CATEGORY_BE_RELATED_BY_DISH = "当前分类关联了菜品,不能删除";public static final String SHOPPING_CART_IS_NULL = "购物车数据为空,不能下单";public static final String ADDRESS_BOOK_IS_NULL = "用户地址为空,不能下单";public static final String LOGIN_FAILED = "登录失败";public static final String UPLOAD_FAILED = "文件上传失败";public static final String SETMEAL_ENABLE_FAILED = "套餐内包含未启售菜品,无法启售";public static final String PASSWORD_EDIT_FAILED = "密码修改失败";public static final String DISH_ON_SALE = "起售中的菜品不能删除";public static final String SETMEAL_ON_SALE = "起售中的套餐不能删除";public static final String DISH_BE_RELATED_BY_SETMEAL = "当前菜品关联了套餐,不能删除";public static final String ORDER_STATUS_ERROR = "订单状态错误";public static final String ORDER_NOT_FOUND = "订单不存在";public static final String ALREADY_EXISTS = "已存在";
}

处理用户名重复的异常

sems-server/src/main/java/com/ljc/handler/GlobalExceptionHandler.java

package com.ljc.handler;import com.ljc.constant.MessageConstant;
import com.ljc.exception.BaseException;
import com.ljc.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.sql.SQLIntegrityConstraintViolationException;/*** 全局异常处理器,处理项目中抛出的业务异常*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {/*** 捕获业务异常* @param ex* @return*/@ExceptionHandlerpublic Result exceptionHandler(BaseException ex){log.error("异常信息:{}", ex.getMessage());return Result.error(ex.getMessage());}/*** 捕获用户名重复* */@ExceptionHandlerpublic Result exceptionHandler(SQLIntegrityConstraintViolationException ex){//Duplicate entry 'zhangsan' for key 'employee.idx_username'//获取异常信息String massage = ex.getMessage();//以” “分割异常信息;if (massage.contains("Duplicate entry")){String[] split = massage.split(" ");String name = split[2];String msg = name+ MessageConstant.ALREADY_EXISTS;//已存在已有常量,尽量避免字符串return Result.error(msg);}else {return Result.error(MessageConstant.UNKNOWN_ERROR);}}}

测试

完成后进入swagger界面测试一下

因为需要进行jwt令牌检测,所以

使用admin用户登录获取令牌

将合法的JWT令牌添加到全局参数中

检查一下添加上了没

然后开始测试

检查数据库添加上了没

学生分页查询

开发到这里我发现还得先开发前端,前端明确后,后端才有针对性,所以先完成前端代码。

麻了,前端一点不会啊,工期有点长了.....................

相关文章:

开始尝试从0写一个项目--后端(二)

实现学生管理 新增学生 接口设计 请求路径&#xff1a;/admin/student 请求方法&#xff1a;POST 请求参数&#xff1a;请求头&#xff1a;Headers&#xff1a;"Content-Type": "application/json" 请求体&#xff1a;Body&#xff1a; id 学生id …...

【图解大数据技术】Hive、HBase

【图解大数据技术】Hive、HBase Hive数据仓库Hive的执行流程Hive架构数据导入Hive HBaseHBase简介HBase架构HBase的列式存储HBase建表流程HBase数据写入流程HBase数据读取流程 Hive Hive是基于Hadoop的一个数据仓库工具&#xff0c;Hive的数据存储在HDFS上&#xff0c;底层基于…...

composables 目录下的文件(web前端)

composables 目录通常用于存放可组合的函数或逻辑&#xff0c;这些函数或逻辑可以在不同的组件中复用。具体来说&#xff0c;composables 目录下的文件通常包含以下内容&#xff1a; 组合式函数 (Composable Functions)&#xff1a; 这些函数利用 Vue 3 的组合式 API&#xff0…...

使用Python绘制堆积柱形图

使用Python绘制堆积柱形图 堆积柱形图效果代码 堆积柱形图 堆积柱形图&#xff08;Stacked Bar Chart&#xff09;是一种数据可视化图表&#xff0c;用于显示不同类别的数值在某一变量上的累积情况。每一个柱状条显示多个子类别的数值&#xff0c;子类别的数值在柱状条上堆积在…...

DP:二维费用背包问题

文章目录 &#x1f3b5;二维费用背包问题&#x1f3b6;引言&#x1f3b6;问题定义&#x1f3b6;动态规划思想&#x1f3b6;状态定义和状态转移方程&#x1f3b6;初始条件和边界情况 &#x1f3b5;例题&#x1f3b6;1.一和零&#x1f3b6;2.盈利计划 &#x1f3b5;总结 &#x1…...

C语言标准库中的函数

由于C语言标准库中的函数非常多&#xff0c;我将按类别列出一些常见函数及其作用。请注意&#xff0c;这里不可能列出所有函数&#xff0c;但我会尽量覆盖主要的类别和函数。 ### 标准输入输出 - printf: 格式化输出到标准输出&#xff08;通常是屏幕&#xff09;。 - scanf: …...

Qt5.9.9 关于界面拖动导致QModbusRTU(QModbusTCP没有测试过)离线的问题

问题锁定 参考网友的思路&#xff1a; Qt5.9 Modbus request timeout 0x5异常解决 网友认为是Qt的bug&#xff0c; 我也认同&#xff1b;网友认为可以更新模块&#xff0c; 我也认同&#xff0c; 我也编译了Qt5.15.0的code并成功安装到Qt5.9.9中进行使用&#xff0c;界面拖…...

API的定义理解

前言 在程序员的日常工作中&#xff0c;“API”这个词在程序员的口中重复的次数&#xff0c;绝对是名列前茅的。 但是对刚开始工作的新人来说&#xff0c;API这个概念还是比较模糊。 确实&#xff0c;API这个概念是随着语义环境而不一样的&#xff0c;所以会让人迷惑。 下面…...

启航IT之旅:高考假期预习指南

标题&#xff1a;启航IT之旅&#xff1a;高考假期预习指南 随着高考的落幕&#xff0c;许多有志于IT领域的学子们即将踏上新的学习旅程。这个假期&#xff0c;是他们探索IT世界的黄金时期。本文将为准IT新生们提供一份全面的预习指南&#xff0c;帮助他们为未来的学习和职业生…...

HarmonyOS开发:循环渲染ForEach

需求&#xff1a; 创建多个列表组件&#xff0c;并实现点赞功能 语言&#xff1a; ArkTS 平台&#xff1a; DevEco Studio ForEach 接口描述 ForEach( arr: Array, itemGenerator: (item: Object, index: number) > void, keyGenerator?: (item: Object, index: number) &…...

构建工程化:多种不同的工程体系如何编写MakeFile

源码分析 核心MakeFile 这个 Makefile 是一个复杂的构建脚本&#xff0c;用于管理和构建一个大型项目。它包括多个目标、条件判断和递归调用 make 命令来处理多个子项目和子目录。让我们逐部分进行详细解析。 伪目标和变量定义 .PHONY: all clean install build test init.…...

聚焦从业人员疏散逃生避险意识能力提升,推动生产经营单位每年至少组织开展(疏散逃生演练,让全体从业人员熟知逃生通道、安全出口及应急处置要求,形成常态化机制。

聚焦从业人员疏散逃生避险意识能力提升&#xff0c;推动生产经营单位每年至少组织开展(疏散逃生演练&#xff0c;让全体从业人员熟知逃生通道、安全出口及应急处置要求&#xff0c;形成常态化机制。完整试题答案查看 A.三次B.两次C.一次 综合运用“四不两直”、明察暗访、 ()、…...

【手机取证】如何使用360加固助手给apk加固

文章关键词&#xff1a;手机取证、电子数据取证、数据恢复 一、前言 APP加固是对APP代码逻辑的一种保护。原理是将应用文件进行某种形式的转换&#xff0c;包括不限于隐藏&#xff0c;混淆&#xff0c;加密等操作&#xff0c;进一步保护软件的利益不受损坏&#xff0c;下面给…...

Vue的介绍

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

MySql数据库常用指令合集

MySql数据库常用指令合集 一、创建数据库db11.创建表 字段---表头 student_no,username,sex2.新增单条插入多条插入3.删除4.更新5.查询5.1.查询该表全部信息5.2.查询该表中username&#xff0c;并且要求名字为zhangsan性别女&#xff0c;还可以用&#xff08;or&#xff09; 6.…...

ArcGIS Pro SDK (七)编辑 13 注解

ArcGIS Pro SDK &#xff08;七&#xff09;编辑 13 注解 文章目录 ArcGIS Pro SDK &#xff08;七&#xff09;编辑 13 注解1 注释构建工具2 以编程方式启动编辑批注3 更新批注文本4 修改批注形状5 修改批注文本图形6 接地到网格 环境&#xff1a;Visual Studio 2022 .NET6 …...

模拟面试001-Java开发工程师+简历+问题+回答

模拟面试001-Java开发工程师简历问题回答 目录 模拟面试001-Java开发工程师简历问题回答面试简历面试官题问求职者回答1. 关于Java编程和技术栈2. 关于XX在线购物平台项目3. 关于XX企业资源规划系统项目4. 团队协作与项目管理5. 个人发展与职业规划 参考资料 面试简历 **个人信…...

微信小程序 ——入门介绍及简单的小程序编写

目录 一、小程序入门 1.1 什么是小程序 1.2 小程序的优点 1.3 小程序注册 1.4 安装开发工具 1.5 创建第一个小程序 二、小程序目录结构及入门案例 2.1 目录结构 2.2 入门案例 2.2.1 创建界面 2.2.2 设置标题 2.2.3 编写WXML文件 2.2.4 编写JS文件 2.2.5 编写WXSS…...

ubuntu20.04安装lio-sam

1、依赖功能包安装 sudo apt install ros-noetic-robot-state-publisher sudo apt-get install ros-noetic-robot-localization libmetis-dev 2、boost版本 boost版本查看&#xff1a;cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION" boost版本为1.…...

Kafka系列之Kafka知识超强总结

一、Kafka简介 Kafka是什么 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff08;消息引擎系统&#xff09;&#xff0c;它可以处理消费者在网站中的所有动作流数据。 这种动作&#xff08;网页浏览&#xff0c; 搜索和其他用户的行动&#xff09;是在现代网络上的许多社…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...