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

web项目工程搭建、Result封装类、部门功能的增删改查和日志技术Logback

工程搭建

第一步

1.检查maven版本和JDK版本(这里我们采用17)和字符集版本(UTF-8)

检查maven
JDK版本

检查字符集

2.创建SpringBoot工程

3.引入web开发起步依赖

lombok驱动(Spring Boot版本自行选择)

spring web

sql驱动(mysql和mybatis)

第二步

1.配置yml文件

#Spring Boot项目名字 spring: application: name:项目名字#配置数据库 datasource: #配置数据库连接池类型(德鲁伊或追光者) type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/连接的数据库名字driver-class-name: com.mysql.cj.jdbc.Driver username:数据库用户名password:数据库密码#配置MyBatis mybatis: #配置映射文件 mapper-locations: classpath:mapper/*.xml #配置实体类包名 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2.创建数据库

-- 创建部门表 dept CREATE TABLE dept ( id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID,主键', name varchar(10) NOT NULL UNIQUE COMMENT '部门名称', create_time datetime DEFAULT NULL COMMENT '创建时间', update_time datetime DEFAULT NULL COMMENT '修改时间' ) COMMENT '部门表'; -- 插入部门数据 INSERT INTO dept VALUES (1, '学工部', '2024-09-25 09:47:40', '2024-09-25 09:47:40'), (2, '教研部', '2024-09-25 09:47:40', '2024-09-09 15:17:04'), (3, '咨询部', '2024-09-25 09:47:40', '2024-09-30 21:26:24'), (4, '就业部', '2024-09-25 09:47:40', '2024-09-25 09:47:40'), (5, '人事部', '2024-09-25 09:47:40', '2024-09-25 09:47:40'), (6, '行政部', '2024-11-30 20:56:37', '2024-09-30 20:56:37');

第三步

准备基础代码,建立三层架构以及实体类包pojo

0.注解注意事项
  1. Controller 层:本身就是控制器类,直接在类上使用@RestController/@Controller,无需接口。
  2. Service 层
    • 接口只定义方法规范,不能加@Service
    • 实现类上必须加@Service,Spring 才会扫描并实例化这个实现类,交给容器管理。
  3. Mapper 层(DAO)
    • 接口上直接加@Mapper(或启动类@MapperScan)即可。
    • 由 MyBatis 的动态代理机制自动生成接口的代理实现类,所以我们不用手动写实现类,也不用在别的地方加注解。
1.创建实体类Dept和Result

2.创建Mapper层接口

3.创建Service层的接口以及其实现类(一般实现类要放在Impl包下面)

特别提醒,所有三层架构的注解都必须加载其实现类的头上,但由于Mapper利用了动态代理来创建一个虚拟的实现类,并且Controller本身就是只有类,所以不需要特别强调,Service多多留意!

4.创建Controller层的

Result封装类(将返回给前端的结果封装为一个Result类)

package com.itheima.pojo; import lombok.Data; @Data public class Result { private Integer code; //编码:1成功,0和其它数字为失败 private String msg; //错误信息 private Object data; //数据 public static Result success() { Result result = new Result(); result.code = 1; return result; }#方法重载---成功返回封装的对象public static Result success(Object object) { Result result = new Result();result.data = object;---返回的对象数据result.code = 1;---默认返回1为成功return result; } public static Result error(String msg) { Result result = new Result(); result.msg = msg;result.code = 0;---默认返回0为失败return result; } }

部门功能

1.查询部门

(1)需求分析

根据接口文档分析需求,这点是非常重要的

一般就是分析基本的信息,请求的参数,响应的数据

[1]分析基本信息

[2]分析请求参数

因为是查询所有,并没有特殊查询所以不需要带参数

[3]分析我们需要给前端响应回去的数据

(2)分析三层架构的职责

Mapper层的sql语句我们可以现在数据库中编写并且测试

比如我们这个部门的要求用如下sql语句即可

-- 查询全部部门 select id, name, create_time, update_time from dept order by update_time desc;

之后Mapper层获取数据,我们的Service通过调用Mapper的接口方法拿回数据

我们的Controller层调用Service层的方法拿到数据最后返回给前端

(3)编写三层架构

[1]编写Controller层
@RestController public class DeptController { @Autowired private DeptService deptService;--这里调用的Service层的方法不要忘记DI依赖注入和IOC控制反转@RequestMapping(value="/depts",method = RequestMethod.GET)--这里的请求访问路径参考接口文档RequestMapping中限定访问类型为Get,RequestMethod是一个枚举类型!同样的你可以直接将@RequestMapping替换为@GetMappingpublic Result list(){--这个方法返回的是Result数据,也就是响应给前端的数据System.out.println("查询全部部门数据"); List<Dept> deptList= deptService.findAll();--调用Service层方法,这个findAll()返回的是所有的部门数据,所以我们封装在List集合中。return Result.success(deptList);--返回结果,其实就是我们的Result封装类的方法,成功返回并且封装数据} }
[2]编写Service层

这里唯一需要注意的就是@Service要加在实现类而非接口上,因为控制反转是将类实例化的权限放在了容器里,而接口是无法实例化的

[3]编写Mapper层

这里编写sql语句可以配置在xml文件也可以选择注解配置

记得链接数据库配置SQL提示(如果用xml可以不管这个)

(4)封装数据

三种解决方案

方案一

因为我们是要封装从数据库拿出来的数据,所以只需要操作Mapper层即可

方案二

起别名和实体类属性名一样即可

方案三!最常用

配置文件即可,驼峰命名规则映射

即数据库字段create_time自动转为createTime

(5)前后端联调测试

我们基于nginx服务器作为代理(中转)服务器,基于nginx服务器的反向代理进行传递

解析我们nginx中的配置文件

2.删除部门(根据部门id删除)

请求参数样例

/depts?id=1
/depts?id=2

delete from dept where id=#{id}

不难看出我们需要接受一个参数,这个参数其实就是id,那我们Controller是和前端对接,自然是要负责接收参数的,这边讲解如何接收参数

Controlloer接收参数

方式一通过HttpServletRequest对象获取请求参数(Http协议中有说明这个对象)
@DeleteMapping("/depts") public Result delete(HttpServletRequestrequest){ String idStr = request.getParameter("id"); int id = Integer.parseInt(idStr); System.out.println("根据ID删除部门: " + id); return Result.success(); }
方式二通过Spring提供的注解@RequestParam
@DeleteMapping("/depts") public Result delete(@RequestParam("id")Integer deptId){ System.out.println("根据ID删除数据"+deptId); return Result.success(); }

注意:一旦使用@RequestParam这个注解,那么参数就必须传递否则报错

因为required默认为true,不传递参数会报错

如果你想避免这个,则只需要把required改为false即可

@DeleteMapping("/depts") public Result delete(@RequestParam(value = "id",required = false) Integer deptId){ System.out.println("根据ID删除数据"+deptId); return Result.success(); }
方法三 请求参数名与形参名相同,则可省略@RequestParam注解

当你知道如何接收参数之后,余下的调用方法都是和查询部门一样了

3.新增部门

即插入数据,请求类型为post,

请求参数样例--不难看出是个json格式

{
"name": "教研部"
}

json参数接收

我们看到,在controller中,需要接收前端传递的请求参数。 那接下来,我们就先来看看在服务器端的Controller程序中,如何获取json格式的参数。

  • JSON格式的参数,通常会使用一个实体对象进行接收 。

  • 规则:JSON数据的键名与方法形参对象的属性名相同,并需要使用@RequestBody注解标识。

在我们的Service层中可以进行业务逻辑的数据,在这里我们要新增两个字段,一个是createTime一个是updateTime

4.修改部门-查询回显,修改数据

1.查询回显

也就是当你需要修改一个部门的数据的时候需要先点击编辑/修改,这一步其实就是获取这个部门的信息,所以其实也就是根据id进行查询,也就是查询回显

如果形参和路径参数名字一样,注解可省略写入路径参数名字

Controller层@GetMapping("/depts/{id}")---->{id}是路径参数的占位符 public Result findById(@PathVariable("id")Integer id){ System.out.println("查询部门数据"+id);Dept dept = deptService.getInfo(id);--这里我们只需返回一个对象就行而非集合return Result.success(dept); }

Service层

@Override public Dept getInfo(Integer id) { return deptMapper.getInfo(id); }

Mapper层

@Select("select id, name, create_time, update_time from dept where id=#{id}") Dept getInfo(Integer id);

这个请求路径其实是我们RESTful规范中的,类型为GET,请求为/depts/1(2,3....)

三个注解的本质区别
注解数据来源URL示例典型场景
@PathVariableURL路径中/depts/1RESTful风格,获取资源ID
@RequestParamURL?后面/depts?name=技术查询参数、分页、筛选
@Param不是给URL用的不直接对应URLMyBatis的SQL参数命名

简单来说@PathVariable是获取路径参数的信息,在这个GET请求中,语义为获取id(主键)=?的数据的信息

但是@RequestParam是获取?后面的信息,它是一种查询参数,更多的是用来筛选和分页

2.修改数据

Controller层

@PutMapping("/depts") public Result update(@RequestBody Dept dept){ System.out.println("修改部门数据"+dept); deptService.put(dept); return Result.success(); }

Service层

@Override public void put(Dept dept) { System.out.println("修改部门数据");//更新的时候并不需要修改createTimedept.setUpdateTime(LocalDateTime.now()); deptMapper.put(dept); System.out.println("修改部门数据成功"); }

@Mapper层

@Update("update dept set name=#{name},update_time=#{updateTime} where id=#{id}") void put(Dept dept);

另外的我们可以将公共的请求路径提取出来放在类上面!

日志技术Logback

Logback是非常优秀的日志技术,也是我们需要去学习和掌握的

Slf4j则类似于一种规范,提供了一套标准接口和抽象类,也就是让我们的Logback去实现

Logback快速入门

Spring中有依赖传递的特性,所以这个依赖我们就无需引入了

logback.xml配置

放在src/main/resources目录下即可,自建一个logback.xml,配置如下

<?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个字符宽度,%logger{50}输出打印日志所在类的全类路径最多不超过50个字符宽度,%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>

定义日志记录对象

private static final Logger log=LoggerFactory.getLogger(LogTest.class);创建日志对象
@Test public void testLog(){ log.debug("开始计算..."); int sum = 0; try { 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]; } } catch (Exception e) { log.error("程序运行出错", e); } log.info("计算结果为: "+sum); log.debug("结束计算..."); }

Logback配置文件(logback.xml)

如果要控制日志输入到文件中

<!-- 按照每天生成日志文件 --> <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个字符宽度,%logger{50}输出打印日志所在类的全类路径最多不超过50个字符宽度,%msg表示日志消息,%n表示换行符 --> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern> </encoder> </appender>

level后面说明了日志的输出级别,即决定了输出哪些日志

后面的名称引用即决定了将日志输出到什么地方,比如这里就是控制台和文件

日志输出内容

控制台版本

其中%msg即日志信息,即你调用debug或info这些方法的时候传递进来的信息

文件版本

其实和控制台版本差不多只不过是输出在文件里

重点是日志存放路径,并且可以指定日志文件的名字格式

Logback日志级别

按照级别从低到高如下!

项目里最常用

  • 开发环境用 debug

  • 生产环境用 info

如果你的输出等级设置为info,那么debug和trace就不会输出

如果你的输出等级设置为debug,那么trace就不会输出

Logback优化项目

引入lombok这个依赖之后我们可以在类上方加注解@Slf4j,这就等于是创建了一个日志对象

省略这个代码

private static final Logger log=LoggerFactory.getLogger(LogTest.class);创建日志对象

另外log提供了占位符方便我们使用,就不需要字符串拼接了

http://www.jsqmd.com/news/794341/

相关文章:

  • ImageGlass深度解析:打造Windows平台高效图像浏览的实战指南
  • DISTINCT 带 WHERE 仍全表扫描?两层优化刀法拆解
  • 鸿蒙与 H5 通信使用的方法及原理
  • 如何彻底解决显卡驱动残留问题?Display Driver Uninstaller深度解析指南
  • 英伟达400亿投资帝国:从卖芯片到控生态,黄仁勋的AI全链路野心
  • PCI、PCIe与InfiniBand接口技术对比与应用解析
  • 百度网盘直链解析技术深度解析:突破限速壁垒的工程实践
  • 【测试方案_100 BASE-T1】快速掌握100BASE-T1 PMA物理层一致性测试
  • MySQL索引失效
  • MCP协议实战:outx-mcp-server如何安全扩展AI工具调用能力
  • 基于 Harmony6.0 的城市空气质量监测页面开发实践:ArkUI 页面构建与跨端能力深度解析
  • PX4 Firmware V1.14.4 开源支持
  • Claude代码自动模式:跳过权限的更安全方式 Claude Code auto mode: a safer way to skip permissions —— Anthropic
  • 量子去极化信道与3槽序列纯化策略解析
  • SecureVault - 基于新范式的Windows文件加密工具
  • 《Java 100 天进阶之路》第2篇:配置Java环境变量
  • 如何在Mac上快速搭建局域网通信系统:飞秋Mac版完整教程
  • HarmonyOS 6.0 跨端页面构建实践:从 UI 代码到热力交互卡片设计
  • 基于AI流水线架构的自动化播客生成:从文本到音频的工程实践
  • DAY 4.链表中环的入口节点
  • Diablo Edit2:暗黑破坏神2存档编辑器的终极使用指南
  • MCP协议实战:构建安全可控的AI智能体外部工具集成平台
  • 《Java 100 天进阶之路》第3篇:为何要配置环境变量?
  • 开源项目封装实战:适配器模式与门面模式提升开发体验
  • 链表专项(二):链表反转、环判断
  • 量子储层计算:光量子与机器学习的融合应用
  • Go语言事件溯源与CQRS实践:基于event-horizon构建可追溯系统
  • AI编程新范式:基于.cursorrules的角色扮演开发环境实战指南
  • GodSVG:基于Godot引擎的结构化SVG编辑器,实现代码与图形双向实时同步
  • 目标检测算法——史上最全遥感数据集汇总附下载链接【速速收藏】