学习日记-spring-day47-9.1

发布于:2025-09-02 ⋅ 阅读:(24) ⋅ 点赞:(0)

知识点:

1.jdbctemplate-查询后封装成对象集合

知识点

核心内容

重点

API调用方法

使用query方法查询并封装多个结果对象,返回List<Monster>集合

queryForObject(单结果)与query(多结果)的区别

SQL参数化查询

通过?占位符动态传入参数(如ID > ?),避免SQL拼接风险

参数绑定与直接拼接SQL的安全性差异

RowMapper复用

相同实体类(Monster)的映射逻辑可直接复用RowMapper实现

不同查询结果复用同一映射器的前提条件

集合结果处理

遍历List<Monster>输出查询结果,适用于非唯一性条件查询

单结果(Optional)与多结果(List)的适用场景对比

JDBC Template核心方法

query(String sql, RowMapper<T> rowMapper, @Nullable Object... args)的参数结构

方法重载(带参数/不带参数)的选择依据

2.jdbctemplate-返回单行单列

知识点

核心内容

重点

JDBC单行单列查询

使用queryForObject方法查询单行单列数据(如count、特定字段值)

返回值类型需匹配(如String/Integer/Double)

SQL语句构造

SELECT name FROM monster WHERE id=100(参数可动态化)

硬编码vs参数化查询的安全性差异

API选择逻辑

通过方法签名推断适用API(queryForObject vs 返回集合的query)

方法重载场景的区分

类型映射

需显式声明返回值类型(如String.class/Integer.class)

基本类型与包装类的选择

扩展应用

统计查询(SELECT COUNT(*))同样适用单行单列模式

聚合函数与类型声明的关联

3.jdbctemplate-具名参数

知识点

核心内容

重点

句名参数

使用具名参数替代问号占位符,通过参数名称明确对应关系

与传统问号参数的区别及优势

NamedParameterJdbcTemplate配置

需通过构造器注入数据源创建专用模板对象

与普通JdbcTemplate的配置差异

参数Map构建

使用HashMap<String,Object>存储具名参数键值对

键名必须与SQL中的参数占位符严格匹配

update方法调用

通过namedParameterJdbcTemplate.update(sql, paramMap)执行操作

返回值仍为受影响行数

SQL语句规范

参数占位符格式为:paramName(冒号+参数名)

与问号占位符语法对比

实战演示

添加蚂蚁精记录(ID:800, name:"蚂蚁精", skill:"喜欢打洞")

参数映射关系验证

4.jdbctemplate-sqlparametersoruce

知识点

核心内容

重点

SQL parameter source用法

使用MapPropertySqlParameterSource封装具名参数

参数名必须与对象属性名严格匹配

参数绑定机制

通过对象属性自动绑定SQL参数

对象属性名(monsterID)与SQL参数名(ID)不一致导致错误

批量操作API

NamedParameterJdbcTemplate.update()方法支持批量处理

需使用SqlParameterSource的数组形式

错误排查方法

根据No value supplied错误提示定位参数绑定问题

属性命名规范一致性检查

API使用思想

通过接口实现类(MapPropertySqlParameterSource)完成功能

需掌握Ctrl+B查看接口实现类的技巧

5.DAO使用jdbctemplate

知识点

核心内容

重点

JDBC Template常用方法

select、insert、delete、update等方法的用法

掌握各方法的使用场景和参数组织方式

使用JDBC Template操作数据库

在dao对象中使用JDBC Template完成数据库操作

如何将JDBC Template注入到dao对象,并调用相应方法进行数据库操作

创建dao类和保存任务

创建一个dao类,并编写保存任务的方法

如何注入JDBC Template,并组织SQL语句进行保存操作

配置扫描包

需要配置扫描包,才能将dao类扫描进Spring容器

忘记配置扫描包会导致dao类无法被Spring容器管理

注意事项

1. 保证dao类能够获取到;

2. 检查容器中是否配置了要扫描的包

1. dao类获取不到;

2. 未配置扫描包导致dao类无法使用

6.事务分类简述

知识点

核心内容

重点

事务分类

编程式事务 vs 声明式事务

编程式事务手动控制提交/回滚 vs 声明式事务基于AOP自动管理

编程式事务流程

1. 获取Connection

2. 关闭自动提交

3. 执行CRUD

4. 提交/异常回滚

setAutoCommit(false) 与 rollback() 的调用时机

声明式事务原理

基于Spring AOP实现,通过注解或配置简化事务管理

与AOP的关联(如环绕通知处理提交/回滚)

案例对比

以商品购买系统演示声明式事务的实际应用

编程式事务代码冗余 vs 声明式事务解耦业务逻辑

7.声明式事务实例(1)

知识点

核心内容

重点

声明式事务原理

通过AOP机制实现事务管理,将业务逻辑与事务控制分离

动态代理实现原理 vs 传统编程式事务

事务一致性场景

用户购买商品涉及三表操作:

商品表查询→用户表扣款→库存表减量

余额扣除成功但库存未减的典型不一致案例

编程式事务实现

手动控制Connection的autoCommit属性,集中编写SQL语句

代码冗余问题 vs 事务边界控制优势

声明式事务优势

方法级事务组装:m1+m2或m2+m3可灵活组合新事务

AOP动态绑定机制实现业务解耦

事务控制要素

必须同时满足的原子操作:SELECT查询→UPDATE余额→UPDATE库存

单个SQL成功但整体失败的异常处理

8.声明式事务实例(2)

知识点

核心内容

重点

声明式事务实现

通过创建用户表、商品表、库存表及GoodsDAO类演示事务操作

表关联关系(用户余额与商品库存的同步修改)

JDBC Template应用

queryForObject()查询价格、update()修改余额/库存

参数绑定顺序(SQL问号与实际参数的对应关系)

DAO层方法设计

queryPriceById()、updateBalance()、updateStock()

方法命名与实际功能的一致性(减少操作而非单纯修改)

测试流程

先验证表结构创建,再测试DAO方法有效性

确保测试数据一致性(如用户初始余额1000/2000)

9.声明式事务实例(3)

知识点

核心内容

重点

Spring容器配置

使用context:component-scan扫描包实现自动注入

XML配置与注解扫描的配合使用

JDBC Template集成

数据源配置与JDBC Template对象创建

外部属性文件引用与对象依赖关系

DAO层方法测试

queryPriceById/updateBalance/updateAmount方法验证

float类型参数传递规范(需加f后缀)

事务管理基础

通过Service层整合多个DAO操作

方法调用链的事务边界控制

依赖注入实践

@Autowired实现GoodsDAO注入

多模块开发时的包路径混淆问题

单元测试规范

JUnit测试框架结合Spring容器测试

测试数据准备与断言验证

类型转换要点

float/double数值类型处理

隐式类型转换的编译错误规避

配置复用技巧

JDBC配置跨文件复用

多环境配置的兼容性处理

10.声明式事务实例(4)

知识点

核心内容

重点

事务管理

演示不使用事务导致的数据不一致问题

部分SQL成功部分失败导致数据不一致

分层架构

Service层调用DAO层完成商品购买业务

依赖注入顺序:Service→DAO→JDBC Template

方法设计

buyGoods()方法参数设计(userId/goodsId/amount)

参数验证在实际开发中的必要性

SQL调试

通过输出购买信息辅助调试

未处理异常时的数据不一致现象

包扫描配置

Spring容器扫描范围配置方案对比

精准扫描(dao+service) vs 父包扫描(tx.*)

事务原子性

多个数据库操作应视为整体事务

要么全部成功,要么全部回滚

11.声明式事务实例(5)

知识点

核心内容

重点

声明式事务管理

使用@Transactional注解标记方法,使方法内的数据库操作作为一个原子性事务(全部成功或全部失败)

注解需配合事务管理器配置,仅加注解不生效

事务管理器配置

需定义DataSourceTransactionManager bean,并指定关联的数据源(与JDBC Template一致)

数据源必须一致,否则事务控制失效

启用注解驱动

需在配置中添加<tx:annotation-driven>标签,并指定事务管理器

需注意选择tx命名空间标签(非其他功能标签)

事务控制验证

通过模拟异常场景(如SQL错误)验证数据一致性(余额与库存同时回滚)

部分成功场景是常见测试用例

源码机制

事务管理器通过数据源连接控制提交/回滚,@Transactional由AOP代理实现

Debug源码可观察代理类生成过程

12.声明式事务实例(6)

知识点

核心内容

重点

事务管理器工作原理

DataSourceTransactionManager 的核心作用与配置方法

数据源连接与事务控制的关系

doBegin方法机制

将autoCommit设为FALSE实现手动提交控制

默认true与手动false的区别

事务提交流程

doCommit方法在无异常时执行connection.commit()

提交时机与业务方法执行顺序

回滚触发条件

doRollback方法在异常时执行connection.rollback()

异常类型与回滚范围

AOP动态代理实现

通过前置通知(doBegin)、返回通知(doCommit)、异常通知(doRollback)实现事务控制

代理对象调用流程与原生代码区别

声明式事务优势

@Transactional注解替代编程式try-catch代码块

注解生效条件与配置要求

事务隔离级别验证

通过debug观察connection.isolationLevel变化

不同隔离级别的并发问题表现

连接池代理对象

通过getConnection()获取的实际是代理连接

原生连接与代理连接的方法拦截差异

13.事务传播机制问题

知识点

核心内容

重点

声明式事务传播机制

多个事务方法嵌套调用时的控制规则(如外层事务管理内层事务的提交/回滚)

嵌套事务的独立性判断(是否受外层事务接管)

事务传播场景案例

multiTxTest方法(事务)调用buyGoods1和buyGoods2(均为事务方法)

方法间事务边界划分(默认机制 vs 显式配置)

传播机制核心问题

嵌套事务的归属管理(如f1和f2是否独立于外层事务f)

传播行为类型(REQUIRED/NEW/NESTED等)

14.事务传播机制种类介绍

知识点

核心内容

重点

事务传播机制种类

介绍事务传播属性的七种类型,重点前两种:required和requires new

required vs requires new的区别

required传播属性

如果当前有事务运行,则在当前事务内执行;否则启动新事务

嵌套事务是否回滚取决于外层事务

requires new传播属性

无论当前是否有事务,都启动新事务,并挂起现有事务(若存在)

嵌套事务独立提交/回滚,互不影响

事务传播示例(required)

f1和f2方法若均使用required,则被统一管理,任一失败整体回滚

嵌套事务的原子性表现

事务传播示例(requires new)

f1和f2方法若使用requires new,则各自独立,失败互不影响

独立事务的隔离性实现

15.事务传播机制图解

知识点

核心内容

重点

事务传播机制(Required)

默认传播机制,若外部方法已开启事务,则内部方法加入同一事务;若外部无事务,则新建独立事务。

整体事务管理:内部方法(如f1、f2)失败会导致外部事务整体回滚。

事务传播机制(Requires New)

强制新建独立事务,挂起外部事务;内部方法事务与外部完全隔离,互不影响。

独立性:f2成功但f3失败时,仅回滚f3的事务。

传播属性指定方法

通过@Transactional(propagation=Propagation.REQUIRED/NEW)注解显式声明。

易忽略点:默认不写propagation即为REQUIRED。

其他传播属性

SUPPORTS/NOT_SUPPORTED/MANDATORY/NEVER等,仅需了解,开发中较少使用。

区分MANDATORY(强制要求外部事务)与NEVER(禁止外部事务)。

图示解析

通过嵌套方法调用(如f1→f2→f3)对比REQUIRED(统一事务)与REQUIRES_NEW(独立事务)的执行流程。

关键差异:REQUIRES_NEW会挂起外部事务并创建新事务上下文。

16.事务传播机制应用实例

知识点

核心内容

重点

事务传播机制

通过商品购买案例演示事务传播机制的控制逻辑,重点分析REQUIRED和REQUIRES_NEW两种传播属性的差异

REQUIRED默认机制下多个方法会合并为同一事务(整体回滚),REQUIRES_NEW会创建独立事务(互不影响)

声明式事务实现

使用@Transactional注解标记方法,通过修改propagation属性控制传播行为

需区分方法调用层级事务嵌套关系,避免混淆传播属性的生效范围

事务回滚验证

通过故意修改SQL语句触发异常,观察不同传播机制下的数据回滚效果

重点验证:REQUIRED会连带回滚已成功的操作,REQUIRES_NEW仅回滚当前失败方法

环境搭建技巧

复制多套DAO/Service方法(如queryPriceById2、updateBalance2)以隔离测试场景

需保持方法功能一致性,仅通过后缀区分不同事务控制逻辑

其他传播属性

SUPPORTS/NOT_SUPPORTED等机制

注意MANDATORY(强制存在事务)与NEVER(强制无事务)的互斥性

17.事务隔离级别说明

知识点

核心内容

重点

事务隔离级别基本概念

介绍事务隔离级别的定义及四种类型(读未提交、读已提交、可重复读、可串行化)

隔离级别的增强顺序及区别

Spring声明式事务默认隔离级别

默认使用底层数据库(如MySQL)的隔离级别(REPEATABLE READ)

Isolation.DEFAULT源码解析:与数据库默认级别同步

MySQL默认隔离级别查询方法

SELECT @@global.tx_isolation 返回当前数据库隔离级别(示例结果为REPEATABLE READ)

实际开发中需明确数据库配置

可重复读隔离级别特性

事务未结束前读取的数据始终一致,其他事务提交的修改不可见

易混淆点:与“读已提交”的可见性差异

源码追踪与验证

通过Spring Isolation 枚举类分析默认隔离级别逻辑

关键代码:@Transactional(isolation = Isolation.DEFAULT)

18.事务隔离级别应用实例(1)

知识点

核心内容

重点

事务隔离级别设置

演示默认隔离级别为REPEATABLE_READ的可重复读特性

默认隔离级别与自动提交的区别

声明式事务测试方法

通过GoodsService类中的buyGoodsByTxIsolation方法进行测试

事务注解@Transactional的使用方式

可重复读隔离级别验证

在事务中两次查询同一数据,即使外部修改已提交仍读取原始值

REPEATABLE_READ与READ_COMMITTED的区别

测试环境搭建

使用Spring程序与SQLyog工具进行并发操作测试

数据库连接工具默认自动提交特性

隔离级别修改方法

通过@Transactional(isolation=Isolation.XXX)属性修改隔离级别

不同隔离级别的适用场景选择

19.事务隔离级别应用实例(2)

知识点

核心内容

重点

声明式事务隔离级别修改

通过isolation属性设置隔离级别,演示从默认级别改为read commit

隔离级别生效条件:必须在新事务中才能观察到修改后的效果

读已提交(READ COMMITTED)特性

可以读取其他事务已提交的数据变更,能获取最新数据

与REPEATABLE READ区别:后者在同一事务中多次读取数据保持一致

隔离级别修改验证方法

通过debug断点调试,观察事务中数据读取的变化过程

关键验证步骤:修改数据后立即提交,在新事务中确认读取到最新值

默认隔离级别建议

推荐保持默认的REPEATABLE READ级别,特殊需求才修改

典型误用场景:无明确需求时盲目修改隔离级别

事务超时回滚预告

下文将讲解事务超时设置与自动回滚机制

关联知识点:超时时间与系统性能的平衡

20.事务超时回滚(1)

知识点

核心内容

重点

声明式事务超时回滚

通过@Transactional(timeout=2)设置事务超时时间为2秒,若方法执行超过该时长则自动回滚

默认值timeout=-1表示采用底层事务系统默认超时时间(如MySQL默认60秒)

超时时间单位

timeout属性默认以为单位(非毫秒)

需注意数据库支持的最小超时精度(如Oracle可能不支持秒级超时)

超时回滚验证

通过Thread.sleep(4000)模拟4秒操作,触发超时回滚(与设置的2秒对比)

测试时需确保SQL语句正确,避免非超时导致的异常干扰结果

默认超时行为

未设置timeout时依赖数据库默认配置,不同数据库差异大(MySQL/Oracle等)

不支持超时的系统会忽略该属性设置

21.事务超时回滚(2)

知识点

核心内容

重点

事务超时模拟

在DAO方法后插入Thread.sleep(4000)模拟4秒超时

超时位置选择(需在成功执行SQL语句后)

事务回滚机制

超时异常触发Spring事务回滚

验证方法:对比数据库余额变化

线程基础应用

使用Thread.sleep()实现延时

时间单位是毫秒(4000ms=4s)

测试验证流程

1. 记录初始余额

2. 执行含超时代码

3. 检查异常日志

4. 验证余额回滚

关键验证点:数据库最终状态应与初始一致


网站公告

今日签到

点亮在社区的每一天
去签到