*************top 1 Spring和MyBatis整合所需的包和核心类
**SqlSessionFactory不需要在Spring中配置
**如果是Spring框架和MyBatis框架整合,则必须要导入mybatis的jar包和mybatis-spring的jar包。
xwork-core.jar是在使用struts框架时使用的jar包。spring-web是在做springMVC时使用的jar包
**在整合Spring框架和MyBatis框架时,可以利用SqlSessionFactoryBean创建SqlSessionFactory,使用MapperFactoryBean将映射接口变成可以注入的SpringBean,SqlSessionTemplate则是负责管理SqlSession的,而ContextLoaderListener是用来在web.xml里面配置Struts或SpringMVC集成Spring的
****Spring与Mybatis集成两种方式:映射接口和SqlSessionTemplate
**MyBatis-Spring的jar包由MyBatis提供。
Spring3.x发布的时候,Mybatis3.x还没有发布,因此,mybatis想要整合Spring框架,只能由它(Mybatis)自己来提供jar包来整合
**Spring和MyBatis的整合可以采用MapperFactoryBean也可以采用SqlSessionTemplate等,整合时需要在applicationContext.xml里面配置数据源datasource和SqlSessionFactoryBean,其中SqlSessionFactoryBean类是由MyBatis提供
**关于数据源
dataSource除了有BasicDataSource类型外,还有其他类型的数据源,SqlSessionFactoryBean和DataSourceTransactionManager都需要注入dataSource
**namespace属性应该是对应接口的完整名称,id属性应该是对应的方法名称
可以不用给出Dao的实现类,而由映射接口实现
MyBatis的配置文件可以写在mybatis本身的配置文件中,也可以在Spring中指定
集成之后同样可以使用xml配置声明式事务
首先应该导入相应的jar包mybatis.jar mybatis-spring.jar等
可以在Spring配置文件中配置数据源
Spring与Mybatis整合可以有多种实现方式
而且为了保证方法自动带事务,必须指定为同一个dataSource
resultMap表示返回类型,应单独配置,resultMap和resultType不能同时存在
*************top 2 使用mapperLocations扫描SQL映射文件
如果在MyBatis-CongigLocation.xml逐个列出所有的sql映射文件,比较繁琐,可以利用SqlSessionFactoryBean的mapperLocations属性扫描式加载SQL映射文件,可以才用*作为通配符的形式,一次加载多个SQL映射文件,但是在集成时还是需要配置MyBatis-CongigLocation.xml
通过SqlSessionFactoryBean中的mapperLocations查看属性
mapperLocations路径不能以/打头
必须指定configLocation,该属性指向MyBatis配置文件
*************top 3 使用SqlSessionTemplate实现数据库操作
getMapper方法实现获取映射接口
selectOne()要求查询最多返回一行结果,如果查询结果不只一条记录,则会出现异常
如果参数存在错误,在编译期间无法识别,只能等到运行的时候才能发现
如果命名空间发生改变,会导致很多地方需要修改,不易维护
即可只传1个参数,也可2个参数
statement为映射项全限定名 命名空间+映射项id
SqlSessionTemplate没有save()方法,只有insert()
*************top 4 使用映射接口实现数据库操作
须遵循的原则:接口的名称和映射命名空间必须相同,接口的方法和映射元素必须相同
**使用SqlSessionTemplate的getMapper方法可以完成映射接口的实现
**可以没有DAO实现的类,这种方式不容易产生错误,并且在编译期就能识别错误。而且命名空间发生变化,也不会导致很多地方需要修改,易于维护。
**在使用Spring 集成MyBatis时,使用SqlSessionTemplate的getMapper()方法获取映射接口时UserMapper接口的名称、方法名称、方法的参数类型都应该和映射文件里面的相关配置一致
**在配置namespace时需要指定带包名的完整类名,否则在启动时会报错
*************top 4 通过不同方式获得映射接口的实例
**采用数据映射器 单个
(MapperFactoryBean)的方式完成对数据库操作
根据Mapper接口获取Mapper对象,它封装了原有的SqlSession.getMapper()功能的实现
** 多个 MapperScannerConfigurer
自动扫描指定包下的Mapper接口,并将它们直接注册为MapperFactoryBean
*************top 5 理解事务属性
**REQUIRED required表示必须运行在事务环境中,REQUIRES_NEW requires_new表示必须运行在自己独立的事务环境内,SUPPORTS supports表示如果没有事务环境,则按照非事务方式执行。默认值是REQUIRED required。
**在自定包和类的指定方法抛出运行时异常时才会执行回滚操作,并非默认情况。
**Spring提供了声明式事务处理机制,它基于AOP实现,无须编写所有的工作全在配置文件中完成
propagation:事务传播机制
isolation:事务隔离级别
read_only:事务是否只读
on-rollback-for:设定运行时异常时回滚
**因为Spring事务管理方式包括编程方式、声明式两种,声明式比编程式更灵活,编程式采用的方式来控制事物的边界。声明式采用配置xml方式,将事务管理与实际业务代码解耦。
**实现声明式事务配置tx和AOP命名空间都是必须导入的。
**安全性属于Java的一个基本特性,并不属于事务属性
事务属性:
一致性
隔离性
持久性
****不便于维护是 编程式事务的特点
**业务代码和事务分离是声明式事务的特点
**声明式事务不需要修改代码本身
**推荐使用声明式事务的原因是它对代码的影响最小,更符合一个无侵入的轻量级容器的特点,而灵活性是编程式事务的特点
*******事务隔离级别5个
ISOLATION_DEFAULT是使用数据库默认的隔离级别,而不是Spring提供的。ISOLATION_SERIALIZABLE是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
ISOLATION_READ_COMMITTED可以防止脏读取
ISOLATION_READ_UNCOMMITTED允许读取其它并行事务还没提交的数据
ISOLATION_REPEATABLE_READ可重复读
************************************************************************
未提交读取(Read Uncommitted)
Spring标识:ISOLATION_READ_UNCOMMITTED。允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
已提交读取(Read Committed)
Spring标识:ISOLATION_READ_COMMITTED。允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
可重复读取(Repeatable Read)
Spring标识:ISOLATION_REPEATABLE_READ。禁止不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
序列化(Serializable)
Spring标识:ISOLATION_SERIALIZABLE。提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
******************************************************************
**事务属性通常由事务的传播行为、事务的隔离级别、事物的超时值、事务只读标志组成
**
*******************在数据库操作过程中很可能出现以下几种不确定情况****************************************************
更新丢失(Lost update)
两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。比如CMS系统中,两个同时打开一篇文章进行修改,一个人先保存,另一个人后保存,后保存的就覆盖了先保存的那个人的内容,这就造成更新丢失。
这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。在并发事务处理带来的问题中,“更新丢失”通常应该是完全避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此,防止更新丢失应该是应用的责任。
脏读(Dirty reads)
一个事务读取到了另一个事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。
不可重复读(Non-repeatable Reads)
一个事务对同一行数据重复读取两次,但是却得到了不同的结果。比如事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。又叫虚读。
幻读(Phantom Reads)
事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。
不可重复读的重点是修改某个记录字段,幻读的重点在于新增或者删除记录。
对于前者, 只需要锁住满足条件的记录。对于后者, 要锁住满足条件及其相近的记录。
“脏读”、“不可重复读”和“幻读”,其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。
*******************************************************************************
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
Spring中同时提供一个标识:ISOLATION_DEFAULT。表示使用后端数据库默认的隔离级别。大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。MySQL的默认隔离级别是Repeatable read。
***********************事务传播机制*****************************
需配置事务管理器,如HibernateTransactionManager
需要定义事务通知,并指定一个事务管理器
需要导入tx 和aop的命名空间
<tx:advice>标签的作用时创建事务处理通知
事务管理器对象由spring负责提供,事务传播机制(propagation)属性默认值是REQUIRED,表示必须存在一个事务,如果当前运行时不存在事务,则会开启一个事务,如果当前运行时存在事务,则支持当前事务。SUPPORTS表示如果存在一个事务,则支持当前事务,如果没有事务,则按非事务方式执行。按照题意分析,默认只有service包中的指定方法在发生运行时异常时才会进行事务回滚
*************top 6 掌握Schema方式的事务配置
----------默认的事务管理器名称是transactionManager
**txMananger是事务管理器对象,但不是由Hibernate框架提供,而是spring框架提供的事务管理bean。REQUIRED是事务管理策略的默认值,表示如果存在一个事务,则支持当前事务,如果当前没有事务,则创建一个新的事务环境来执行,而不是按照非事务方式执行。
**Spring中<tx:advice>标签是用来指定不同的事务性设置而不是创建一个事务
-------------声明式事务:
基于Aop的实现
需要用到tx和aop的两个命名空间
通过<aop:advice>将事务增强与切入点组合
注入事务管理器transactionManager的时候就已经注入了sessionFactory,所以不用再注入sessionFactory属性
execution(* cn.jbit.service.*.*(..)) 表示cn.jbit.service包下所有类的所有方法都应用事务规则
-------------事务通知的配置包含了<tx:advice>和<tx:attribute>以及<tx:method>三组元素,其中<tx:advice>元素中包含事务通知的ID和事务管理器的引用配置;<tx:method>元素包含目标方法名称、事务传播机制以及事务隔离级别等配置
------Spring提供的完整、优秀的事务处理机制
由Spring单独实现,不依赖其他框架,也不与底层API耦合,具有低耦合的特点
提供了声明式事务处理,它基于AOP实现,与代码完全分离,配置即可用,减少了代码的工作量
*dao层:数据访问层,一般只涉及与数据相关的操作,像事务配置等,都会放在业务逻辑层中。
事务配置总是由三个组成部分,分别是DataSource,TransactionManager和代理机制这三部分
**Advisor是Pointcut和Advice的配置器,它包括Pointcut和Advice,是将Advice注入程序中Pointcut位置的代码
******top 7 使用注解实现声明式事务
**execution(public * com.pb.service.impl..*(..))说明要添加事务的方法必须是public的
**timeout是设置事务执行时间,单位是秒
**Spring支持的事务管理类型有:声明式事务管理和编程式事务管理
**@Transactional声明式务的注解,可以指定事务的传播行为和隔离级别
**propagation属性,可以指定事务的传播行为
**isolation属性,可以指定事务的隔离级别
Spring框架的事务管理的优点
为不同的事务API(如JTA、JDBC、hibernate、JPA、JDO)
提供了一个不变的编程模式
为编程事务管理提供一套简单的API
和Spring各种数据访问抽象层都很好的集成
支持声明式事务管理和编程式事务管理
<tx:annotation-driven />用于启动事务控制的注解支持
@Transaction(rollbackFor=Exception.class) 该注解指定,遇到异常Exception时事务回滚
@Transaction注解可以被应用于接口定义和接口方法,类定义和类的public方法上
反转控制--依赖注入
IoC的定义Bean的注解:
@Component
@Service(“userBiz”)表示定义一个id为UserBiz业务Bean
@Repository 用于标DAO类
使用context命名空间下component-scan标签扫描包含注解的类,完成初始化
******top 8 配置DBCP数据源
**DBCP数据源依赖 Jakarta commons-pool对象池机制,支持连接池功能
DBCP是一个依赖Apache commons-pool对象池机制的数据库连接池
使用是需要把Apache的DBCP数据源的实现类包作为第三方依赖包引入
org.springframework.jdbc.datasource.DrivermanagerDataSource数据源,没有连接池的作用
DBCP 1.x数据源的配置属性:
maxActive:最大活动连接数,设置为负数时,没有 限制
maxIdle:最大空闲连接数,设置为负数时,表示没有限制
maxWait:最大等待时间,单位为毫秒,超过时间会抛出异常
defaultReadOnly:设置数据源是否仅能执行只读操作,默认值取决于JDBC驱动的缺省值
使用Spring配置数据源时,initialSize属性是配置DBCP可选的
(必需)driverClassName是数据库服务名username 用户名password 密码initialSize 初始化连接大小url 数据库连接语句
两个必要的jar包:
commons-dbcp.jar
commons-pool.jar