Spring整合Mybatis
将 MyBatis 与 Spring 进行整合,主要解决的问题就是将 SqlSessionFactory 对象交由 Spring 来管理。所以,该整合只需要将 SqlSessionFactory 的对象生成器SqlSessionFactoryBean 注册在 Spring 容器中,再将其注入给 Dao 的实现类即可完成整合。
实现 Spring 与 MyBatis 的整合。常用的方式:扫描的 Mapper 动态代理。Spring 像插线板一样,mybatis 框架是插头,可以容易的组合到一起。插线板 spring 插上 mybatis,两个框架就是一个整体。
事务原本是数据库中的概念,在实际项目的开发中,进行事务的处理一般是在业务逻辑层, 即 Service 层。这样做是为了能够使用事务的特性来管理关联操作的业务。
在 Spring 中通常可以通过以下两种方式来实现对事务的管理:
Ⅰ 使用 Spring 的事务注解管理事务
Ⅱ 使用 AspectJ 的 AOP 配置管理事务(声明式事务管理)
Ⅰ 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
Ⅱ 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
Ⅲ 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读,但是innoDB解决了幻读
Ⅳ 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
Ⅴ 使用数据库默认的隔离级别isolation = Isolation.DEFAULT
MySQL:mysql默认的事务处理级别是’REPEATABLE-READ’,也就是可重复读
Oracle:oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。默认系统事务隔离级别是READ COMMITTED,也就是读已提交
多个事务之间的合并,互斥等都可以通过设置事务的传播特性来解决.
常用
PROPAGATION_REQUIRED:必被包含事务(增删改必用)
PROPAGATION_REQUIRES_NEW:自己新开事务,不管之前是否有事务【将正在执行的A的事务挂起,然后执行自己新开的B事务,执行完毕之后,继续执行B事务】
PROPAGATION_SUPPORTS:支持事务,如果加入的方法有事务,则支持事务,如果没有,不单开事务【例如A事务是REQUIRERD类型的,那么B事务进来后也会表成REQUIRED,】
PROPAGATION_NEVER:不能运行中事务中,如果包在事务中,抛异常
PROPAGATION_NOT_SUPPORTED:不支持事务,运行在非事务的环境【将正在执行的A的事务挂起,然后执行自己新开的B事务,执行完毕之后,继续执行B事务】
不常用
PROPAGATION_MANDATORY:必须包在事务中,没有事务则抛异常
PROPAGATION_NESTED:嵌套事务
【了解,一般使用声明式事务的方式】
①propagation = Propagation.REQUIRED,//事务的传播特性
②noRollbackForClassName = “ArithmeticException”, //指定发生什么异常不回滚,使用的是异常的名称
③noRollbackFor = ArithmeticException.class,//指定发生什么异常不回滚,使用的是异常的类型
④rollbackForClassName = “”,//指定发生什么异常必须回滚
⑤rollbackFor = ArithmeticException.class,//指定发生什么异常必须回滚
⑥timeout = -1, //连接超时设置,默认值是-1,表示永不超时
⑦readOnly = false, //默认是false,如果是查询操作,必须设置为true.
⑧ isolation = Isolation.DEFAULT//使用数据库自已的隔离级别
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>5.2.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.2.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.2.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.6version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.29version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.12version>
dependency>
dependencies>
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
build>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<tx:annotation-driven transaction-manager="transactionManager">tx:annotation-driven>

添加事务管理器的原因:事务管理器用来生成相应技术的连接+执行语句的对象. 如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理
下面是不同方式实现对数据库的操作对象
JDBC: Connection con.commit(); con.rollback();
MyBatis: SqlSession sqlSession.commit(); sqlSession.rollback();
Hibernate: Session session.commit(); session.rollback();
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
配置事务切面时可以使用通配符*来匹配所有方法
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<tx:advice id="myadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*select*" read-only="true"/>
<tx:method name="*find*" read-only="true"/>
<tx:method name="*search*" read-only="true"/>
<tx:method name="*get*" read-only="true"/>
<tx:method name="*insert*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="*add*" propagation="REQUIRED"/>
<tx:method name="*save*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="*set*" propagation="REQUIRED"/>
<tx:method name="*update*" propagation="REQUIRED"/>
<tx:method name="*change*" propagation="REQUIRED"/>
<tx:method name="*modify*" propagation="REQUIRED"/>
<tx:method name="*delete*" propagation="REQUIRED"/>
<tx:method name="*remove*" propagation="REQUIRED"/>
<tx:method name="*drop*" propagation="REQUIRED"/>
<tx:method name="*clear*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut id="mycut" expression="execution(* com.bjpowernode.service.impl.*.*(..))">aop:pointcut>
<aop:advisor advice-ref="myadvice" pointcut-ref="mycut">aop:advisor>
aop:config>