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

SpringBoot实战第三天

今天主要完成了:

新增棋子分类

棋子分类列表

获取棋子分类详情

更新棋子分类

更新棋子分类和添加棋子分类_分组校验

新增棋子

新增棋子参数校验

棋子分类列表查询(条件分页)

先给出分类实体类

@Data
public class Category {private Integer id;//主键ID@NotEmptyprivate String categoryName;//分类名称(赛季全名)@NotEmptyprivate String categoryAlias;//分类别名(赛季版本号)private Integer createUser;//创建人IDprivate LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//更新时间
}

新增棋子分类

接口文档

 

读接口文档,需求就是一个@Insert,但是发现接口文档没有考虑到可能会有重复分类的创建,我认为重复分类的创建是不合适的,所以我做了一个分类存在检测以防止重复分类的出现

基本属于User新建的小修小改,直接上代码

Controller层

    @PostMappingpublic Result add(@RequestBody @Validated Category category){String init_name = category.getCategoryName();Category incategory = categoryService.getCategoryByNAME(init_name);if (incategory == null){        categoryService.add(category);return Result.success();} else {return Result.error("棋子分类已存在!");}}

写了一个条件判断来防止重复分类的出现,用json里给的分类名查分类是否存在

Service层

    @Overridepublic void add(Category category) {Map<String,Object> map = ThreadLocalUtil.get();Integer id  = (Integer) map.get("id");category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());category.setCreateUser(id);categoryMapper.add(category);}@Overridepublic Category getCategoryByNAME(String init_name) {Category c = categoryMapper.getCategoryByNAME(init_name);return c;}

一个新增一个查询,为了达成给分类写入创建人相关信息,还是老方法,从ThreadLocal里面取

Mapper层

    @Insert("insert into category(category_name,category_alias,create_user,create_time,update_time) " +"values(#{categoryName},#{categoryAlias},#{createUser},#{createTime},#{updateTime}) ")void add(Category category);@Select("Select * from category where category_name = #{init_name}")Category getCategoryByNAME(String init_name);

 搞定

棋子分类列表

接口文档

 可以看到,这次不需要接入任何参数,返回的是一个棋子分类列表,区别不大,开搞!

ps:突然发现接口文档要求的时间格式跟直接捞出来的localdatatime格式不一样,这是个问题

Controller层

    @GetMappingpublic Result<List<Category>> list(){List<Category> categoryList = categoryService.list();return Result.success(categoryList);}

Service层

    @Overridepublic List<Category> list() {Map<String,Object> map = ThreadLocalUtil.get();Integer id  = (Integer) map.get("id");return categoryMapper.list(id);}

老规矩,ThreadLocal拿用户信息 

Mapper层

    @Select("select * from category where create_user = #{id}")List<Category> list(Integer id);

解决给出时间格式需修改问题 

在实体类中用 @JsonFormat接口

    private LocalDateTime createTime;//创建时间@JsonFormat(pattern = TIME_REGEXP)private LocalDateTime updateTime;//更新时间

RT,相应的也更新了我的正则文件

    public static final String TIME_REGEXP = "^yyyy-MM-dd HH:mm:ss";

搞定收工 

 

获取棋子分类详情

接口文档

 

阅读接口文档,通过分类ID获取分类全部信息,再多考虑下非法ID输入就行

Controller层

    @GetMapping("detail")public Result<Category> getDetail(Integer id){Category category = categoryService.getCategoryByID(id);if (category == null){return Result.error("查询分类不存在!");}else {return Result.success(category);}}

做了个简单逻辑判断来确保查询的分类是存在的 

Service层

    @Overridepublic Category getCategoryByID(Integer init_ID) {return categoryMapper.getCategoryByID(init_ID);}

Mapper层

    @Select("Select * from category where id = #{init_ID}")Category getCategoryByID(Integer init_ID);

 顺手修改下新增棋子接口

由于这个按ID查询棋子和新增棋子接口用的按分类名查询实际上效果一样,为了提高代码复用率,把新增棋子接口的查询直接改成按ID查询,如下:

    @PostMappingpublic Result add(@RequestBody @Validated Category category){Integer init_ID = category.getId();Category incategory = categoryService.getCategoryByID(init_ID);if (incategory == null){        categoryService.add(category);return Result.success();} else {return Result.error("棋子分类已存在!");}}

(别忘了删除其他基层的按分类名查询) 

 

 

更新棋子分类

接口文档

 

 读接口文档,注意下参数校验和身份验证就行

先看Controller层

    @PutMappingpublic Result update(@RequestBody @Validated Category incategory){Category category = categoryService.getCategoryByID(incategory.getId());if (category == null){return Result.error("要修改的分类不存在!");}else {Integer userID = category.getCreateUser();Map<String,Object> map = ThreadLocalUtil.get();Integer id_user  = (Integer) map.get("id");if (userID.equals(id_user)){categoryService.update(incategory);return Result.success();}else {return Result.error("您所要更改的分类不属于您!");}}}

先对要更改的分类存不存在进行验证,如果存在在进行身份验证,都验证通过了就可以进行修改操作了

Service层

    @Overridepublic void update(Category category) {category.setUpdateTime(LocalDateTime.now());categoryMapper.update(category);}

Mapper层

    @Update("update category set category_name = #{categoryName} , category_alias = #{categoryAlias} , update_time = #{updateTime} where id = #{id}")void update(Category category);

对了,要在实体类中给id加一个@NotNull注解来验证

    @NotNullprivate Integer id;//主键ID

搞定收工 

 

更新棋子分类和添加棋子分类_分组校验

由于我们在刚刚写修改棋子分类的时候给ID加上了notnull的注解,导致了在每次检验CateGory对象的时候都会检验id是否为null,而我们在写新增分类的时候由于id是会自增的所以我们并没有传入棋子id。这时,刚刚的更改会导致新增分类接口无法正常使用,为了解决这个问题,我们就要用到分组校验

分组校验

把校验项进行归类分组,在完成不同功能的时候,校验指定组中的校验项

步骤

1.定义分组

使用接口来定义分组

例如我们要给category加add和update两个分组,我们就可以在其实体类中定义如下两个分组

    public interface Add{}public interface Update{}
2.定义校验项时指定归属的分组

如下例:

    @NotNull(groups = Update.class)private Integer id;//主键ID@NotEmpty(groups = {Update.class,Add.class})private String categoryName;//分类名称@NotEmpty(groups = {Update.class,Add.class})private String categoryAlias;//分类别名

可以看到,分组可以同时指定多个,用{}来承接 

3.校验时指定要校验的分组
 public Result add(@RequestBody @Validated(Category.Add.class) Category category){public Result update(@RequestBody @Validated(Category.Update.class) Category incategory){
小优化

校验分组存在如下两条规则

1.如果某个校验项没有指定分组,则默认属于Defult分组

2.分组之间可以继承,A extends B,则A中继承B中所有的校验项目

那么我们可以对上例进行如下优化:

我们可以看到add和update的唯一区别就是对于ID非空的检验,所以我们可以让其他所有校验直接进入Defult组,并让我们自定义的两个分组都继承Defult组,add独立的划入对于ID的飞控检查

@Data
public class Category {@NotNull(groups = Update.class)private Integer id;//主键ID@NotEmptyprivate String categoryName;//分类名称@NotEmptyprivate String categoryAlias;//分类别名private Integer createUser;//创建人ID@JsonFormat(pattern = TIME_REGEXP)private LocalDateTime createTime;//创建时间@JsonFormat(pattern = TIME_REGEXP)private LocalDateTime updateTime;//更新时间public interface Add extends Default {}public interface Update extends Default {}

相关文章:

SpringBoot实战第三天

今天主要完成了&#xff1a; 新增棋子分类 棋子分类列表 获取棋子分类详情 更新棋子分类 更新棋子分类和添加棋子分类_分组校验 新增棋子 新增棋子参数校验 棋子分类列表查询(条件分页) 先给出分类实体类 Data public class Category {private Integer id;//主键IDNot…...

mysql学习打卡day22

今日成果&#xff1a; select * from employees where salary > (select avg(salary) from employees); -- 查询超过平均工资的员工select * from clients where client_id not in (select distinct client_id from invoices); -- 查询没有发票的用户 感谢各位读者查阅&…...

Unity | Spine动画记录

https://blog.csdn.net/linshuhe1/article/details/79792432 https://blog.csdn.net/winds_tide/article/details/128925407 1.需要的三个文件 通常制作好的 Spine 动画导出时会有三个文件&#xff1a; .png 、.json 和 .atlas&#xff1a; skeleton-name.json 或 skeleton-…...

【Flink】FlinkSQL实现数据从MySQL到MySQL

简介 我们在实际开发过程中可以使用Flink实现数据从MySQL传输到MySQL具体操作,本例子Flink版本1.13.6,具体操作如下: 创建mysql测试表 下面语句创建了mysql原表和目标表,并插入一条语句到mysql原表中 CREATE TABLE `mysql_source` ( `id` int(11) unsigned NOT NULL AUT…...

python爬虫抓取新闻并且植入自己的mysql远程数据库内

python爬虫抓取新闻并且植入自己的mysql远程数据库内&#xff01;这个代码是我自己写了很久才写好的&#xff0c;分享给大家。喜欢的点个赞。 # -*- coding: utf-8 -*- from xml.etree import ElementTree as ET import datetime import randomimport pymysql from selenium im…...

netty实现简单的客户端、服务端互相发消息

引入maven依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.20.Final</version> </dependency> 一、服务端 1、创建服务端启动类 public class MyServer {public static voi…...

利用jmeter完成简单的压力测试

Jmeter是一个非常好用的压力测试工具。Jmeter用来做轻量级的压力测试&#xff0c;非常合适&#xff0c;只需要十几分钟&#xff0c;就能把压力测试需要的脚本写好。 1、什么是压力测试 顾名思义&#xff1a;压力测试&#xff0c;就是 被测试的系统&#xff0c;在一定的访问压…...

【手写数据库toadb】toadb物理存储模型,数据库物理存储原理,物理文件组织关系以及行列混合模型存储结构

存储模型概述 ​专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段…...

MySQL-----DDL基础操作

SQL通用语法 1.SQL语句可以单行或多行书写&#xff0c;以分号结尾。 2. SQL语句可以使用空格/缩进来增强语句的可读性。 3. MySQL数据库的SQL语句不区分大小写&#xff0c;关键字建议使用大写。 4&#xff0e;注释: 单行注释:--注释内容或#注释内容(MySQL特有) 多行注释:/*注释…...

【MySQL】在 Centos7 环境安装 MySQL -- 详细完整教程

说明&#xff1a; 安装与卸载中&#xff0c;用户全部切换成为 root&#xff0c;一旦安装&#xff0c;普通用户就能使用。 一、卸载内置环境 1、卸载不要的环境 [rootVM-8-5-centos ~]$ ps ajx | grep mariadb # 先检查是否有mariadb存在 13134 14844 14843 13134 pts/0 14843…...

理解React中的setState()方法

在React中&#xff0c;setState()方法是一个非常重要的概念&#xff0c;它用于更新组件的状态并触发重新渲染。本文将探讨setState()的使用方法、工作原理以及一些基本的用法。 setState()方法简介 setState()是React组件中用于更新状态的方法之一。它接受一个对象或一个函数作…...

数据库管理-第144期 深入使用EMCC-01(20240204)

数据库管理144期 2024-02-04 数据库管理-第144期 深入使用EMCC-01&#xff08;20240204&#xff09;1 用户管理2 配置告警动作3 配置意外事件规则总结 数据库管理-第144期 深入使用EMCC-01&#xff08;20240204&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&am…...

flask_django_python五金电商网络营销的可视化分析研究

前面部分完成了系统需求分析&#xff0c;了解到新闻数据业务方面的需求&#xff0c;系统主要分为用户管理、五金信息管理、在线留言、系统管理等功能。销的可视化研究&#xff0c;并对这些数据进行处理&#xff0c; 然后对这些数据进行可视化分析和统计。 Python 爬虫技术目前来…...

Java并发(二十三)----同步模式之保护性暂停

1、定义 即 Guarded Suspension&#xff0c;用在一个线程等待另一个线程的执行结果 要点 有一个结果需要从一个线程传递到另一个线程&#xff0c;让他们关联同一个 GuardedObject 如果有结果不断从一个线程到另一个线程那么可以使用消息队列 JDK 中&#xff0c;join 的实现…...

###C语言程序设计-----C语言学习(9)#函数基础

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 一. 基础知识的学习 1.函数的定义 函数是一个完成特定工作的独立程序模块&…...

Dockerfile文件参数配置和使用

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

Java实现婚恋交友网站 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…...

React16源码: React中详解在渲染阶段Suspend的源码实现

Suspend 挂起详解 1 &#xff09;概述 在react的更新过程当中&#xff0c;它的任务是可以被挂起的&#xff0c;也就是 Suspend关于 Suspend 字面意思就是挂起在某次更新的任务更新完成之后&#xff0c;暂时不提交 在 react更新中&#xff0c;分为两个阶段&#xff0c;首先是re…...

mac电脑风扇控制软件:Macs Fan Control Pro for mac 激活版

Macs Fan Control 是一款专门为 Mac 用户设计的软件&#xff0c;它可以帮助用户控制和监控 Mac 设备的风扇速度和温度。这款软件允许用户手动调整风扇速度&#xff0c;以提高设备的散热效果&#xff0c;减少过热造成的风险。 Macs Fan Control 可以在菜单栏上显示当前系统温度和…...

easyexcel解析跨多行的数据

在使用easyexcel解析excel文件的时候&#xff0c;存在某列横跨多行&#xff0c;那么存在解析出的对象的某些属性是没有值的&#xff0c;那么我们要怎么处理呢&#xff1f;代码如下 定义实体对应excel文件 public class EtcParkingReconciliationDailyImportModel implements S…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...