事务:传播行为
- PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就 加入该事务,该设置是最常用的设置。
- PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不 存在事务,就以非事务执行。
- PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前 不存在事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前 事务挂起。
- PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行(a是父事务,b是子事务,子事务有创建回滚点savepoint,父事务回滚则所有子事务都回滚。子事务回滚到回滚点父事务继续执行,但是由于子事务失败父事务最终也会提交失败)。如果当前没有事务,则 按REQUIRED属性执行。
理解:默认条件事务a,事务b b{a}
1.required: 有新事务加入,则跟着新事物走, eg:使用required, a要跟着b走,只要b回滚(有异常发生),则 a也跟着回滚,等同于事务a,b均未成功
2.required_new : eg:使用required_new ,但是a,b不存在相互影响,
b异常发生在a执行之前,则b回滚,但是a压根没有执行,
b异常发生在a执行之后,则b会回滚,但是a正常commit(执行完成)
java中执行sql之后,不一定会直接映射到java对象中,sql操作的是数据库
// 示例流程 Emp emp = empMapper.selectById(37); // 1. 从数据库查询,映射到Java对象 empExprMapper.deleteByEmpId(37); // 2. 删除数据库记录 System.out.println(emp.getExprList()); // 3. Java对象中的列表仍存在
- 步骤 1:MyBatis 执行查询,将数据库数据映射到
emp
对象的exprList
- 步骤 2:删除操作仅影响数据库,不会修改内存中的
emp
对象 - 步骤 3:Java 对象中的
exprList
仍然保留着查询时的数据
- 数据存储位置独立:Java 对象在内存,数据库在磁盘,两者不会自动同步
- ORM 的映射时机:仅查询操作会将数据库数据映射到 Java 对象
- 保持同步的方法:
- 增删改后若需要最新数据,必须重新查询
- 手动管理 Java 对象状态,与数据库操作保持逻辑一致
- 缓存的影响:删除操作后建议刷新缓存,避免读取旧数据
数据同步的黄金法则
- 增删改操作不自动更新对象:数据库操作与 Java 对象是分离的
- 需要最新数据必须重新查询:通过
select
语句获取最新映射 - 前端渲染依赖显式数据传递:
- 方式 1:后端返回查询结果
- 方式 2:前端发起查询请求
- 事务保证一致性,但不保证同步:事务内可查询最新数据,事务外必须重新查询
sql语句在Java中的xml文件执行,使用foreach循环,可以循环整个语句吗,还是只能循环片段,比如:delete from emp where in{ id}多个id批量删除,可以只循环id或者整个语句循环吗
答:循环整个语句不建议,一般循环的是sql片段(整个会导致效率低下,MyBatis 会将其拼接为多个 DELETE 语句,而不是一次一次的执行)
delete from emp where id in ( <foreach collection="ids" item="id" separator=","> #{id} //根据id进行删除,应该循环的是id,而不是,整个片段 </foreach> )