百知教育 — Spring系列课程 — 持久层整合


第一章、持久层整合

1.Spring框架为什么要与持久层技术进行整合
  1. 1. JavaEE开发需要持久层进行数据库的访问操作。
  2. 2. JDBC Hibernate MyBatis进行持久开发过程存在大量的代码冗余
  3. 3. Spring基于模板设计模式对于上述的持久层技术进行了封装
2. Spring可以与那些持久层技术进行整合?
  1. 1. JDBC
  2. |- JDBCTemplate
  3. 2. Hibernate (JPA)
  4. |- HibernateTemplate
  5. 3. MyBatis
  6. |- SqlSessionFactoryBean MapperScannerConfigure

第二章、Spring与MyBatis整合

1. MyBatis开发步骤的回顾
  1. 1. 实体
  2. 2. 实体别名
  3. 3.
  4. 4. 创建DAO接口
  5. 5. 实现Mapper文件
  6. 6. 注册Mapper文件
  7. 7. MybatisAPI调用
2. Mybatis在开发过程中存在问题
  1. 配置繁琐 代码冗余
  2. 1. 实体
  3. 2. 实体别名 配置繁琐
  4. 3.
  5. 4. 创建DAO接口
  6. 5. 实现Mapper文件
  7. 6. 注册Mapper文件 配置繁琐
  8. 7. MybatisAPI调用 代码冗余
3. Spring与Mybatis整合思路分析

4. Spring与Mybatis整合的开发步骤
  • 配置文件(ApplicationContext.xml) 进行相关配置

    1. #配置 是需要配置一次
    2. <bean id="dataSource" class=""/>
    3. <!--创建SqlSessionFactory-->
    4. <bean id="ssfb" class="SqlSessionFactoryBean">
    5. <property name="dataSource" ref=""/>
    6. <property name="typeAliasesPackage">
    7. 指定 实体类所在的包 com.baizhiedu.entity User
    8. Product
    9. </property>
    10. <property name="mapperLocations">
    11. 指定 配置文件(映射文件)的路径 还有通用配置
    12. com.baizhiedu.mapper/*Mapper.xml
    13. </property>
    14. </bean>
    15. <!--DAO接口的实现类
    16. session ---> session.getMapper() --- xxxDAO实现类对象
    17. XXXDAO ---> xXXDAO
    18. -->
    19. <bean id="scanner" class="MapperScannerConfigure">
    20. <property name="sqlSessionFactoryBeanName" value="ssfb"/>
    21. <property name="basePacakge">
    22. 指定 DAO接口放置的包 com.baizhiedu.dao
    23. </property>
    24. </bean>
  • 编码

    1. # 实战经常根据需求 写的代码
    2. 1. 实体
    3. 2.
    4. 3. 创建DAO接口
    5. 4. 实现Mapper文件
5. Spring与Mybatis整合编码
  • 搭建开发环境(jar)

    1. <dependency>
    2. <groupId>org.springframework</groupId>
    3. <artifactId>spring-jdbc</artifactId>
    4. <version>5.1.14.RELEASE</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.mybatis</groupId>
    8. <artifactId>mybatis-spring</artifactId>
    9. <version>2.0.2</version>
    10. </dependency>
    11. <dependency>
    12. <groupId>com.alibaba</groupId>
    13. <artifactId>druid</artifactId>
    14. <version>1.1.18</version>
    15. </dependency>
    16. <dependency>
    17. <groupId>mysql</groupId>
    18. <artifactId>mysql-connector-java</artifactId>
    19. <version>5.1.48</version>
    20. </dependency>
    21. <dependency>
    22. <groupId>org.mybatis</groupId>
    23. <artifactId>mybatis</artifactId>
    24. <version>3.4.6</version>
    25. </dependency>
  • Spring配置文件的配置

    1. <!--连接池-->
    2. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    3. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    4. <property name="url" value="jdbc:mysql://localhost:3306/suns?useSSL=false"></property>
    5. <property name="username" value="root"></property>
    6. <property name="password" value="123456"></property>
    7. </bean>
    8. <!--创建SqlSessionFactory SqlSessionFactoryBean-->
    9. <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
    10. <property name="dataSource" ref="dataSource"></property>
    11. <property name="typeAliasesPackage" value="com.baizhiedu.entity"></property>
    12. <property name="mapperLocations">
    13. <list>
    14. <value>classpath:com.baizhiedu.mapper/*Mapper.xml</value>
    15. </list>
    16. </property>
    17. </bean>
    18. <!--创建DAO对象 MapperScannerConfigure-->
    19. <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    20. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"></property>
    21. <property name="basePackage" value="com.baizhiedu.dao"></property>
    22. </bean>
  • 编码

    1. 1. 实体
    2. 2.
    3. 3. DAO接口
    4. 4. Mapper文件配置
6. Spring与Mybatis整合细节
  • 问题:Spring与Mybatis整合后,为什么DAO不提交事务,但是数据能够插入数据库中?

    1. Connection --> tx
    2. Mybatis(Connection)
    3. 本质上控制连接对象(Connection) ---> 连接池(DataSource)
    4. 1. Mybatis提供的连接池对象 ---> 创建Connection
    5. Connection.setAutoCommit(false) 手工的控制了事务 操作完成后,手工提交
    6. 2. DruidC3P0 DBCP)作为连接池 ---> 创建Connection
    7. Connection.setAutoCommit(true) true默认值 保持自动控制事务,一条sql 自动提交
    8. 答案:因为SpringMybatis整合时,引入了外部连接池对象,保持自动的事务提交这个机制(Connection.setAutoCommit(true)),不需要手工进行事务的操作,也能进行事务的提交
    9. 注意:未来实战中,还会手工控制事务(多条sql一起成功,一起失败),后续Spring通过事务控制解决这个问题。

第三章、Spring的事务处理

1. 什么是事务?
  1. 保证业务操作完整性的一种数据库机制
  2. 事务的4特点: A C I D
  3. 1. A 原子性
  4. 2. C 一致性
  5. 3. I 隔离性
  6. 4. D 持久性
2. 如何控制事务
  1. JDBC:
  2. Connection.setAutoCommit(false);
  3. Connection.commit();
  4. Connection.rollback();
  5. Mybatis
  6. Mybatis自动开启事务
  7. sqlSession(Connection).commit();
  8. sqlSession(Connection).rollback();
  9. 结论:控制事务的底层 都是Connection对象完成的。
3.Spring控制事务的开发
  1. Spring是通过AOP的方式进行事务开发
1. 原始对象
  1. public class XXXUserServiceImpl{
  2. private xxxDAO xxxDAO
  3. set get
  4. 1. 原始对象 ---》 原始方法 ---》核心功能 (业务处理+DAO调用)
  5. 2. DAO作为Service的成员变量,依赖注入的方式进行赋值
  6. }
2. 额外功能
  1. 1. org.springframework.jdbc.datasource.DataSourceTransactionManager
  2. 2. 注入DataSource
  3. 1. MethodInterceptor
  4. public Object invoke(MethodInvocation invocation){
  5. try{
  6. Connection.setAutoCommit(false);
  7. Object ret = invocation.proceed();
  8. Connection.commit();
  9. }catch(Exception e){
  10. Connection.rollback();
  11. }
  12. return ret;
  13. }
  14. 2. @Aspect
  15. @Around
3. 切入点
  1. @Transactional
  2. 事务的额外功能加入给那些业务方法。
  3. 1. 类上:类中所有的方法都会加入事务
  4. 2. 方法上:这个方法会加入事务
4 组装切面
  1. 1. 切入点
  2. 2. 额外功能
  3. <tx:annotation-driven transaction-manager=""/>
4. Spring控制事务的编码
  • 搭建开发环境 (jar)

    1. <dependency>
    2. <groupId>org.springframework</groupId>
    3. <artifactId>spring-tx</artifactId>
    4. <version>5.1.14.RELEASE</version>
    5. </dependency>
  • 编码

    1. <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
    2. <property name="userDAO" ref="userDAO"/>
    3. </bean>
    4. <!--DataSourceTransactionManager-->
    5. <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    6. <property name="dataSource" ref="dataSource"/>
    7. </bean>
    8. @Transactional
    9. public class UserServiceImpl implements UserService {
    10. private UserDAO userDAO;
    11. <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
  • 细节

    1. <tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"/>
    2. 进行动态代理底层实现的切换 proxy-target-class
    3. 默认 false JDK
    4. true Cglib

第四章、 Spring中的事务属性(Transaction Attribute)

1. 什么是事务属性
  1. 属性:描述物体特征的一系列值
  2. 性别 身高 体重 ...
  3. 事务属性:描述事务特征的一系列值
  4. 1. 隔离属性
  5. 2. 传播属性
  6. 3. 只读属性
  7. 4. 超时属性
  8. 5. 异常属性
2. 如何添加事务属性
  1. @Transactional(isloation=,propagation=,readOnly=,timeout=,rollbackFor=,noRollbackFor=,)
3. 事务属性详解
1. 隔离属性 (ISOLATION)
  • 隔离属性的概念

    1. 概念:他描述了事务解决并发问题的特征
    2. 1. 什么是并发
    3. 多个事务(用户)在同一时间,访问操作了相同的数据
    4. 同一时间:0.000几秒 微小前 微小后
    5. 2. 并发会产生那些问题
    6. 1. 脏读
    7. 2. 不可重复读
    8. 3. 幻影读
    9. 3. 并发问题如何解决
    10. 通过隔离属性解决,隔离属性中设置不同的值,解决并发处理过程中的问题。
  • 事务并发产生的问题

    • 脏读

      1. 一个事务,读取了另一个事务中没有提交的数据。会在本事务中产生数据不一致的问题
      2. 解决方案 @Transactional(isolation=Isolation.READ_COMMITTED)
    • 不可重复读

      1. 一个事务中,多次读取相同的数据,但是读取结果不一样。会在本事务中产生数据不一致的问题
      2. 注意:1 不是脏读 2 一个事务中
      3. 解决方案 @Transactional(isolation=Isolation.REPEATABLE_READ)
      4. 本质: 一把行锁
    • 幻影读

      1. 一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题
      2. 解决方案 @Transactional(isolation=Isolation.SERIALIZABLE)
      3. 本质:表锁
    • 总结

      1. 并发安全: SERIALIZABLE>REPEATABLE_READ>READ_COMMITTED
      2. 运行效率: READ_COMMITTED>REPEATABLE_READ>SERIALIZABLE
  • 数据库对于隔离属性的支持

    隔离属性的值 MySQL Oracle
    ISOLATION_READ_COMMITTED
    IOSLATION_REPEATABLE_READ
    ISOLATION_SERIALIZABLE
    1. Oracle不支持REPEATABLE_READ 如何解决不可重复读
    2. 采用的是多版本比对的方式 解决不可重复读的问题
  • 默认隔离属性

    1. ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性
    2. MySQL : REPEATABLE_READ
    3. Oracle: READ_COMMITTED
    • 查看数据库默认隔离属性

      • MySQL

        1. select @@tx_isolation;
      • Oracle

        1. SELECT s.sid, s.serial#,
        2. CASE BITAND(t.flag, POWER(2, 28))
        3. WHEN 0 THEN 'READ COMMITTED'
        4. ELSE 'SERIALIZABLE'
        5. END AS isolation_level
        6. FROM v$transaction t
        7. JOIN v$session s ON t.addr = s.taddr
        8. AND s.sid = sys_context('USERENV', 'SID');
  • 隔离属性在实战中的建议

    1. 推荐使用Spring指定的ISOLATION_DEFAULT
    2. 1. MySQL repeatable_read
    3. 2. Oracle read_commited
    4. 未来实战中,并发访问情况 很低
    5. 如果真遇到并发问题,乐观锁
    6. Hibernate(JPA) Version
    7. MyBatis 通过拦截器自定义开发
2. 传播属性(PROPAGATION)
  • 传播属性的概念

    1. 概念:他描述了事务解决嵌套问题的特征
    2. 什么叫做事务的嵌套:他指的是一个大的事务中,包含了若干个小的事务
    3. 问题:大事务中融入了很多小的事务,他们彼此影响,最终就会导致外部大的事务,丧失了事务的原子性
  • 传播属性的值及其用法

    传播属性的值 外部不存在事务 外部存在事务 用法 备注
    REQUIRED 开启新的事务 融合到外部事务中 @Transactional(propagation = Propagation.REQUIRED) 增删改方法
    SUPPORTS 不开启事务 融合到外部事务中 @Transactional(propagation = Propagation.SUPPORTS) 查询方法
    REQUIRES_NEW 开启新的事务 挂起外部事务,创建新的事务 @Transactional(propagation = Propagation.REQUIRES_NEW) 日志记录方法中
    NOT_SUPPORTED 不开启事务 挂起外部事务 @Transactional(propagation = Propagation.NOT_SUPPORTED) 及其不常用
    NEVER 不开启事务 抛出异常 @Transactional(propagation = Propagation.NEVER) 及其不常用
    MANDATORY 抛出异常 融合到外部事务中 @Transactional(propagation = Propagation.MANDATORY) 及其不常用
  • 默认的传播属性

    1. REQUIRED是传播属性的默认值
  • 推荐传播属性的使用方式

    1. 增删改 方法:直接使用默认值REQUIRED
    2. 查询 操作:显示指定传播属性的值为SUPPORTS
3. 只读属性(readOnly)
  1. 针对于只进行查询操作的业务方法,可以加入只读属性,提供运行效率
  2. 默认值:false
4. 超时属性(timeout)
  1. 指定了事务等待的最长时间
  2. 1. 为什么事务进行等待?
  3. 当前事务访问数据时,有可能访问的数据被别的事务进行加锁的处理,那么此时本事务就必须进行等待。
  4. 2. 等待时间
  5. 3. 如何应用 @Transactional(timeout=2)
  6. 4. 超时属性的默认值 -1
  7. 最终由对应的数据库来指定
5. 异常属性
  1. Spring事务处理过程中
  2. 默认 对于RuntimeException及其子类 采用的是回滚的策略
  3. 默认 对于Exception及其子类 采用的是提交的策略
  4. rollbackFor = {java.lang.Exception,xxx,xxx}
  5. noRollbackFor = {java.lang.RuntimeException,xxx,xx}
  6. @Transactional(rollbackFor = {java.lang.Exception.class},noRollbackFor = {java.lang.RuntimeException.class})
  7. 建议:实战中使用RuntimeExceptin及其子类 使用事务异常属性的默认值
4. 事务属性常见配置总结
  1. 1. 隔离属性 默认值
  2. 2. 传播属性 Required(默认值) 增删改 Supports 查询操作
  3. 3. 只读属性 readOnly false 增删改 true 查询操作
  4. 4. 超时属性 默认值 -1
  5. 5. 异常属性 默认值
  6. 增删改操作 @Transactional
  7. 查询操作 @Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
5. 基于标签的事务配置方式(事务开发的第二种形式)
  1. 基于注解 @Transaction的事务配置回顾
  2. <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
  3. <property name="userDAO" ref="userDAO"/>
  4. </bean>
  5. <!--DataSourceTransactionManager-->
  6. <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  7. <property name="dataSource" ref="dataSource"/>
  8. </bean>
  9. @Transactional(isolation=,propagation=,...)
  10. public class UserServiceImpl implements UserService {
  11. private UserDAO userDAO;
  12. <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
  13. 基于标签的事务配置
  14. <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
  15. <property name="userDAO" ref="userDAO"/>
  16. </bean>
  17. <!--DataSourceTransactionManager-->
  18. <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  19. <property name="dataSource" ref="dataSource"/>
  20. </bean>
  21. 事务属性
  22. <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
  23. <tx:attributes>
  24. <tx:method name="register" isoloation="",propagation=""></tx:method>
  25. <tx:method name="login" .....></tx:method>
  26. 等效于
  27. @Transactional(isolation=,propagation=,)
  28. public void register(){
  29. }
  30. </tx:attributes>
  31. </tx:advice>
  32. <aop:config>
  33. <aop:pointcut id="pc" expression="execution(* com.baizhiedu.service.UserServiceImpl.register(..))"></aop:pointcut>
  34. <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
  35. </aop:config>
  • 基于标签的事务配置在实战中的应用方式

    1. <bean id="userService" class="com.baizhiedu.service.UserServiceImpl">
    2. <property name="userDAO" ref="userDAO"/>
    3. </bean>
    4. <!--DataSourceTransactionManager-->
    5. <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    6. <property name="dataSource" ref="dataSource"/>
    7. </bean>
    8. 编程时候 service中负责进行增删改操作的方法 都以modify开头
    9. 查询操作 命名无所谓
    10. <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager">
    11. <tx:attributes>
    12. <tx:method name="register"></tx:method>
    13. <tx:method name="modify*"></tx:method>
    14. <tx:method name="*" propagation="SUPPORTS" read-only="true"></tx:method>
    15. </tx:attributes>
    16. </tx:advice>
    17. 应用的过程中,service放置到service包中
    18. <aop:config>
    19. <aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut>
    20. <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    21. </aop:config>

Spring一套全通4—持久层整合的更多相关文章

  1. Spring一套全通—工厂

    百知教育 - Spring系列课程 - 工厂 第一章 引言 1. EJB存在的问题 2. 什么是Spring Spring是一个轻量级的JavaEE解决方案,整合众多优秀的设计模式 轻量级 1. 对于 ...

  2. 第五章 征服数据库(Spring对DB的使用)——开发持久层

    本章内容: 定义Spring对数据库访问的支持 配置数据库资源 使用Spring的JDBC模板 在几乎所有的企业级应用中,都需要构建数据持久层.现在意义上的数据持久层是指把对象或者数据保存到数据库中, ...

  3. 【Spring】对持久层技术的整合

    一.持久层技术 二.JdbcTemplate 开发步骤: 1. 导入相关的jar包 2. 配置连接池(数据源) 将参数设置到属性文件中: 3. 创建表 4. 编写实体类 5. Dao层实现 5.1 继 ...

  4. 【Spring 持久层】Spring 与 Mybatis 整合

    持久层整合总述 1.Spring 框架为什么要与持久层技术进行整合? JavaEE开发需要持久层进行数据库的访问操作 JDBC.Hibernate.MyBatis 进行持久开发过程存在大量的代码冗余 ...

  5. Mybatis(一):手写一套持久层框架

    作者 : 潘潘 未来半年,有幸与导师们一起学习交流,趁这个机会,把所学所感记录下来. 「封面图」 自毕业以后,自己先创业后上班,浮沉了近8年,内心着实焦躁,虽一直是走科班路线,但在技术道路上却始终没静 ...

  6. 基于 Spring 和 iBATIS 的动态可更新多数据源持久层

    前言 我们时常会遇到一些 web 项目,需要从不同的数据源中抓取数据来进行分析,而这些数据源是有可能变化的,需要用户来进行动态的维护和添加.可是,大多数的 web 程序使用了应用服务器或者容器中间件来 ...

  7. SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装

    SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...

  8. Spring集成MyBatis持久层框架

    一.MyBatis介绍 MyBatis 是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,可以使用简单的XML ...

  9. 为caffe添加最简单的全通层AllPassLayer

    参考赵永科的博客,这里我们实现一个新 Layer,名称为 AllPassLayer,顾名思义就是全通 Layer,“全通”借鉴于信号处理中的全通滤波器,将信号无失真地从输入转到输出. 虽然这个 Lay ...

随机推荐

  1. Java基础系列(27)- 什么是方法

    何谓方法 System.out.println();它是什么呢 # System:类 # out:对象 # println():方法 Java方法是语句的集合,它们在一起执行一个功能 方法是解决一类问 ...

  2. Shell系列(15)- 数值运算方法

    数值运算-方法1 declare -i [root@localhost ~]# aa=11 [root@localhost ~]# aa=22   #给变量aa和bb赋值 [root@localhos ...

  3. postgresql批量插入copy_from()的使用

    在批量插入postgresql时想使用同Mysql的语法时发现并不能使用: cursor.executemany("INSERT INTO persons VALUES (%d, %s, % ...

  4. 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段 | 百篇博客分析OpenHarmony源码 | v71.01

    子曰:"我非生而知之者,好古,敏以求之者也." <论语>:述而篇 百篇博客系列篇.本篇为: v71.xx 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段 ...

  5. 鸿蒙内核源码分析(时间管理篇) | 谁是内核基本时间单位 | 百篇博客分析OpenHarmony源码 | v35.02

    百篇博客系列篇.本篇为: v35.xx 鸿蒙内核源码分析(时间管理篇) | 谁是内核基本时间单位 | 51.c.h .o 本篇说清楚时间概念 读本篇之前建议先读鸿蒙内核源码分析(总目录)其他篇. 时间 ...

  6. Jmeter压测学习6---登录参数CSV

    前言 我们在压测登录接口的时候,如果只用一个账号去设置并发压测,这样的结果很显然是不合理的,一个用户并发无法模拟真实的情况.如果要压测登录接口,肯定得准备几百,甚至上千的账号去登录,测试的结果才具有可 ...

  7. Python 文件路径设置

    菜鸟教程:https://www.runoob.com/python/os-chdir.html Python官方文件教程:https://docs.python.org/3.9/library/os ...

  8. Markdown 相关语法

    MD语法博客:https://www.cnblogs.com/Jetictors/p/8506757.html 公式 \[\mathbf{x}_{t}=\Phi_{t}\left(\mathbf{x} ...

  9. 【C++ Primer Plus】编程练习答案——第7章

    1 double ch7_1_harmonicaverage(double a, double b) { 2 return 2 / (1 / a + 1 / b); 3 } 4 5 void ch7_ ...

  10. 模仿ToDoList

    1.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...