【项目记录】部门增删改及日志技术
1 删除部门
1.1 需求
删除部门数据。在点击 "删除" 按钮,会根据ID删除部门数据。
了解了需求之后,我们再看看接口文档中,关于删除部门的接口的描述,然后根据接口文档进行服务端接口的开发。
1.2 接口描述
1.2.1 基本信息
请求路径:/depts
请求方式:DELETE
接口描述:该接口用于根据ID删除部门数据
1.2.2 请求参数
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
id | number | 必须 | 部门ID |
请求参数样例:
/depts?id=1
/depts?id=2
1.2.3 响应数据
参数格式:application/json
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
code | number | 必须 | 响应码,1 代表成功,0 代表失败 |
msg | string | 非必须 | 提示信息 |
data | object | 非必须 | 返回的数据 |
1.3 思路分析
Controller:接收客户端请求参数(如/depts?id=8),调用 Service 层处理业务,再将结果响应给客户端 。
Service:承接 Controller 调用,调用 Mapper 接口方法,实现业务逻辑 。
Mapper:执行 SQL 语句(delete from dept where id =?),负责与数据库交互,完成数据的增删改查 。
1.4 简单参数接收
我们看到,在controller中,需要接收前端传递的请求参数。 那接下来,我们就先来看看在服务器端的Controller程序中,如何获取这类简单参数。 具体的方案有如下三种:
方案一:通过原始的 HttpServletRequest 对象获取请求参数
/**
* 根据ID删除部门 - 简单参数接收: 方式一 (HttpServletRequest)
*/
@DeleteMapping("/depts")
public Result delete(HttpServletRequest request){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 注解的value属性,需要与前端传递的参数名保持一致 。
注:@RequestParam注解required属性默认为true,代表该参数必须传递,如果不传递将报错。 如果参数可选,可以将属性设置为false。
方案三:如果请求参数名与形参变量名相同,直接定义方法形参即可接收。(省略@RequestParam)
@DeleteMapping("/depts")
public Result delete(Integer id){System.out.println("根据ID删除部门: " + deptId);return Result.success();
}
对于以上的这三种方案,推荐第三种方案。
1.5 代码实现
1) Controller层
在 DeptMapper 中,增加 delete 方法,代码实现如下:
/*** 根据id删除部门 - delete http://localhost:8080/depts?id=1*/
@DeleteMapping("/depts")
public Result delete(Integer id){System.out.println("根据id删除部门, id=" + id);deptService.deleteById(id);return Result.success();
}
2) Service层
在 DeptService 中,增加 deleteById 方法,代码实现如下:
/*** 根据id删除部门*/
void deleteById(Integer id);
在 DeptServiceImpl 中,增加 deleteById 方法,代码实现如下:
public void deleteById(Integer id) {deptMapper.deleteById(id);
}
3) Mapper层
在 DeptMapper 中,增加 deleteById 方法,代码实现如下:
/*** 根据id删除部门*/
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
如果mapper接口方法形参只有一个普通类型的参数,#{…} 里面的属性名可以随便写,如:#{id}、#{value}。
对于 DML 语句来说,执行完毕也是有返回值的,返回值代表的是增删改操作,影响的记录数,所以可以将执行 DML 语句的方法返回值设置为 Integer。 但一般开发时不需要这个返回值,所以也可以设置为void。
代码编写完毕后,就可以启动服务进行测试了。
2 新增部门
2.1 需求
点击 "新增部门" 的按钮之后,弹出新增部门表单,填写部门名称后,点击确定,保存部门数据。
了解了需求后,再看看接口文档中,关于新增部门的接口的描述,然后根据接口文档进行服务端接口的开发 。
2.2 接口描述
2.2.1 基本信息
请求路径:/depts
请求方式:POST
接口描述:该接口用于添加部门数据
2.2.2 请求参数
参数格式:application/json
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
name | string | 必须 | 部门名称 |
2.3 思路分析
Controller:接收客户端
/depts
请求及{"name":"教研部"}
参数,调用 Service 层,再响应结果。Service:补全基础属性,调用 Mapper 接口方法,处理业务逻辑。
Mapper:执行
insert into dept (name,create_time,update_time) values (?,?,?)
SQL 语句,与数据库交互完成数据插入 。
2.4 json参数接收
可以看到,在controller中,需要接收前端传递的请求参数。 那接下来,就先来看看在服务器端的Controller程序中,如何获取json格式的参数。
JSON格式的参数,通常会使用一个实体对象进行接收 。
规则:JSON数据的键名与方法形参对象的属性名相同,并需要使用@RequestBody注解标识。
前端传递的请求参数格式为json,内容如下:{"name":"研发部"}。这里可以通过一个对象来接收,只需要保证对象中有name属性即可。
2.5 代码实现
1) Conteoller层
在DeptController中增加方法save,具体代码如下:
/*** 新增部门 - POST http://localhost:8080/depts 请求参数:{"name":"研发部"}*/
@PostMapping("/depts")
public Result save(@RequestBody Dept dept){System.out.println("新增部门, dept=" + dept);deptService.save(dept);return Result.success();
}
2) Service层
在DeptServiceImpl中增加save方法,完成添加部门操作,具体代码如下:
public void save(Dept dept) {//补全基础属性dept.setCreateTime(LocalDateTime.now());dept.setUpdateTime(LocalDateTime.now());//保存部门deptMapper.insert(dept);
}
3) Mapper层
/*** 保存部门*/
@Insert("insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})")
void insert(Dept dept);
如果在mapper接口中需要传递多个参数,可以把多个参数封装到一个对象中。 在SQL语句中获取参数的时候,#{...} 里面写的是对象的属性名【注意是属性名,不是表的字段名】。
代码编写完毕后,即可启动服务进行测试。
3 修改部门
对于任何业务的修改功能来说,一般都会分为两步进行:查询回显、修改数据。
3.1 查询回显
3.1.1 需求
当点击 "编辑" 时,需要根据ID查询部门数据用于页面回显展示。
3.1.2 接口描述
3.1.2.1 基本信息
请求路径:/depts/{id}
请求方式:GET
接口描述:该接口用于根据ID查询部门数据
3.1.2.2 请求参数
参数格式:路径参数
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
id | number | 必须 | 部门ID |
请求参数样例:
/depts/1
/depts/3
3.1.2.3 响应数据
参数格式:application/json
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
code | number | 必须 | 响应码,1 代表成功,0 代表失败 |
msg | string | 非必须 | 提示信息 |
data | object | 非必须 | 返回的数据 |
|- id | number | 非必须 | id |
|- name | string | 非必须 | 部门名称 |
|- createTime | string | 非必须 | 创建时间 |
|- updateTime | string | 非必须 | 修改时间 |
3.1.3 思路分析
明确了根据ID查询部门的需求后,再梳理一下实现该功能时三层架构每一层的职责:
Controller:接收客户端路径参数/depts/1请求,调用 Service 层,再响应结果。
Service:调用 Mapper 接口方法,衔接 Controller 与 Mapper 。
Mapper:执行select * from dept where id = 1 语句,从数据库查询对应部门数据 。
3.1.4 路径参数接收
/depts/1,/depts/3这种在url中传递的参数,称之为路径参数。 如何接收这样的路径参数呢 ?
路径参数:通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用
@PathVariable
获取路径参数。如果路径参数名与controller方法形参名称一致,@PathVariable注解的value属性是可以省略的。
3.1.5 代码实现
1) Controller层
在 DeptController 中增加 getById方法,具体代码如下:
/*** 根据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);
}
2) Service层
在 DeptService 中增加 getById方法,具体代码如下:
/*** 根据id查询部门*/
Dept getById(Integer id);
在 DeptServiceImpl 中增加 getById方法,具体代码如下:
public Dept getById(Integer id) {return deptMapper.getById(id);
}
3) Mapper层
在 DeptMapper 中增加 getById 方法,具体代码如下:
/**
* 根据ID查询部门数据
*/
@Select("select id, name, create_time, update_time from dept where id = #{id}")
Dept getById(Integer id);
代码编写完毕后,就可以启动服务进行测试了。
3.2 修改数据
3.2.1 需求
查询回显回来后就可以对部门信息进行修改了,修改完毕后,点击确定,此时就需要根据ID修改部门的数据。
了解需求后,再看接口文档中关于修改部门的接口的描述,进行服务端接口的开发 。
3.2.2 接口描述
3.2.2.1 基本信息
请求路径:/depts
请求方式:PUT
接口描述:该接口用于修改部门数据
3.2.2.2 请求参数
参数格式:application/json
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
---|---|---|---|
id | number | 必须 | 部门ID |
name | string | 必须 | 部门名称 |
3.2.3 思路分析
参照接口文档,梳理三层架构每一层的职责:
Controller :接收来自客户端的 JSON 格式请求参数{"id":1,"name":"教研部"},然后调用 Service 层的方法进行业务处理,最后将处理结果响应给客户端。
Service :承接 Controller 层的调用,首先补全基础属性,之后调用 Mapper 接口方法 。
Mapper :执行 update dept set name =?, update_time =? where id =? 语句,与数据库交互,完成部门信息的更新操作。
通过接口文档,可以看到前端传递的请求参数是json格式的请求参数,在Controller的方法中,可以通过@RequestBody 注解来接收,并将其封装到一个对象中。
3.2.4 代码实现
1) Controller层
在 DeptController 中增加 update 方法,具体代码如下:
/*** 修改部门 - PUT http://localhost:8080/depts 请求参数:{"id":1,"name":"研发部"}*/
@PutMapping("/depts")
public Result update(@RequestBody Dept dept){System.out.println("修改部门, dept=" + dept);deptService.update(dept);return Result.success();
}
2) Service层
在 DeptService 中增加 update 方法。
/*** 修改部门*/
void update(Dept dept);
在 DeptServiceImpl 中增加 update 方法。 由于是修改操作,每一次修改数据,都需要更新updateTime。所以,具体代码如下:
public void update(Dept dept) {//补全基础属性dept.setUpdateTime(LocalDateTime.now());//保存部门deptMapper.update(dept);
}
3) Mapper层
在 DeptMapper 中增加 update 方法,具体代码如下:
/*** 更新部门*/
@Update("update dept set name = #{name},update_time = #{updateTime} where id = #{id}")
void update(Dept dept);
代码编写完毕之后,我们就可以启动服务,进行测试了。
3.2.5 @RequestMapping
到此,关于基本的部门的增删改查功能已经实现了。 会发现,在 DeptController 中所定义的方法,所有的请求路径,都是 /depts 开头的,只要操作的是部门数据,请求路径都是 /depts 开头。
此时可以把这个公共的路径 /depts 抽取到类上的,在各个方法上就可以省略了这个 /depts 路径。 代码如下:
package org.example.controller;import jakarta.servlet.http.HttpServletRequest;
import org.example.pojo.Dept;
import org.example.pojo.Result;
import org.example.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RequestMapping("/depts")
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;/*** 查询部门列表* @return*///@RequestMapping(value = "/depts",method = RequestMethod.GET) //method:指定请求方式@GetMappingpublic Result list() {System.out.println("查询全部部门数据");List<Dept> deptList = deptService.findAll();return Result.success(deptList);}/*** 删除部门*///方式一:基于HttpServletRequest对象获取参数/*@DeleteMappingpublic Result delete(HttpServletRequest request){String idStr = request.getParameter("id");int id = Integer.parseInt(idStr);System.out.println("删除部门:"+id);return Result.success();}*///方式二:通过 @RequestParam 注解将请求参数绑定给方法形参/*@DeleteMappingpublic Result delete(@RequestParam (value = "id",required = false) Integer deptId ){System.out.println("删除部门:"+ deptId);return Result.success();}*///方式三:如果请求参数名与形参变量名相同,直接定义方法形参即可接收。(省略@RequestParam)@DeleteMappingpublic Result delete(Integer id ){System.out.println("删除部门:"+ id);deptService.deleteById(id);return Result.success();}/*** 新增部门*/@PostMappingpublic Result add(@RequestBody Dept dept){System.out.println("新增部门:" + dept);deptService.add(dept);return Result.success();}/*** 根据ID查询部门*//*@GetMapping("/{id}")public Result getInfo(@PathVariable("id") Integer deptId){System.out.println("根据id查询部门:" + deptId);return Result.success();}*/@GetMapping("/{id}")public Result getInfo(@PathVariable Integer id){System.out.println("根据id查询部门:" + id);Dept dept = deptService.getById(id);return Result.success(dept);}/*** 修改部门信息*/@PutMappingpublic Result update(@RequestBody Dept dept){System.out.println("修改部门:" + dept);deptService.update(dept);return Result.success();}}
4 日志技术
4.1 概述
什么是日志?
日志就好比生活中的日记,可以随时随地记录你生活中的点点滴滴。
程序中的日志,是用来记录应用程序的运行信息、状态信息、错误信息的。
为什么要在程序中记录日志呢?
便于追踪应用程序中的数据信息、程序的执行过程。
便于对应用程序的性能进行优化。
便于应用程序出现问题之后,排查问题,解决问题。
便于监控系统的运行状态。
... ...
之前编写程序时,也可以通过System.out.println(...) 来输出日志,为什么还要学习日志技术呢?
这是因为,如果通过System.out.println(...)记录日志,会存在以下几点问题:
硬编码。所有的记录日志的代码,都是硬编码,没有办法做到灵活控制,要想不输出这个日志了,只能删除掉记录日志的代码。
只能输出日志到控制台。
不便于程序的扩展、维护。
所以,在现在的项目开发中,一般都会使用专业的日志框架来解决这些问题。
4.2 日志框架
JUL:这是JavaSE平台提供的官方日志框架,也被称为JUL。配置相对简单,但不够灵活,性能较差。
Log4j:一个流行的日志框架,提供了灵活的配置选项,支持多种输出目标。
Logback:基于Log4j升级而来,提供了更多的功能和配置选项,性能由于Log4j。
Slf4j:(Simple Logging Facade for Java)简单日志门面,提供了一套日志操作的标准接口及抽象类,允许应用程序使用不同的底层日志框架。
4.3 Logback入门
1) 准备工作:引入logback依赖(springboot中无需引入,在springboot中已经传递了此依赖)
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.11</version>
</dependency>
2) 引入配置文件 logback.xml ,放在 src/main/resources 目录下
<?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显示日志记录器的名称, %msg表示日志消息,%n表示换行符 --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern></encoder></appender><!-- 系统文件输出 --><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><!-- 日志输出级别 --><root level="info"><appender-ref ref="STDOUT" /><appender-ref ref="FILE" /></root>
</configuration>
3) 记录日志:定义日志记录对象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("结束计算...");}}
运行单元测试,可以在控制台中看到输出的日志,如下所示:
可以看到在输出的日志信息中,不仅输出了日志的信息,还包括:日志的输出时间、线程名、具体在哪个类输出。
4.4 Logback配置文件
Logback日志框架的配置文件叫 logback.xml 。 该配置文件是对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>
4.5 Logback日志级别
日志级别指的是日志信息的类型,日志都会分级别,常见的日志级别如下(优先级由低到高):
日志级别 | 说明 | 记录方式 |
---|---|---|
trace | 追踪,记录程序运行轨迹 【使用很少】 | log.trace("...") |
debug | 调试,记录程序调试过程中的信息,实际应用中一般将其视为最低级别 【使用较多】 | log.debug("...") |
info | 记录一般信息,描述程序运行的关键事件,如:网络连接、io操作 【使用较多】 | log.info("...") |
warn | 警告信息,记录潜在有害的情况 【使用较多】 | log.warn("...") |
error | 错误信息 【使用较多】 | log.error("...") |
可以在配置文件logback.xml中,灵活的控制输出那些类型的日志。(大于等于配置的日志级别的日志才会输出)
4.6 案例日志记录
package org.example.controller;import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.example.pojo.Dept;
import org.example.pojo.Result;
import org.example.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@Slf4j
@RequestMapping("/depts")
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;/*** 查询部门列表* @return*///@RequestMapping(value = "/depts",method = RequestMethod.GET) //method:指定请求方式@GetMappingpublic Result list() {//System.out.println("查询全部部门数据");log.info("查询全部部门数据");List<Dept> deptList = deptService.findAll();return Result.success(deptList);}/*** 删除部门*///方式一:基于HttpServletRequest对象获取参数/*@DeleteMappingpublic Result delete(HttpServletRequest request){String idStr = request.getParameter("id");int id = Integer.parseInt(idStr);System.out.println("删除部门:"+id);return Result.success();}*///方式二:通过 @RequestParam 注解将请求参数绑定给方法形参/*@DeleteMappingpublic Result delete(@RequestParam (value = "id",required = false) Integer deptId ){System.out.println("删除部门:"+ deptId);return Result.success();}*///方式三:如果请求参数名与形参变量名相同,直接定义方法形参即可接收。(省略@RequestParam)@DeleteMappingpublic Result delete(Integer id ){//System.out.println("删除部门:"+ id);log.info("删除部门:{}", id);deptService.deleteById(id);return Result.success();}/*** 新增部门*/@PostMappingpublic Result add(@RequestBody Dept dept){//System.out.println("新增部门:" + dept);log.info("新增部门:{}", dept);deptService.add(dept);return Result.success();}/*** 根据ID查询部门*//*@GetMapping("/{id}")public Result getInfo(@PathVariable("id") Integer deptId){System.out.println("根据id查询部门:" + deptId);return Result.success();}*/@GetMapping("/{id}")public Result getInfo(@PathVariable Integer id){//System.out.println("根据id查询部门:" + id);log.info("根据id查询部门:{}", id);Dept dept = deptService.getById(id);return Result.success(dept);}/*** 修改部门信息*/@PutMappingpublic Result update(@RequestBody Dept dept){//System.out.println("修改部门:" + dept);log.info("修改部门:{}", dept);deptService.update(dept);return Result.success();}}
注:lombok中提供的@Slf4j注解,可以简化定义日志记录器这步操作。添加了该注解,就相当于在类中定义了日志记录器,即如下代码:
private static Logger log = LoggerFactory. getLogger(Xxx. class);
相关文章:

【项目记录】部门增删改及日志技术
1 删除部门 1.1 需求 删除部门数据。在点击 "删除" 按钮,会根据ID删除部门数据。 了解了需求之后,我们再看看接口文档中,关于删除部门的接口的描述,然后根据接口文档进行服务端接口的开发。 1.2 接口描述 1.2.1 基…...

TDengine 更多安全策略
简介 上一节我们介绍了 TDengine 安全部署配置建议,除了传统的这些配置外,TDengine 还有其他的安全策略,例如 IP 白名单、审计日志、数据加密等,这些都是 TDengine Enterprise 特有功能,其中白名单功能在 3.2.0.0 版本…...

电子制造企业智能制造升级:MES系统应用深度解析
在全球电子信息产业深度变革的2025年,我国电子信息制造业正经历着增长与转型的双重考验。据权威数据显示,2025年一季度行业增加值同比增长11.5%,但智能手机等消费电子产量同比下降1.1%,市场竞争白热化趋势显著。叠加关税政策调整、…...

Java使用Collections集合工具类
1、Collections 集合工具类 Java 中的 Collections 是一个非常有用的工具类,它提供了许多静态方法来操作或返回集合。这个类位于 java.util 包中,主要包含对集合进行操作的方法,比如排序、搜索、线程安全化等。 Java集合工具类的使用&#x…...
磁盘空间不足,迁移Docker 数据目录
停止 Docker 服务。 sudo systemctl stop docker 将现有的 Docker 数据移动到新位置(例如 /home/docker-data)。 sudo mv /var/lib/docker /home/docker-data 在原位置创建一个指向新位置的符号链接。 sudo ln -s /home/docker-data /var/lib/dock…...

python打卡day33
知识点回顾: PyTorch和cuda的安装查看显卡信息的命令行命令(cmd中使用)cuda的检查简单神经网络的流程 数据预处理(归一化、转换成张量)模型的定义 继承nn.Module类定义每一个层定义前向传播流程 定义损失函数和优化器定…...
目标检测新突破:用MSBlock打造更强YOLOv8
文章目录 YOLOv8的现状与挑战YOLO-MS的MSBlock简介MSBlock的工作原理MSBlock的优势利用MSBlock改进YOLOv8替换YOLOv8主干网络中的部分模块代码实现:替换CSP模块为MSBlock在YOLOv8的颈部(Neck)中插入MSBlock代码实现:在颈部区域插入MSBlock实验结果与分析实验设置性能对比性…...

同城上门预约服务系统案例分享,上门服务到家系统都有什么功能?这个功能,很重要!
你以为上门按摩这类平台只要做好接单派单就万事大吉了?大错特错!市面上90%的系统只会吹嘘基础功能,却对最关键的财税问题避而不谈。很多创业者直到被税务稽查才发现,自己每年都在白白多交几倍的冤枉税!举个例子&#x…...
docker面试题(5)
Docker安全么 Docker 利用了 Linux 内核中很多安全特性来保证不同容器之间的隔离,并且通过签名机制来对镜像进行 验证。大量生产环境的部署证明,Docker 虽然隔离性无法与虚拟机相比,但仍然具有极高的安全性。 如何清理后台停止的容器 可以使用…...
为什么需要在循环里fetch?
假设有多个设备连接在后端,数量不定,需要按个读回状态,那么就要在循环里fetch了. 此函数非常好用,来自于国内一个作者,时间久了,忘记了来源,抱歉. export default async function fetchWithTimeout(resource, options {}) {const { timeout 1000 } options;const controll…...

用 UniApp 开发 TilePuzzle:一个由 CodeBuddy 主动驱动的拼图小游戏
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 起心动念:从一个小游戏想法开始 最近在使用 UniApp 做练手项目的时候,我萌生了一个小小…...

HJ101 输入整型数组和排序标识【牛客网】
文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 HJ101 输入整型数组和排序标识 一、题目描述 二、测试用例 三、解题思路 基本思路: 选择一个排序算法,然后根据标识确定升序还是降序;具体思路&a…...

在Linux debian12系统上使用go语言以及excelize库处理excel数据
go-do-excel 一、介绍 myBook.xlsx表中,B列是“全部IP地址“,A列是“分发成功的IP地址“,本脚本采用go语言编写,通过读取myBook.xlsx中B列“全部IP地址“和A列“分发成功的IP地址“数据,计算出“分发失败的IP地址“数据,将其写入到C列。 二、编程语言 本脚本在Linux De…...
Appium 的 enableMultiWindows 参数
引言 在移动应用自动化测试中,混合应用(Hybrid App) 和多窗口场景(如分屏、弹窗、多 WebView)的处理一直是技术难点。Appium 的 enableMultiWindows 参数为这类场景提供了关键支持,但在实际使用中常…...

【Python/Tkinter】实现程序菜单
程序源码: import tkinter as tk from tkinter.colorchooser import askcolordef set_colour():saskcolor(color"red",title"选择背景色")root.config(bgs[1])class Application(tk.Frame):def __init__(self,masterNone):super().__init__(ma…...

“轩辕杯“云盾砺剑 CTF挑战赛web方向题解
目录 ezjs 签到 ezssrf1.0 ezflask ezrce ezsql1.0 ezweb ezjs 看到这个,直接访问getflag.php,POS提交score 100000000000 签到 6个小模块,我直接放bp的结果 1 2 3 4 5 6 ezssrf1.0 ?urlhttp:127.0.1/FFFFF11111AAAAAggggg.php也可…...

常用UI自动化测试框架
🔍 常用UI自动化测试框架全览(Web / 移动 / 桌面 / AI驱动) UI(用户界面)测试框架是一类用于自动化测试应用图形界面的工具,帮助开发者和测试人员验证界面元素的功能性、交互性和视觉一致性。本文系统梳理了…...
场景化应用实战系列六:检索问答系统
目录 景化应用实战系列六:检索问答系统 一、目标设定 二、关键知识点梳理 三、案例讲解与实战操作 1. 数据准备与预处理 2. 倒排表构建 3. 文本相似度计算 4. 检索问答系统实现 5. 系统优化与改进 一、目标设定 构建一个高效的检索问答系统,能…...
选择合适的AI模型:解析Trae编辑器中的多款模型及其应用场景
在当今数字化时代,人工智能技术飞速发展,各种AI模型层出不穷,为人们的工作和生活带来了极大的便利。Trae编辑器作为一款集成了多种先进AI模型的工具,为用户提供了丰富的选择,以满足不同场景下的多样化需求。本文将深入…...

已经 上线 Vue 项目 国际化 i18n 中译英
省流说明:本文不是把项目中译英,只是抽取js、vue文件里的中文到JSON文件中,en.json里的value还是需要自己翻译成英文 ### 安装 `npm install vve-i18n-cli -D` ### package.json 里添加脚本命令,简化命令使用 ```json { "scripts": { "i18n": …...

RISC-V 开发板 MUSE Pi Pro Gstreamer 编码UVC及MIPI CSI摄像头视频流
视频讲解: RISC-V 开发板 MUSE Pi Pro Gstreamer 编码UVC及MIPI CSI摄像头视频流 Gstreamer 在视频编码、解码、保存等场景下非常常用,其基于插件化的架构,可以玩的很花,进迭时空的Spacemit GStreamer 支持 spacemitdec 专有插件&…...
Android 直播播放器FFmpeg静态库编译实战指南(NDK r21b)
一、环境准备与验证 1.1 必要组件安装 # Ubuntu环境依赖 sudo apt update sudo apt install -y git make automake autoconf libtool pkg-config curl unzip# NDK r21b下载 mkdir -p ~/android && cd ~/android wget https://dl.google.com/android/repository/andro…...

【RA-Eco-RA2L1-48PIN】ADC 电压表
【RA-Eco-RA2L1-48PIN】ADC 电压表 本文介绍了 RA-Eco-RA2L1-48PIN 开发板通过瑞萨 e2 Studio 灵活软件包(FSP)编程实现 ADC 串口采集电压的项目设计,包括 串口通信、打印字符串、UART 和 ADC 配置、关键代码、ADC 电压转换、电压值串口打印…...
Oracle 数据文件被删除后使用rman备份恢复过程
有个环境,因空间使用率100%,现场直接误删了数据文件,log记录恢复过程下 SQL > select file#,name,checkpoint_change# from v$datafile; FILE# NAME CHECKPOINT_CHANGE# ------…...

KS107BG型超声体模的结构及性能
KS107BG型超声体模适用于工作频率在5~10MHz之间的B超设备的性能检测。 一、外部结构 体模外壳和底座由有机玻璃加工组装而成,底面板上开有两个直径36mm的圆孔,其上封有2mm厚的真空橡皮,作为抽气及注射保养液的入口。体模外壳外表…...
visual studio重新安装如何修改共享组件、工具和SDK路径方案
安装了VsStudio后,如果自己修改了Shared路径,当卸载旧版本,需要安装新版本时发现,之前的Shared路径无法进行修改,这就很坑了 但是却遇到了路径无法修改的问题…真让人头大,当然不修改也可以,有时候&#x…...

目标检测评估指标mAP详解:原理与代码
目标检测评估指标mAP详解:原理与代码 目标检测评估指标mAP详解:原理与代码一、前言:为什么需要mAP?二、核心概念解析2.1 PR曲线(Precision-Recall Curve)2.2 AP计算原理 三、代码实现详解3.1 核心函数ap_pe…...

【风控】模型算法区分度指标KS
一、KS指标的定义原理 背景 KS(Kolmogorov–Smirnov)原本用于检验样本分布与理论分布或两个样本分布是否一致。风控建模中,将“好样本”(Good)与“坏样本”(Bad)的模型输出概率看作两组经验分布…...
道可云人工智能每日资讯|浙江省人民政府印发《关于支持人工智能创新发展的若干措施》
道可云元宇宙每日简报(2025年5月21日)讯,今日元宇宙新鲜事有: 浙江省人民政府印发《关于支持人工智能创新发展的若干措施》 为抢占人工智能发展制高点,打造全球人工智能创新发展高地,浙江省人民政府于近日…...

win11下jenkins+docker+maven自动部署springboot项目
win11下jenkinsdockermaven自动部署springboot项目 一、前置软件安装二、jenkins配置三、springboot项目准备四、jenkins打包部署项目到本地docker中五、jenkins打包部署项目到远程服务器docker中 一、前置软件安装 docker安装 需要开启wsl,以管理员身份运行docke…...