news 2026/4/16 13:03:26

Redis:延迟双删的适用边界与落地细节使

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis:延迟双删的适用边界与落地细节使

pagehelper整合

引入依赖

com.github.pagehelper

pagehelper-spring-boot-starter

2.1.0

compile

编写代码

@GetMapping("/list/{pageNo}")

public PageInfo findAll(@PathVariable int pageNo) {

// 设置当前页码和每页显示的条数

PageHelper.startPage(pageNo, 10);

// 查询数据

List allVip = vipService.findAllVip();

// 将数据封装到pageinfo对象中

PageInfo pageInfo = new PageInfo<>(allVip);

return pageInfo;

}

web层响应结果的封装

对于前后端分离的系统来说,后端会返回json数据,一般会封装一个R对象来解决统一响应格式问题。

package com.ali.springboot3ssm.result;

import lombok.AllArgsConstructor;

import lombok.Builder;

import lombok.Data;

import lombok.NoArgsConstructor;

@Data

@NoArgsConstructor

@AllArgsConstructor

@Builder // 建造模式

public class R {

// 响应状态码

private int code;

// 消息描述:成功或失败

private String msg;

// 响应对象:任意类型对象

private T data;

public static R OK(T data) {

return R.builder().code(200).msg("成功").data(data).build();

}

// 成功的方法

public static R OK() {

return R.builder().code(200).msg("成功").build();

}

// 失败的方法

public static R FAIL(int code,String msg) {

return R.builder().code(code).msg(msg).build();

}

public static R FAIL() {

return R.builder().code(400).msg("失败").build();

}

}

controller中使用

@GetMapping("/list/{pageNo}")

public R< PageInfo> findAll(@PathVariable int pageNo) {

// 设置当前页码和每页显示的条数,设置后会自动为查询语句加limit

PageHelper.startPage(pageNo, 10);

// 查询数据

List allVip = vipService.findAllVip();

// 将数据封装到pageinfo对象中

PageInfo pageInfo = new PageInfo<>(allVip);

return R.OK(pageInfo);

}

改进R对象

添加一个枚举类型

package com.ali.springboot3ssm.enums;

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

@NoArgsConstructor

@AllArgsConstructor

public enum CodeEnum {

// 枚举的大括号一开始的位置必须有枚举值

// 枚举值下面如果没有代码,枚举值列表最后的“;”可以省略

// 枚举值下面如果有代码,枚举值列表最后的“;” 不可以省略

OK(200, "OK"),

FAIL(400, "失败"),

BAD_REQUEST(400, "失败"),

NOT_FOUND(400, "失败"),

INTERNAL_ERROR(400, "失败"),

MODIFICATION_ERROR(400, "失败"),

DELETION_ERROR(400, "失败"),

CREATE_ERROR(400, "失败");

@Getter

@Setter

private int code;

@Getter

@Setter

private String msg;

}

重写R类

@Data

@NoArgsConstructor

@AllArgsConstructor

@Builder // 建造模式

public class R {

// 响应状态码

private int code;

// 消息描述:成功或失败

private String msg;

// 响应对象:任意类型对象

private T data;

public static R OK(T data) {

return R.builder().code(CodeEnum.OK.getCode()).msg(CodeEnum.OK.getMsg()).data(data).build();

}

// 成功的方法

public static R OK() {

return R.builder().code(CodeEnum.OK.getCode()).msg(CodeEnum.OK.getMsg()).build();

}

// 失败的方法

public static R FAIL(CodeEnum codeEnum) {

return R.builder().code(codeEnum.getCode()).msg(codeEnum.getMsg()).build();

}

public static R FAIL() {

return R.builder().code(CodeEnum.FAIL.getCode()).msg(CodeEnum.FAIL.getMsg()).build();

}

}

事务管理

spring boot自动配置了事务管理器。只需要使用@Transactional注解标注需要事务控制的方法即可。

就这么简单。

怎么打war包

修改pom文件

war

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-tomcat

org.springframework.boot

spring-boot-starter-tomcat

provided

启动类继承SpringBootServletInitializer类并重写configure方法

@MapperScan(basePackages = "com.ali.springboot3ssm.repository")

@SpringBootApplication

public class Springboot3SsmApplication extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {

return builder.sources(Springboot3SsmApplication.class);

}

public static void main(String[] args) {

SpringApplication.run(Springboot3SsmApplication.class, args);

}

}

日志处理

抽象的日志框架

什么时抽象的日志框架?编译阶段可以使用抽象的日志框架,能正常编译。但运行阶段必须提供具体的日志框架,目的是:具体的日志框架可灵活切换。

抽象框架有SLF4J 、 Commons Logging。这2个都可以绑定具体的日志框架,如Log4j、Log4j2、Logback、JUL

具体的日志框架

Log4j(已过时)、Log4j2(推荐)、Logback(推荐)、JUL(Java util Logging,功能有限,适合小型应用)

spring boot默认集成log back

日志级别

日志级别由低到高:

trace:级别最低。记录最详细信息,通常在调试时使用

debug:记录程序运行时的详细信息,比如变量的值,进入或退出某个方法等,主要用于开发时调试

info:记录一般信息,如系统启动、服务初始化完成等,表示程序运行正常。

warn:警告信息

error:错误信息

生成环境中 通常把日志级别设为info或更高级别

开发或测试环境中,设为debug或trace

spring boot默认日志级别是info

@Slf4j // 这是lombok的一个注解,作用是为我们维护一个日志对象log

@SpringBootApplication

public class Springboot3SsmApplication {

public static void main(String[] args) {

SpringApplication.run(Springboot3SsmApplication.class, args);

// 直接使用log

log.info("日志信息");

}

}

调整日志级别

# 调整日志级别

logging.level.root=debug

日志的粗细粒度

# 调整根日志级别(全局的,整个项目都是这个级别)

logging.level.root=debug

# 为特定包设置日志级别

logging.level.com.ali.springboot3ssm.controller=debug

# 为特定类设置日志级别

logging.level.com.ali.springboot3ssm.service.UserService=trace

# 在控制台中打印sql (这个包是Mapper类所在的包)

logging.level.com.ali.springboot3ssm.repository=debug

日志输出到文件

有2种方式,这2种方式不能共存,如果同时存在,只有logging.file.name生效

# 将日志文件输出到当前项目根目录下的log目录中。文件名默认spring.log 并且文件名不可修改

# 路径可随便改。可以是硬盘上的任意有权限路径

logging.file.path=./log/

# 日志文件输出到当前项目根目录下my.log文件。路径不可修改

logging.file.name=my.log

滚动日志

防止日志无线增长,将日志文件分割成多个文件,避免单个文件过大难以处理

# 此策略仅适合logback

# 日志文件达到多大时进行归档,打成一个压缩包

logging.logback.rollingpolicy.max-file-size=10MB

# 归档日志文件总共达到多大时删除

logging.logback.rollingpolicy.total-size-cap=50GB

# 归档日志文件最多保留几天

logging.logback.rollingpolicy.max-history=60

#启动项目时是否清理归档日志文件

logging.logback.rollingpolicy.clean-history-on-start=false

# 归档日志文件名格式

logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz

日志框架切换

先排除log back 再引入新依赖

org.springframework.boot

spring-boot-starter-logging

org.springframework.boot

spring-boot-starter-log4j2

酵莆蹦谟

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 22:59:17

从领域驱动到本体论:AI 时代的架构方法论变了对

从0构建WAV文件&#xff1a;读懂计算机文件的本质 虽然接触计算机有一段时间了&#xff0c;但是我的视野一直局限于一个较小的范围之内&#xff0c;往往只能看到于算法竞赛相关的内容&#xff0c;计算机各种文件在我看来十分复杂&#xff0c;认为构建他们并能达到目的是一件困难…

作者头像 李华
网站建设 2026/4/16 2:14:08

华为-AC+FIT AP组网(web方式)

通过web方式配置ACFIT AP组网 一、拓扑图 二、基础配置 2.1 登录web界面 AC1&#xff1a; <AC6605>sys # 进入系统视图 [AC6605]un in en # 关闭信息中心 [AC6605]sys AC1 # 命名 [AC1]vlan 100 # 创建vlan100&#xff08;这个vlan作为web界面的登录地址&#xff09;…

作者头像 李华
网站建设 2026/4/15 23:36:31

BUUCTF(MISC)_[DDCTF2018]

目录 [DDCTF2018](╯□&#xff09;╯︵ ┻━┻ [DDCTF2018]流量分析 [DDCTF2018](╯□&#xff09;╯︵ ┻━┻ 点击跳转至题目 keyd4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1…

作者头像 李华
网站建设 2026/4/11 22:57:19

3个突破性技巧:彻底解决Amlogic S905L3B设备Armbian部署难题

3个突破性技巧&#xff1a;彻底解决Amlogic S905L3B设备Armbian部署难题 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s905, s905l, rk…

作者头像 李华
网站建设 2026/4/11 22:57:18

5分钟快速上手:用Docker一键部署Stable Diffusion AI绘画平台

5分钟快速上手&#xff1a;用Docker一键部署Stable Diffusion AI绘画平台 【免费下载链接】stable-diffusion-webui-docker Easy Docker setup for Stable Diffusion with user-friendly UI 项目地址: https://gitcode.com/gh_mirrors/st/stable-diffusion-webui-docker …

作者头像 李华
网站建设 2026/4/11 22:56:18

从 Apache SeaTunnel 走向 ASF Member:一位开发者的长期主义样本把

一、中间件是啥&#xff1f;咱用“餐厅”打个比方 想象一下&#xff0c;你的FastAPI应用是个高级餐厅。 ?? 顾客&#xff08;客户端请求&#xff09;来到门口。- 迎宾&#xff08;CORS中间件&#xff09;&#xff1a;先看你是不是从允许的街区&#xff08;域名&#xff09;来…

作者头像 李华