SpringBoot学习日记 Day5:解锁企业级开发核心技能

一、前言:从玩具项目到生产系统

经过前四天的学习,我们已经能够开发基础功能了。但要让应用真正具备生产价值,还需要掌握数据库高级操作、事务控制、缓存优化等企业级开发技能。今天就来攻克这些关键知识点!

二、JPA进阶:让数据库操作更高效

1. 复杂查询的三种实现方式

方式一:方法名派生查询

public interface UserRepository extends JpaRepository<User, Long> {// 根据姓名模糊查询+年龄范围List<User> findByUsernameContainingAndAgeBetween(String name, Integer minAge, Integer maxAge);// 统计大于某年龄的用户数Long countByAgeGreaterThan(Integer age);
}

方式二:@Query注解(JPQL)

@Query("SELECT u FROM User u WHERE u.dept.id = :deptId AND u.status = :status")
List<User> findUsersByDeptAndStatus(@Param("deptId") Long deptId, @Param("status") Integer status);

方式三:原生SQL查询

@Query(value = "SELECT * FROM users WHERE reg_time > :date", nativeQuery = true)
List<User> findRecentUsers(@Param("date") Date date);

2. 分页查询最佳实践

@GetMapping("/users")
public PageResult<User> getUsers(@RequestParam(defaultValue = "1") Integer page,@RequestParam(defaultValue = "10") Integer size,@RequestParam(required = false) String name) {Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createTime").descending());Page<User> userPage;if (StringUtils.isEmpty(name)) {userPage = userRepository.findAll(pageable);} else {userPage = userRepository.findByUsernameContaining(name, pageable);}return PageResult.success(userPage);
}

3. 关联关系实战(用户-部门示例)

实体类配置:

@Entity
@Data
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;@ManyToOne@JoinColumn(name = "dept_id")private Department department;
}@Entity
@Data
public class Department {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@OneToMany(mappedBy = "department")private List<User> users;
}

查询优化建议:

1. 使用@EntityGraph解决N+1查询问题:

@EntityGraph(attributePaths = {"department"})
List<User> findAllWithDepartment();

2. 延迟加载时注意事务范围:

// 在Service层方法上添加事务注解
@Transactional(readOnly = true)
public User getUserDetail(Long id) {User user = userRepository.findById(id).orElseThrow();// 此时可以安全访问延迟加载的关联对象System.out.println(user.getDepartment().getName());return user;
}

三、事务管理:数据一致性的守护者

1. 声明式事务基础

@Service
@RequiredArgsConstructor
public class OrderService {private final OrderRepository orderRepository;private final UserRepository userRepository;@Transactionalpublic void createOrder(OrderDTO dto) {// 扣减用户余额User user = userRepository.findById(dto.getUserId()).orElseThrow(() -> new BusinessException("用户不存在"));user.setBalance(user.getBalance() - dto.getAmount());userRepository.save(user);// 创建订单Order order = new Order();// 设置订单属性...orderRepository.save(order);// 如果这里抛出异常,上面所有操作都会回滚}
}

2. 事务传播行为实验

传播行为说明适用场景
REQUIRED(默认)当前有事务则加入,没有则新建大多数业务方法
REQUIRES_NEW总是新建事务,挂起当前事务日志记录等独立操作
NESTED在当前事务嵌套子事务部分需要独立回滚的子流程

测试用例:

@Transactional
public void parentMethod() {// 操作1...childMethod();  // 测试不同传播行为// 操作2...
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void childMethod() {// 子方法操作...
}

四、Redis缓存:性能加速器

1. 集成Redis三步走

第一步:添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

第二步:配置连接

spring:redis:host: localhostport: 6379password: database: 0

第三步:启用缓存

@SpringBootApplication
@EnableCaching
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}

2. 缓存注解实战

@Service
public class UserService {// 缓存查询结果@Cacheable(value = "user", key = "#id")public User getUserById(Long id) {return userRepository.findById(id).orElseThrow();}// 更新时清除缓存@CacheEvict(value = "user", key = "#user.id")public User updateUser(User user) {return userRepository.save(user);}// 条件缓存@Cacheable(value = "user", key = "#name", unless = "#result == null")public User getUserByName(String name) {return userRepository.findByUsername(name);}
}

五、文件操作:用户头像上传实战

1. 配置文件上传

spring:servlet:multipart:max-file-size: 2MBmax-request-size: 10MB

2. 实现上传接口

@PostMapping("/avatar/upload")
public Result<String> uploadAvatar(@RequestParam("file") MultipartFile file) {if (file.isEmpty()) {throw new BusinessException("请选择文件");}// 生成唯一文件名String fileName = UUID.randomUUID() + "." + FileUtil.getExtension(file.getOriginalFilename());// 保存文件Path path = Paths.get("uploads/avatars", fileName);try {Files.createDirectories(path.getParent());file.transferTo(path);} catch (IOException e) {throw new BusinessException("文件上传失败");}return Result.success("/avatars/" + fileName);
}

3. 文件下载实现

@GetMapping("/avatar/download/{filename:.+}")
public void downloadAvatar(@PathVariable String filename, HttpServletResponse response) throws IOException {Path path = Paths.get("uploads/avatars", filename);if (!Files.exists(path)) {response.sendError(404, "文件不存在");return;}response.setContentType("image/jpeg");Files.copy(path, response.getOutputStream());
}

六、今日成果:用户管理系统升级版

1. 数据库层:

   - 实现多表关联查询

   - 支持分页排序

   - 完善事务管理

2. 缓存层:

   - 高频查询结果缓存

   - 自动更新缓存策略

3. 文件操作:

   - 头像上传下载功能

   - 文件大小限制处理

4. API增强:

// 分页查询示例
GET /users?page=1&size=10&name=张&sort=age,desc// 头像上传
POST /avatar/upload// 带缓存的用户查询
GET /users/{id}

七、避坑指南

1. N+1查询问题:

   - 使用@EntityGraph或JOIN FETCH优化

   - 测试时开启SQL日志观察查询次数

2. 事务失效场景:

   - 方法必须是public

   - 自调用问题(AOP失效)

   - 异常类型默认只回滚RuntimeException

3. 缓存一致性:

   - 更新数据库后及时清除缓存

   - 考虑使用@CachePut更新缓存

4. 文件存储安全:

   - 校验文件类型(不要仅靠扩展名)

   - 限制上传目录权限

   - 考虑使用云存储服务

八、明日计划

1. 学习SpringBoot定时任务

2. 集成邮件发送功能

3. 实现系统监控端点

4. 探索AOP统一日志处理

思考题:在电商系统中,下单操作需要扣减库存、生成订单、扣减优惠券等多个步骤,该如何设计事务边界?欢迎评论区分享你的设计方案!

如果觉得这篇日记有帮助,请点赞收藏支持~完整代码示例可通过私信获取。在实际开发中遇到问题也欢迎留言讨论!

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

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

相关文章

将英文PDF文件完整地翻译成中文的4类方式

文章目录一、在线翻译服务&#xff08;最快捷&#xff0c;适合临时查看&#xff09;1.1 代表工具&#xff1a;1.2 操作流程&#xff08;以Google翻译为例&#xff09;1.3 优点和缺点1.4 适用场景二、专业软件&#xff08;最佳平衡&#xff0c;兼顾格式与质量&#xff09;2.1 代…

【分享】我国八大沙漠空间矢量范围

今天小编整理分享的是 我国八大沙漠空间矢量范围shp。▲ 我国八大沙漠空间矢量范围概况数据概况我国八大沙漠空间矢量范围。中国八大沙漠。分别为腾格里沙漠&#xff0c;塔克拉马干沙漠&#xff0c;巴丹吉林沙漠&#xff0c;库布奇沙漠&#xff0c;乌兰布和沙漠&#xff0c;库…

【音视频】WebRTC C++ native 编译

一、搭建环境 我们这里介绍在Windows10VS2019的环境下编译WebRTC源码&#xff0c;由于WebRTC源码在外网上&#xff0c;需要科学的方式下载&#xff0c;不然下载特别慢&#xff0c;建议直接找国内下载好的源码&#xff0c;这里的源码是2021年的版本&#xff1a;https://pan.bai…

Selenium在Pyhton应用

目录 1. selenium的基本原理 2. selenium环境的搭建步骤 3. 元素的定位和操作 4.元素的基本属性方法 5.浏览器的操作方法 6.三种等待 强制等待 显示等待 隐式等待 7. 键盘与鼠标的操作 鼠标悬停用 拖拽操作 8. 下拉框元素定位 9.页面滚动操作 10. 页面截图操作 S…

【Docker】Redis基础命令在Docker中的使用

文章目录一 Redis 容器化部署指南1 获取 Redis 镜像2 服务启动2.1 首次启动新容器2.2 重启已有容器3 服务验证4 连接 Redis5 数据持久化方案5.1 使用 Docker 卷5.2 启用 AOF 持久化6 容器管理6.1 停止容器6.2 删除容器7 数据清理7.1 清空 Redis 数据7.2 完全移除7.3 删除数据卷…

ubuntu 2024 安装拼音输入法

1. 卸载ibussudo apt remove ibus2. install fcitx5核心组件sudo apt install fcitx5 fcitx5-chinese-addons fcitx5-material-color3. 安装中文语言支持sudo apt install language-pack-zh-hans4. 设置默认输入法im-config -n fcitx55. 配置环境变量sudo vim ~/.bashrc粘贴&am…

语言模型的多个agent

是的&#xff0c;语言模型 在某些情况下确实可以通过多个 agent&#xff08;代理&#xff09;来共同协作完成任务。这种设计通常用于复杂任务或需要多步骤处理的场景&#xff0c;具体的流程如下&#xff1a; 1. 什么是 Agent&#xff1f; Agent&#xff08;代理&#xff09; 是…

CSS--:root指定变量,其他元素引用

原文网址&#xff1a;CSS--:root指定变量&#xff0c;其他元素引用-CSDN博客 简介 本文介绍CSS中使用变量的方法。 场景描述 CSS可以使用变量&#xff0c;比如&#xff1a;指定整个网页的主体颜色作为变量&#xff0c;其他的元素去使用这个颜色。这样在修改颜色时&#xff…

秋招笔记-8.7

今天先来补充一下关于Unity和UE的一些问题&#xff0c;后续开始深挖项目&#xff1a;Unity关于fixed update和update&#xff1a;同一帧中物理更新优先执行&#xff1f;关于协程&#xff1a;协程是基于迭代器实现的&#xff0c;而迭代器是基于状态机实现的。协程的本质是编译器…

DAY 26 函数专题1:函数定义与参数

浙大疏锦行知识点回顾&#xff1a; 函数的定义变量作用域&#xff1a;局部变量和全局变量函数的参数类型&#xff1a;位置参数、默认参数、不定参数传递参数的手段&#xff1a;关键词参数传递参数的顺序&#xff1a;同时出现三种参数类型时 作业 #作业1 import math def calcul…

跨学科视域下的深层语义分析与人类底层逻辑一致性探索

摘要本文章旨在系统性地探讨一个前沿的交叉学科研究课题&#xff1a;如何通过深层语义分析&#xff0c;探索并建模人类认知中普遍存在的底层逻辑一致性。此研究横跨自然语言处理&#xff08;NLP&#xff09;、知识图谱&#xff08;KG&#xff09;、认知科学、脑神经科学、系统科…

Flink CDC如何保障数据的一致性?

Flink CDC 通过 Checkpoint 机制、幂等性设计 和 事务一致性协议 保障数据同步的一致性。以下是具体实现方式和关键配置&#xff1a;1. Checkpoint 机制&#xff08;核心保障&#xff09;作用&#xff1a;定期保存同步状态&#xff08;包括 Binlog 位置和全量快照进度&#xff…

上传文件至华为云OBS

1 创建华为云Bucket1.1 创建Bucket1.2 获取Bucket的Endpoint1.3 获取访问凭证注&#xff1a;每个访问密钥仅能下载一次&#xff0c;为了账号安全性&#xff0c;建议您定期更换并妥善保存访问密钥。不再使用的访问密钥&#xff0c;建议停用和删除。2 创建Sprint Boot工程创建一个…

使用驱动移除内核回调,

https://br-sn.github.io/Removing-Kernel-Callbacks-Using-Signed-Drivers/ 原创 大蓝 RJ45实验室 使用签名驱动移除内核回调-安全KER - 安全资讯平台 介绍 创建该PoC的目的是了解驱动漏洞利用程序的强大功能&#xff0c;以及EDR如何使用内核回调以防止恶意软件的攻击。…

从零搭建Cloud Alibaba (下) Sentinel篇

1.Sentinel控制台的安装 下载地址&#xff1a; Releases alibaba/Sentinelx 下载后是一个jar包 进入目录 CMD命令 java -jar "sentinel-dashboard-1.8.8 .jar" 如果发生了端口冲突则使用以下命令启动 修改端口号为8090 java -Dserver.port8090 -jar "sen…

Numpy科学计算与数据分析:Numpy数学函数入门与实践

Numpy数学函数实战&#xff1a;探索数学运算的无限可能 学习目标 通过本课程的学习&#xff0c;学员将掌握Numpy中常用的数学函数&#xff0c;包括三角函数、指数函数和对数函数的使用方法&#xff0c;以及如何利用这些函数对数组进行高效的数学运算。本课程不仅会讲解理论知识…

BIGO Ads是什么?BIGO广告营销核心玩法解析

在全球化竞争白热化的当下&#xff0c;BIGO Ads凭借其覆盖150国家的庞大流量池和AI驱动的精准营销能力&#xff0c;已成为出海企业突破增长瓶颈的利器。2025年Q1数据显示&#xff0c;BIGO Ads广告业务同比增长27%&#xff0c;非直播收入占比达24.9%&#xff0c;成为欢聚集团第二…

人工智能领域、图欧科技、IMYAI智能助手2025年3月更新月报

2025年3月AI领域重要技术进展与平台更新概览 2025年3月&#xff0c;人工智能领域迎来一系列重要技术更新与平台功能迭代&#xff0c;尤其在多模态模型、图像生成编辑、视频生成、大型语言模型&#xff08;LLM&#xff09;性能提升等方面表现活跃。以下是对关键进展的梳理&#…

STM32HAL 快速入门(一):点灯前的准备 —— 从软件安装到硬件原理

前言 大家好&#xff0c;这里是 Hello_Embed。嵌入式开发的 “Hello World” 是点灯 —— 通过控制单片机引脚的高低电平&#xff0c;让 LED 亮灭。要实现这个功能&#xff0c;前期准备必不可少&#xff1a;从软件安装到硬件原理理解&#xff0c;每一步都很关键。本文就来详细说…

Python网络编程技术

一、网络编程基础概念 1.1 什么是网络编程&#xff1f; 定义&#xff1a;程序通过网络与其他程序进行通信的技术。核心目标&#xff1a;实现数据在不同主机或进程间的传输与交互。应用场景&#xff1a;Web服务、API调用、实时通信、分布式系统等。 1.2 网络通信模型 OSI七层…