提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
在学习这个项目过程中,发现之前学习的很多javase中的基础知识,在实际应用场景中有了许多的扩展,于是在读懂这些代码的同时,我也对一些知识或是已经忘记的,或是还没掌握的,做一个搜索加重新了解,希望可以在回顾时,能够有一个实践做项目时,积累的一些知识经验。
同时,也会按照自己的理解试着梳理下思路和业务逻辑
一、intern
首先我们要知道什么是常量池,
- 字符串常量池是 JVM 内存中的一块特殊区域,用于存储字符串字面量和通过 intern()
方法显式放入的字符串,确保相同内容的字符串在常量池中唯一
其次我们要知道他的核心特点:
- 唯一性保证:常量池中不会存在两个内容相同的字符串。
而intern()针对上述Java常量池特点的用法则有如下:
关键原则:intern() 的价值在于利用常量池的唯一性,将逻辑上相同的字符串(如同一用户 ID 对应的字符串)映射为同一个对象引用,从而在锁机制、内存管理等场景中实现高效的唯一性控制。
二、用户创建空间的并发控制与事务管理
针对智能云图库系统,我们针对空间设计,提出了单个用户仅仅可以创建一个空间。
那么针对 "每个用户仅能创建一个私有空间" 的业务逻辑,我们可以通过字符串常量池 + 同步锁 + 数据库事务组合方案解决并发问题。
那么我们用到的关键api,就有
-
字符串常量池与 intern()
-
同步块 synchronized
- TransactionTemplate:
相比声明式事务(@Transactional),可更灵活地控制事务边界。
这是由于:
而:
三、Stream API 核心概念与常用操作
在处理私有空间时,我们使用了SpaceLevelEnum枚举中获取所有空间等级,并将其转换为SpaceLevel对象列表,然后将转换后的列表封装到统一的响应结构中返回。
那么针对上述知识,我们使用了ava 8 引入的 Stream API。它作为一种函数式编程范式,用于对集合(Collection)、数组等数据源进行高效、简洁的数据处理。Stream 本身不存储数据,而是提供一系列中间操作和终止操作,支持链式调用和延迟执行。
1.Arrays.stream(T[] array)
功能·:将数组转换为顺序流(Stream),便于进行后续的函数式操作(如过滤、映射、聚合等)。
核心特性:支持多种数组类型:包括对象数组(如 String[]、Integer[])和基本类型数组(如 int[]、long[])。
2. Stream.map(Function<? super T, ? extends R> mapper)
功能·:对 Stream 中的每个元素应用映射函数,将其转换为另一种类型,返回一个包含转换后元素的新 Stream。
核心特性:
是中间操作,不会立即执行,而是在终止操作时延迟执行。支持类型转换,可以将 Stream<T> 转换为 Stream<R>(如 Stream<String> → Stream<Integer>)
3. Collectors.toList()
功能·:将 Stream 中的元素收集到一个 List 集合中,通常作为终止操作使用
核心特性:
终止操作:触发 Stream 的执行并生成最终结果。
默认返回 ArrayList:如果需要指定具体实现(如 LinkedList),需使用重载方法。
组合使用实例:
补充一些其他比较常用的api:
四、spaceService.lambdaUpdate() 知识扩展
在处理controller层有关前端请求时,我们在service中使用了MyBatis-Plus(MP)框架提供的 Lambda 式更新构造器,用于构建和执行动态 SQL 更新语句。
- 补充知识如下
条件构造方法:
更新设置方法:
小小的区分一下:
使用 setSql() 而非 set() 可避免并发问题(多个线程同时更新时,setSql() 能保证最终结果的正确性)
五、MyBatis-Plus(MP)框架
上述第四点提到,我在service层中使用MyBatis-Plus的一些知识用于构建和执行动态 SQL 更新语句。
那么我的mapper层中是这样写的:
并且配置了SpaceMapper.xml文件:
这是因为我们是用来基于 MyBatis-Plus(MP)框架 的标准写法,这种分层和配置方式结合了 MP 的简化 CRUD 功能和 MyBatis 的灵活 SQL 支持。
接下来我将对 Mapper 层和 XML 配置进行一个简单的分析:
- 继承 BaseMapper 的作用
- BaseMapper 是 MP 提供的通用 Mapper 接口,内置了 17 个常用数据库操作方法(如 selectById、insert、updateById、delete 等)。
- 继承 BaseMapper<Space> 后,无需编写任何 SQL 代码,即可直接使用这些方法操作数据库。
- 那么为什么不再需要手动实现方法呢?
这是因为:
MP 通过 动态代理机制,在运行时自动生成 SpaceMapper 的实现类,并将方法调用转换为对应的 SQL 语句。
例如:selectById 会自动生成 SELECT * FROM space WHERE id = ? 的 SQL
XML 配置文件分析(SpaceMapper.xml)
- resultMap 的作用
- sql 片段的作用
3.为什么同时需要 Mapper 接口和 XML 配置?
综上所述:这种写法既享受了 MP 的高效性,又保留了 MyBatis 自定义 SQL 的灵活性,适用于大多数业务场景。当项目需要扩展复杂查询时,可直接在 XML 中编写自定义 SQL,无需抛弃 MP 的基础功能。