Web day07 项目实战

目录

Restful风格:

代码结构:

 1). Controller层

2). Service层

3). Mapper(dao)层

4).yml文件:

数据封装:

1). 手动结果映射

2). 起别名

3). 开启驼峰命名(推荐)

删除部门:

新增部门:

修改数据:

日志技术(重要):

记录日志:

Logback配置文件:

1). 如果需要输出日志到控制台。添加如下配置:

2). 如果需要输出日志到文件。添加如下配置:

3). 日志开关配置 (开启日志(ALL),取消日志(OFF))

Logback日志级别:


Restful风格:

在前后端分离的开发模式中,前后端开发人员都需要根据提前定义好的接口文档,来进行前后端功能的开发。

传统URL风格如下:

http://localhost:8080/user/getById?id=1 GET:查询id为1的用户

  • http://localhost:8080/user/saveUser POST:新增用户

  • http://localhost:8080/user/updateUser POST:修改用户

  • http://localhost:8080/user/deleteUser?id=1 GET:删除id为1的用户

我们看到,原始的传统URL呢,定义比较复杂,而且将资源的访问行为对外暴露出来了。而且,对于开发人员来说,每一个开发人员都有自己的命名习惯,就拿根据id查询用户信息来说的,不同的开发人员定义的路径可能是这样的:getByIdselectByIdqueryByIdloadById... 。 每一个人都有自己的命名习惯,如果都按照各自的习惯来,一个项目组,几十号或上百号人,那最终开发出来的项目,将会变得难以维护,没有一个统一的标准。

基于REST风格URL如下:

  • http://localhost:8080/users/1 GET:查询id为1的用户

  • http://localhost:8080/users POST:新增用户

  • http://localhost:8080/users PUT:修改用户

  • http://localhost:8080/users/1 DELETE:删除id为1的用户

通过URL定位要操作的资源,通过HTTP动词(请求方式)来描述具体的操作。

  • GET : 查询

  • POST :新增

  • PUT : 修改

  • DELETE :删除

我们看到如果是基于REST风格,定义URL,URL将会更加简洁、更加规范、更加优雅

代码结构:

 1). Controller层

post添加 get查询 put修改 delete删除

get后无参数时 查询 全部 后有参数时用 @GetMapping("/{id}") 解析restful风格的参数

@RestController
@RequestMapping("/depts")
public class DeptController {@Autowiredprivate DeptService deptService;@GetMappingpublic Result findAll(){List<Dept> all = deptService.findAll();return Result.Success(all);}/*@DeleteMappingpublic Result delete(Integer id){deptService.delete(id);return Result.Success("删除成功");}*/@DeleteMappingpublic Result delete(@RequestParam("id") Integer id){deptService.delete(id);return Result.Success("删除成功");}@PostMappingpublic Result addDept(@RequestBody Dept dept){deptService.addDept(dept);return Result.Success("添加成功");}@GetMapping("/{id}")public Result findById(@PathVariable Integer id){Dept dept = deptService.findById(id);return Result.Success(dept);}@PutMappingpublic Result update(@RequestBody Dept dept){deptService.updateDept(dept);return Result.Success("修改成功");}}

2). Service层

接口:

public interface DeptService {List<Dept> findAll();Integer delete(Integer id);void addDept(Dept dept);Dept findById(Integer id);void updateDept(Dept dept);}

实现类:

@Service
public class DeptServiceImpl implements DeptService {@Autowiredprivate DeptMapper deptMapper;@Overridepublic List<Dept> findAll() {return deptMapper.selectAll();}@Overridepublic Integer delete(Integer id) {int i = deptMapper.deleteById(id);return i;}@Overridepublic void addDept(Dept dept) {dept.setCreate_time(LocalDateTime.now());dept.setUpdate_time(LocalDateTime.now());deptMapper.insert(dept);}@Overridepublic Dept findById(Integer id) {Dept dept = deptMapper.selectById(id);return dept;}@Overridepublic void updateDept(Dept dept) {dept.setUpdate_time(LocalDateTime.now());deptMapper.update(dept);}
}

3). Mapper(dao)层

@Mapper
public interface DeptMapper {@Select("select * from dept")List<Dept> selectAll();@Delete("delete from dept where id=#{id}")int deleteById(Integer id);@Insert("insert into dept values (null,#{name},#{create_time},#{update_time})")void insert(Dept dept);@Select("select * from dept where id=#{id}")Dept selectById(Integer id);@Update("update dept set name=#{name},update_time=#{update_time} where id=#{id}")void update(Dept dept);
}

4).yml文件:

spring:application:name: tlias-manager-sysdatasource:url: jdbc:mysql://127.0.0.1:3306/testdriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 1234type: com.alibaba.druid.pool.DruidDataSource
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

数据封装:

注意只有在查询时 数据库mybaits 框架自动返回对象时才会产生这个问题

当自定义实体类的 名字 和 数据库的字段名不完全一样时 在查询时:就会有不能自动封装的问题

解决方案:

  • 手动结果映射

  • 起别名

  • 开启驼峰命名

1). 手动结果映射

在DaoMapper接口方法上,通过 @Results及@Result 进行手动结果映射。

@Results({@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})
@Select("select id, name, create_time, update_time from dept")
public List<Dept> findAll();

2). 起别名

在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样。

@Select("select id, name, create_time createTime, update_time updateTime from dept")
public List<Dept> findAll();

3). 开启驼峰命名(推荐)

如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射。驼峰命名规则: abc_xyz => abcXyz

  • 表中字段名:abc_xyz

  • 类中属性名:abcXyz

在application.yml中做如下配置,开启开关。

mybatis:configuration:map-underscore-to-camel-case: true

 

删除部门:

  • 方案一:通过原始的 HttpServletRequest 对象获取请求参数

  • 方案二:通过Spring提供的 @RequestParam 注解,将请求参数绑定给方法形参

  • 方案三:如果请求参数名与形参变量名相同,直接定义方法形参即可接收。(省略@RequestParam)

新增部门:

/*** 根据ID查询 - GET http://localhost:8080/depts/1*/
@GetMapping("/depts/{id}")
public Result getById(@PathVariable Integer id){System.out.println("根据ID查询, id=" + id);Dept dept = deptService.getById(id);return Result.success(dept);
}

 @RequestBody 注解 可以将post请求体中 传入的json 数据 自动封装为  Dept对象 

@RequsetParam 可以自动获取 URL风格的传参 (localhost:8080/depts?id=3)例如

@DeleteMapping()public Result delete(@RequestParam("id") Integer id){deptService.delete(id);return Result.Success("删除成功");}

如果使用 restful 风格 传参 需要使用 @PathVariable 修饰参数 

/*** 根据ID查询 - GET http://localhost:8080/depts/1*/
@GetMapping("/depts/{id}")
public Result getById(@PathVariable Integer id){System.out.println("根据ID查询, id=" + id);Dept dept = deptService.getById(id);return Result.success(dept);
}

修改数据:

修改数据时用 PutMapping注解修饰方法 前端服务器 用put方法发送请求json数据 时 会根据键

配对 实体类中的 变量名  运用 @RequsetBody 注解自动封装到 实体类对象中 

日志技术(重要):

日志框架:

准备工作:引入logback的依赖(springboot中无需引入,在springboot中已经传递了此依赖)

<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.11</version>
</dependency>

引入配置文件 logback.xml (资料中已经提供,拷贝进来,放在 src/main/resources 目录下; 或者直接AI生成)

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度  %msg:日志消息,%n是换行符 --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern></encoder></appender><!-- 日志输出级别 --><root level="ALL"><appender-ref ref="STDOUT" /></root>
</configuration>

记录日志:

使用@Slf4j   注解即可使用 会自动创建 Logger 对象

public class LogTest {//定义日志记录对象private static final Logger log = LoggerFactory.getLogger(LogTest.class);@Testpublic void testLog(){log.debug("开始计算...");int sum = 0;int[] nums = {1, 5, 3, 2, 1, 4, 5, 4, 6, 7, 4, 34, 2, 23};for (int i = 0; i < nums.length; i++) {sum += nums[i];}log.info("计算结果为: "+sum);log.debug("结束计算...");}}

Logback配置文件:

1). 如果需要输出日志到控制台。添加如下配置:

<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern></encoder>
</appender>

2). 如果需要输出日志到文件。添加如下配置:

<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 日志文件输出的文件名, %i表示序号 --><FileNamePattern>D:/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern><!-- 最多保留的历史日志文件数量 --><MaxHistory>30</MaxHistory><!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB --><maxFileSize>10MB</maxFileSize></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern></encoder>
</appender>

3). 日志开关配置 (开启日志(ALL),取消日志(OFF))

<!-- 日志输出级别 -->
<root level="ALL"><!--输出到控制台--><appender-ref ref="STDOUT" /><!--输出到文件--><appender-ref ref="FILE" />
</root>

Logback日志级别:

trace 几乎不使用 会用 debug替代

lombok中提供的@Slf4j注解,可以简化定义日志记录器这步操作。添加了该注解,就相当于在类中定义了日志记录器,就下面这句代码:

private static Logger log = LoggerFactory. getLogger(Xxx. class);

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rest-assured multiPart上传中文名称文件,文件名乱码

rest-assured是一个基于java语言的REST API测试框架&#xff0c;在使用rest-assured的multipart 上传文件后&#xff0c;后端获取的文件名称乱码。截图如下&#xff1a; 原因是rest-assured multipart/form-data默认的编码格式是US-ASCII&#xff0c;需要设置为UTF-8。 Befo…

【Git操作】-- 将已存在的项目复制一份到另一个分组空间下

目录 1、需求描述 2、操作步骤 2.1 配置 2.2、git 上创建新项目 2.3 添加到旧的项目中 2.3、将新项目添加到待复制的项目上 3、Push an existing Git repository 4、浏览器打开新项目 nn_bigdata 5、其他&#xff1a;如果项目已经拉取到本地&#xff0c;那么可以使用以…

搭建环境-PHP简介及环境搭建教程

搭建环境-PHP简介及环境搭建教程 前言 在现代Web开发中,PHP是一种广泛使用的服务器端脚本语言,它以简洁、高效和跨平台的特性受到开发者的青睐。无论是小型网站还是大型企业应用,PHP都能提供强大的支持。本文将为您详细介绍PHP的基本概念、特点,以及如何搭建PHP开发环境。…

Python中通过点运算符来访问命名空间中参数args方法

Python中通过点运算符来访问命名空间中参数args方法 在Python中&#xff0c;在使用args进行参数传入时&#xff0c;通常是调用argparse模块的ArgumentParser来创建对象。这种设计虽然使得访问命令行参数更加方便&#xff0c;可以通过点运算符来访问命名空间中的参数。但是当封装…

Unity类银河战士恶魔城学习总结(P156 Audio Settings音频设置)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了音频的大小设置与保存加载 音频管理器 UI_VolumeSlider.cs 定义了 UI_VolumeSlider 类&#xff0c;用于处理与音频设置相关的…

基于单片机的WIFI、语音、储存、时钟、闹钟、定位系统

所有仿真详情导航&#xff1a; PROTEUS专栏说明-CSDN博客 目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DS1302时钟模块&#xff0c;通过LCD1602显示实时时间&#xff0c;也可以储存时间在AT2DC02中&#xff0c…

贪心算法专题(四)

目录 1. 单调递增的数字 1.1 算法原理 1.2 算法代码 2. 坏了的计算器 2.1 算法原理 2.2 算法代码 3. 合并区间 3.1 算法原理 3.2 算法代码 4. 无重叠区间 4.1 算法原理 4.2 算法代码 5. 用最少数量的箭引爆气球 5.1 算法原理 ​5.2 算法代码 1. 单调递增的数字…

Creating Server TCP listening socket *:6379: bind: No error

启动redis报错&#xff1a;Creating Server TCP listening socket *:6379: bind: No error 解决方案&#xff1a; 1、直接在命令行中输入 redis-cli.exe 2、输入shutdown&#xff0c;关闭 3、输exit&#xff0c;退出 4、重新输入 redis-server.exe redis.windows.conf&…

【HM-React】02. React基础-下

React表单控制 受控绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 function App(){const [value, setValue] useState()return (<input type"text" value{value} onChange{e > setValue(e.target.value)}/>) …

基于python的汽车数据爬取数据分析与可视化

一、研究背景 基于提供的代码片段和讨论&#xff0c;我们可以得出一个与网络抓取、数据处理和数据可视化相关的研究背景&#xff0c;该背景涉及到汽车行业。以下是研究背景的陈述&#xff1a; "在迅速发展的汽车行业中&#xff0c;准确和及时的数据对各方利益相关者至关…

BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测,含优化前后对比

BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测&#xff0c;含优化前后对比 目录 BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测&#xff0c;含优化前后对比预测效果基本介绍模型描述程序设计…

使用 Monaco Editor 实现 ECharts 变量使用功能

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【深度学习】四大图像分类网络之AlexNet

AlexNet是由Alex Krizhevsky、Ilya Sutskever&#xff08;均为Hinton的学生&#xff09;和Geoffrey Hinton&#xff08;被誉为”人工智能教父“&#xff0c;首先将反向传播用于多层神经网络&#xff09;在2012年ImageNet图像分类竞赛中提出的一种经典的卷积神经网络。AlexNet在…

网络安全(三):网路安全协议

网络安全协议设计的要求是实现协议过程中的认证性、机密性与不可否认性。网络安全协议涉及网络层、传输层与应用层。 1、网络层安全与IPSec协议、IPSec VPN 1.1、IPSec安全体系结构 IP协议本质上是不安全的额&#xff0c;伪造一个IP分组、篡改IP分组的内容、窥探传输中的IP分…

AWS账号提额

Lightsail提额 控制台右上角&#xff0c;用户名点开&#xff0c;选择Service Quotas 在导航栏中AWS服务中找到lightsail点进去 在搜索框搜索instance找到相应的实例类型申请配额 4.根据自己的需求选择要提额的地区 5.根据需求来提升配额数量,提升小额配额等大约1小时生效 Ligh…

LCD与lvgl

LCD与lvgl 目录 LCD与lvgl 回顾 LCD 的驱动层讲解 1、LCD 的常见接口 2、我们的 LCD 的参数 3、LCD 的设备树说明 4、LCD 的设备树说明 5、如何移植 LCD 的驱动(重点) LCD 的应用层开发 1&#xff1a;LCD 应用开发->界面开发的方法 2&#xff1a;LVGL 模拟器安装…

Linux -初识 与基础指令2

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【Linux】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 文章目录 &#x1f4da; 前言&#x1f511; 概念一&#x1f511; 概念二 &#x1f4d6; man&#x1f4ac; echo&#x1f4c1; cp&#x1f4c2; mv&#x1f511; 概念三&am…

HCIE IGP双栈综合实验

实验拓扑 实验需求及解法 本实验模拟ISP网络结构&#xff0c;R1/2组成国家骨干网&#xff0c;R3/4组成省级网络&#xff0c;R5/6/7组成数据中 心网络。 配置所有ipv4地址&#xff0c;请自行测试直连。 R1 sysname R1 interface GigabitEthernet0/0/0ip address 12.1.1.1 255.…

大模型微调论文阅读 LoRA:LOW-RANK ADAPTION OF LARGE LANGUAGE MODELS 大型语言模型的低秩自适应

论文link&#xff1a;https://arxiv.org/pdf/2106.09685 code&#xff1a;https://github.com/microsoft/LoRA LoRA&#xff1a;Low-Rank Adaptation of Large Language Models Abstract 自然语言处理的一个重要范例是对通用领域数据进行大规模预训练&#xff0c;并适应特定任…

Ubuntu24.04配置DINO-Tracker

一、引言 记录 Ubuntu 配置的第一个代码过程 二、更改conda虚拟环境的默认安装路径 鉴于不久前由于磁盘空间不足引发的重装系统的惨痛经历&#xff0c;在新系统装好后当然要先更改虚拟环境的默认安装路径。 输入指令&#xff1a; conda info可能因为我原本就没有把 Anacod…