“在代码的世界里,每一行都是进步的足迹,每一次挑战都是成长的机遇。”

编写程序操作数据库 I/O 的一些注意事项


### 避免在 for 循环中执行低效的数据库操作
1. **数据库 CRUD 操作方面**:
- 不要在 for 循环体内部直接执行增删改查(CRUD)操作。因为每一次循环都执行一次数据库操作会带来大量的 I/O 开销,严重影响性能。
- 建议使用 JDBC 的 `addBatch()` 和 `executeBatch()` 方法来批量处理数据库操作。例如在批量插入、更新等场景下,先将多条 SQL 语句添加到批处理中,然后一次性执行,这样可以有效减少与数据库交互的次数,提升数据库操作效率。
- 对于在 for 循环中的查询操作,如果数据量是固定的,可以考虑使用缓存机制。将查询结果缓存起来,后续循环中直接从缓存获取数据,避免重复查询数据库。而当数据量不固定时,可以将需要的数据 ID 进行循环收集,然后使用 `IN (ID)` 语句(适用于 SQL 语句场景)或者利用 MyBatis 的 `foreach` 标签来查询出一个 `LIST`,并将其放到 `MAP` 中,后续在 for 循环时直接从这个 `MAP` 里查找对应的值即可,减少频繁查询数据库的次数。
2. **远程调用方面(以 Feign 为例)**:
同样不建议在 for 循环中调用 Feign 进行远程服务调用。因为网络 I/O 本身具有不稳定性,而且循环过多去发起远程调用会极大地消耗性能。更好的做法是单独编写一个批量接口来处理相关业务逻辑,一次性完成多个数据的远程交互需求,减少因频繁网络调用导致的性能损耗和潜在的不稳定因素,像rpc这些调用基于线程池的可能会将线程池打满。也不要请求任何的网络连接。
### 合理管理数据库事务
在业务逻辑的 `service` 层,要谨慎开启事务,只针对真正涉及增删改查等会改变数据状态的操作开启事务,避免不必要的事务开销。
并且,推荐使用编程式事务。相较于 Spring 基于注解的事务(这种方式在直接调用方法时就开启了事务),编程式事务能够更加灵活精准地控制事务的开启、提交、回滚等操作,使事务管理更加贴合实际业务需求,增强对数据库操作事务一致性的把控。

### 参数校验相关
在 Spring 框架应用中,对于参数的校验可以采取以下合理方式:
一方面,可以将参数校验的工作放到更上游的环节,例如在接口接收参数时就进行初步的合法性、完整性等校验,尽早拦截不符合要求的请求,避免无效的业务处理流程继续向下执行,减少不必要的数据库操作压力。
另一方面,可以借助 JSR 框架来进行参数校验。该框架提供了一套规范且有效的参数校验机制,能够方便地在代码中对方法参数进行细致的校验,确保传入数据库操作相关方法的参数都是符合业务要求的,从而提高数据库操作的准确性和稳定性,避免因参数问题导致的数据库操作异常或数据不一致等情况发生。
此外,在操作数据库 I/O 时,还需注意数据库连接的合理配置与管理,比如设置合适的连接池参数,包括最大连接数、最小连接数、连接超时时间等,确保数据库连接资源能够高效利用且不会出现因连接不足或连接闲置过长等问题影响整体性能。同时,对于数据库的查询语句,要尽量优化其 SQL 写法,合理使用索引,避免出现全表扫描等性能低下的查询情况,以提升数据库 I/O 的整体效率。

Write your comment Here