这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战
Spring集成Mybatis
集成思路
Spring能集成很多的框架,是Spring的优势,通过集成其他框架试开发更简单方便,集成使用的SPring的IOC功能
要使用Mybatis步骤
要使用mybatis就要创建mybatis框架里的某些对象,使用这些对象就能使用mybatis的功能了,到底需要哪些呢,我们可以把这些对象交给Spring来管理,需要使用在容器里拿就可以了
- 需要有dao的代理对象
- 需要SQLSessionFactory,创建sqlSessionFactory对象,才能使用openSession()得到SqlSession对象
- 数据源DataSource对象
整合mybatis
生成数据库表
1 | sql复制代码CREATE TABLE `user` ( |
加入依赖xml
1 | xml复制代码<dependencies> |
实体类
1 | typescript复制代码public class User { |
UserMapper.java
1 | java复制代码@Mapper |
UserMapper.xml
1 | xml复制代码<?xml version="1.0" encoding="UTF-8" ?> |
1 | java复制代码@Service |
1 | java复制代码@Service |
Mybatis配置文件
1 | xml复制代码<?xml version="1.0" encoding="UTF-8" ?> |
spring配置文件
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
测试类
1 | ini复制代码@Test |
输出结果
Spring事务
概述
事务是一些列SQL语句的集合,是多条SQL要么都成功要么都失败。
什么时候使用事务
一个操作需要多条Sql语句一块完成,操作才能成功
事务在哪里说明
在业务方法上边
1 | java复制代码public class dao(){ |
Spring事务管理器
不同的数据库访问技术,处理事务是不同的,Spring统一管理事务,把不同的数据访问技术的事务处理统一起来,使用Spring的事务管理器,管理不同数据库访问技术处理事务,只需要掌握spring的事务处理一个方案,可以实现使用不同数据库访问技术的事务管理。
spring框架使用事务管理器管理对象,事务管理器的接口是PlatformTransacationManger,定义了事务的操作,主要是commit()rollback()事务管理器有很多实现类,一种数据库访问计数有一个实现类,有实现类具体完成事物的提交,回滚。 jdbc和mmybatis的事务管理器是DataSourceTranactionManager。hibernate事务管理器是hibernateTranactionManager
老师画的一张图,spring管理事务的工作方式,业务代码正常执行局提交了,运行时出现异常就回滚了
业务代码正常执行局提交了,运行时出现异常就回滚了
异常分类
- Error 严重错误,回滚事务
- Exception 异常类,可以处理的异常
- 运行时异常 : RuntimeException和它的子类都是运行时异常,在程序执行中抛出的异常,常见的有 NullPointException空指针异常,IndexOutOfBoundsException数组越界异常ClassCastException强制装换异常
- 受查异常: 编写java代码的时候,必须出来的异常,如IOException。SQLException
运行方法中只要出现了运行时异常事务回滚,其他情况(正常执行方法,受查异常)提交事务
事务使用的是AOP的环绕通知
环绕通知: 可以在目标方法的前后都机上增强,不需要修改代码,在业务代码前开启事务,在业务代码后提交事务,出现异常Catch回滚事务
事务定义接口 TransactionDefinition
定义了三类常量,定义了有关事务控制的属性
- 隔离级别
- 传播行为
- 事物的超时
隔离级别
隔离级别:控制事物之间的影响程度
这些常量均是以 ISOLATION_开头。即形如 ISOLATION_XXX。
- DEFAULT:采用 DB 默认的事务隔离级别。MySql 的默认为 REPEATABLE_READ(可重复读);Oracle默认为 READ_COMMITTED。(读已提交)
- READ_UNCOMMITTED:读未提交。未解决任何并发问题。
- READ_COMMITTED:读已提交。解决脏读,存在不可重复读与幻读。
- REPEATABLE_READ:可重复读。解决脏读、不可重复读,存在幻读
- SERIALIZABLE:串行化。不存在并发问题。
超时时间
以秒为单位 ,默认-1,表示一个业务方法最长的执行时间,到时见没有执行完毕,会回滚事务
传播行为
业务方法在执行时,事务在方法间的传递和使用,可以标志方法有无事务,有七个值PROPAGATION_XXXX开头
- PROPAGATION_REQUIRED 默认传播行为,方法执行时,如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务,在新事务里执行
- PROPAGATION_SUPPORTS 支持,如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
- PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
- PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
- PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。
- PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常
- PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
代码测试–不加事务
模拟买东西订单表添加商品,库存表减库存
准备两张表
1 | sql复制代码CREATE TABLE `sale` ( |
实体类
1 | vbnet复制代码@Data |
1 | vbnet复制代码@Data |
spring配置文件
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
mybatis配置文件
1 | xml复制代码<?xml version="1.0" encoding="UTF-8" ?> |
mapper及xml
1 | xml复制代码<?xml version="1.0" encoding="UTF-8" ?> |
1 | java复制代码@Mapper |
1 | xml复制代码<?xml version="1.0" encoding="UTF-8" ?> |
1 | java复制代码@Mapper |
业务方法
1 | csharp复制代码public interface BuyService { |
1 | scss复制代码@Autowired |
测试类
1 | ini复制代码public void shouldAnswerWithTrue() |
以上代码我没加事务的情况下 去购买没有的产品,报错但是第一步订单表的信息还是会保存。
Spring框架使用自己的注解@Transaction控制事务
@Transaction使用注解的属性控制事务,隔离级别,传播行为,超时时间
@Transaction的属性
- propagation : 事物的传播行为,他使用的Propagation类的枚举值 Propagation.REQUIRED
- isolation : 隔离级别 使用Isolation枚举类表示隔离级别 默认Isolation.DEFAULT
- readOnly : Boolean类型的值 标识数据库操作是不是只读,默认false
- timeout : 事务超时,默认是-1 整数值单位是秒,例如 timeout =20
- rollBackFor :表示回滚的异常类型
- rollBackForClassName : 回滚的异常类列表。值时异常类名称,String类型的值
- noRollackFor :不需要回滚的数据异常,是class类型
- noRollBackForClassName : 不需要回滚的数据异常,是String类型
位置 - 在业务方法的上边,在public方法上边
- 在类的上边
特点 - Spring自己的事务管理
- 适合中小项目
- 使用方便
使用注解实现事务
在Spring配置文件里声明事务管理器并开启注解
1 | xml复制代码 <!--声明事务控制器--> |
在业务代码上添加@Transactional注解并配置属性,直接写@Transactional也可以实现事务,都使用默认值。rollbackFor回滚的异常类型,指定的话先根据指定的找,找不到找是不是RuntimeException的子类都会回滚,那这个属性是不是有点多余,当我们要指定受查异常时就可以使用,还有一个属性noRollackFor,可以指定什么异常不需要回滚
1 | ini复制代码@Transactional(propagation = Propagation.REQUIRED, |
声明式事务
1 | xml复制代码<!--声明式事务--> |
本文转载自: 掘金