「2020最新」Spring最易学习教程 4—整合Mybatis 事务控制

简介: 「2020最新」Spring最易学习教程 4—整合Mybatis 事务控制


0 复习



  1. 代理模式


    代理模式,可以为目标类添加额外功能。


  2. Spring 动态代理



    1. 定义目标类对象
    2. 定义额外功能,增强。实现Spring内置的接口
    3. 配置增强类
    4. 定义切入点
    5. 编织组装

  3. 增强类型



    1. 前置增强 MethodBeforeAdvice
    2. 后置增强 AfterReturningAdvice
    3. 异常增强 ThrowsAdvice
    4. 环绕增强 MethodInterceptor

  4. 切入点表达式



    1. execution(返回值类型 包名.类名.方法名(参数表))



      execution( com.bcl.service..*(..));



    2. args(参数表)


    3. within(全类名)


    4. @annotation(自定义注解)



  5. 事务的隔离级别



1 再谈web.xml


1.1 web.xml中标签的加载顺序


到目前为止web.xml中出现的标签:servlet filter listener context-param


加载顺序,从前到后:



context-param 定义一对键值对数据,通常为listener使用


listener ContextLoaderListener:在web应用启动时执行,创建Spring工厂


filter Struts2Filter:过滤所有请求


servlet



1.2 Servlet的url-pattern的配置方式


Servlet的url-pattern有4种配置格式:



精确匹配 /book/showAllBooks


路径匹配 / /book/


后缀名匹配 .action .do *.jsp


缺省匹配 / 在上面3种都无法匹配的情况下,做默认匹配



优先级从高到低:



1 精确匹配 2 路径匹配 3后缀名匹配 4缺省匹配



注意点:



  1. 同是路径匹配,路径最长者优先
  2. 路径匹配和后缀名匹配不能混淆使用。/book/*.do 错误
  3. 任何时候,无论怎么配置,filter一定优先于servlet

2 Spring整合MyBatis


2.1 MyBatis项目开发步骤



  1. 搭建开发环境



    1. 新建项目


    2. 导入依赖



      数据库驱动依赖:ojdbcx.jar mysql-connector-java.jar


      MyBatis相关的依赖


      servlet+jsp+jstl的依赖


      struts2的依赖


      junit+hutool+druid



    3. 配置文件+工具类



      jdbc.properties


      log4j.properties


      xxxMapper.xml


      mybatis-config.xml


      struts.xml



    4. 配置文件初始化



      web.xml 配置Struts2Filter


      mybatis-config.xml 初始化配置




  2. 建表


  3. 实体


  4. mapper



    1. 接口
    2. 实现:XxxMapper.xml

  5. service



    1. 接口


    2. 实现:



      SqlSession sqlSession = MyBatisUtils.openSession();


      XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);




  6. test


  7. action+jsp


  8. 集成测试



2.2 整合思路


image-20200603111758115image-20200603111758115

2.3 整合实战


准备工作,添加 mybatis-spring


https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!-- 整合spring mybatis的依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.4</version>
</dependency>

初版配置:


https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!-- 读取jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 0 定义一个连接池 -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<!-- 定义SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

    <property name="dataSource" ref="druidDataSource"/>
    <!--
            配置实体类的包名,自动为实体配置短类名的别名
         -->

    <property name="typeAliasesPackage" value="com.bcl.entity"/>
    <property name="mapperLocations">
        <!-- 配置mapper.xml的路径-->
        <list>
            <!--<value>classpath:com/bcl/mapper/UserMapper.xml</value>
                <value>classpath:com/bcl/mapper/StudentMapper.xml</value>
                <value>classpath:com/bcl/mapper/BookMapper.xml</value>-->

            <value>classpath:com/bcl/mapper/*Mapper.xml</value>
        </list>
    </property>
</bean>

<!-- 定义SqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg ref="sqlSessionFactory"/>
</bean>

<!-- 创建 UserMapper实现类对象-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="sqlSessionTemplate" ref="sqlSession"/>
    <property name="mapperInterface" value="com.bcl.mapper.UserMapper"/>
</bean>

<!--<bean id="bookMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionTemplate" ref="sqlSession"/>
        <property name="mapperInterface" value="com.bcl.mapper.BookMapper"/>
    </bean>-->


<bean id="userService" class="com.bcl.service.impl.UserServiceImpl">
    <property name="userMapper" ref="userMapper"/>
</bean>

最终配置:


https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!-- 读取jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 0 定义一个连接池 -->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 定义SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="druidDataSource"/>
        <!--
            配置实体类的包名,自动为实体配置短类名的别名
         -->

        <property name="typeAliasesPackage" value="com.bcl.entity"/>
        <property name="mapperLocations">
            <!-- 配置mapper.xml的路径-->
            <list>                <value>classpath:com/bcl/mapper/*Mapper.xml</value>
            </list>
        </property>
    </bean>
    <!--
        自动创建Mapper实现类对象
        自动扫描basePackage包下的Mapper接口,自动创建Mapper接口的实现类对象

    -->

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--
            mapper实现类对象的id规则:接口名首字母小写
            UserMapper  ==> userMapper
            BookMapper ==> bookMapper
        -->

        <property name="basePackage" value="com.bcl.mapper"/>
    </bean>



    <bean id="userService" class="com.bcl.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"/>
    </bean>

2.4 Spring整合MyBatis项目的开发步骤



  1. 搭建开发环境



    1. 新建web项目


    2. 导入依赖



      jdbc驱动依赖


      mybatis依赖


      struts2依赖


      spring依赖


      spring整合mybaits依赖


      spring整合struts2依赖



      https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>4.3.26.RELEASE</version>
      </dependency>

      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.48</version>
      </dependency>
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.4</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.30</version>
      </dependency>

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.26.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>4.3.26.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.9.5</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>4.3.26.RELEASE</version>
      </dependency>

      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
      </dependency>
      <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>javax.servlet.jsp-api</artifactId>
          <version>2.3.3</version>
      </dependency>
      <dependency>
          <groupId>jstl</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>
      <dependency>
          <groupId>org.apache.struts</groupId>
          <artifactId>struts2-core</artifactId>
          <version>2.3.16.3</version>
      </dependency>

      <!-- 整合spring mybatis的依赖-->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis-spring</artifactId>
          <version>2.0.4</version>
      </dependency>

      <!-- druid的依赖-->
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.14</version>
      </dependency>

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>4.3.26.RELEASE</version>
      </dependency>
       <dependency>
                  <groupId>org.apache.struts</groupId>
                  <artifactId>struts2-spring-plugin</artifactId>
                  <version>2.3.16.3</version>
              </dependency>

    3. 导入配置文件



      jdbc.properties


      log4j.properties


      xxxMapper.xml


      mybatis-config.xml


      struts.xml


      applicationContext.xml



    4. 配置文件初始化


      web.xml


      https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:applicationContext.xml</param-value>
      </context-param>
      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>

      <filter>
          <filter-name>Struts2Filter</filter-name>
          <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>Struts2Filter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

      applicationContext.xml


      https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!-- 读取jdbc.properties-->
      <context:property-placeholder location="classpath:jdbc.properties"/>
      <!-- 0 定义一个连接池 -->
      <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
          <property name="driverClassName" value="${jdbc.driverClassName}"/>
          <property name="url" value="${jdbc.url}"/>
          <property name="username" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
      </bean>

      <!-- 定义SqlSessionFactory-->
      <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

          <property name="dataSource" ref="druidDataSource"/>
          <!--
                  配置实体类的包名,自动为实体配置短类名的别名
               -->

          <property name="typeAliasesPackage" value="com.bcl.entity"/>
          <property name="mapperLocations">
              <!-- 配置mapper.xml的路径-->
              <list>
                  <value>classpath:com/bcl/mapper/*Mapper.xml</value>
              </list>
          </property>
      </bean>

      <!--
              自动创建Mapper实现类对象
              自动扫描basePackage包下的Mapper接口,自动创建Mapper接口的实现类对象

          -->

      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
          <!--
                  mapper实现类对象的id规则:接口名首字母小写
                  UserMapper  ==> userMapper
                  BookMapper ==> bookMapper
              -->

          <property name="basePackage" value="com.bcl.mapper"/>
      </bean>


  2. 建表


  3. 实体


  4. mapper


  5. service



    1. 接口


    2. 实现


      https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;">class XxxServiceImpl implements XxxService{
          private XxxMapper xxxMapper;
          public void setXxxMapper(XxxMapper mapper){
              this.xxxMapper = mapper;
          }
          
          业务方法...
      }


  6. test


  7. action+jsp


    https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;">XxxAction{
        private XxxService xxxService;
        public void setXxxService(XxxService service){
            this.xxxService = service;
        }
        
        服务方法...
    }

  8. 集成测试



3 Spring中事务控制


Spring提供2种控制方式:



  1. 编程式事务控制:在程序中定义事务控制代码。
  2. 声明式事务控制:借助Spring AOP实现,将事务控制的代码定义成功能增强,将增强编织到切点指定的位置(业务层)。

Spring AOP声明式事务控制的步骤:



  1. 定义原始类对象(service对象)


    https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!-- 定义目标类对象-->
    <bean id="userService" class="com.bcl.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"/>
    </bean>

  2. 定义增强类,Spring内置有事务控制的增强


    DataSourceTransactionManager事务增强类


  3. 配置增强类


    https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!-- 配置增强类:事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"/>
    </bean>
    <tx:advice transaction-manager="txManager" id="txAdvice">
        <tx:attributes>
            <!-- login 开启只读事务-->
            <tx:method name="login" read-only="true"/>
            <!-- 其它的方法,都必须开启事务 -->
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

  4. 定义切点


  5. 编织组装


    https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #f8f8f8; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"><!--
            定义切入点
            编织组装
         -->

    <aop:config>
        <aop:pointcut id="servicePointCut" expression="execution( com.bcl.service..*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointCut"/>
    </aop:config>


4 事务详解



  1. read-only="true"


    只读事务,不能执行增删改,但对于查询有性能优化。


  2. timeout 超时机制


    如果超过执行时间,事务自动回滚。默认值-1,表示跟数据库的配置有关。


  3. rollback-for和no-rollback-for


    rollback-for 定义异常类型:事务遇到这种异常会回滚


    no-rollback-for 定义异常类型:事务遇到这种异常不会回滚


    Spring中,rollback-for的默认值是RuntimeException,no-rollback-for的默认值是Exception。


    自定义异常时,发生该异常需要回滚事务,继承RuntimeException


    自定义异常时,发生该异常不需要回滚事务,继承Exception


  4. propagation(传播机制)


    企业开发时,业务复杂时,会出现业务方法调用业务方法的情况。propagation定义了一个业务方法被另外一个业务方法调用时,事务的传播方式。


    常见的事务传播机制:



    REQUIRED 如果外部有事务,加入外部事务,如果没有则新建


    SUPPORTS 如果外部有事务,加入外部事务,如果没有则以无事务的状态运行


    REQUIRES_NEW 无论是否有外部事务,都会新建一个事务



  5. isolation(隔离级别)



    READ_UNCOMMITTED 读未提交


    READ_COMMITTED 读提交 实战时使用


    REPEATABLE_READ 可重复读


    SERIALIZABLE 序列化读




「❤️ 帅气的你又来看了我」


如果你觉得这篇内容对你挺有有帮助的话:



  1. 点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)
  2. 欢迎在留言区与我分享你的想法,也欢迎你在留言区记录你的思考过程。
  3. 觉得不错的话,也可以关注 编程鹿 的个人公众号看更多文章和讲解视频(感谢大家的鼓励与支持🌹🌹🌹)


相关文章
|
4天前
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
12天前
|
Java 开发者 Spring
Spring高手之路24——事务类型及传播行为实战指南
本篇文章深入探讨了Spring中的事务管理,特别是事务传播行为(如REQUIRES_NEW和NESTED)的应用与区别。通过详实的示例和优化的时序图,全面解析如何在实际项目中使用这些高级事务控制技巧,以提升开发者的Spring事务管理能力。
26 1
Spring高手之路24——事务类型及传播行为实战指南
|
13天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
6天前
|
XML Java 数据库连接
Spring中的事务是如何实现的
Spring中的事务管理机制通过一系列强大的功能和灵活的配置选项,为开发者提供了高效且可靠的事务处理手段。无论是通过注解还是AOP配置,Spring都能轻松实现复杂的事务管理需求。掌握这些工具和最佳实践,能
13 3
|
21天前
|
SQL 存储 数据库
深入理解@TableField注解的使用-MybatisPlus教程
`@TableField`注解在MyBatis-Plus中是一个非常灵活和强大的工具,能够帮助开发者精细控制实体类与数据库表字段之间的映射关系。通过合理使用 `@TableField`注解,可以实现字段名称映射、自动填充、条件查询以及自定义类型处理等高级功能。这些功能在实际开发中,可以显著提高代码的可读性和维护性。如果需要进一步优化和管理你的MyBatis-Plus应用程
94 3
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
295 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
24天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
61 2
|
1月前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
69 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
1月前
|
Java 关系型数据库 MySQL
Spring事务失效,我总结了这7个主要原因
本文详细探讨了Spring事务在日常开发中常见的七个失效原因,包括数据库不支持事务、类不受Spring管理、事务方法非public、异常被捕获、`rollbackFor`属性配置错误、方法内部调用事务方法及事务传播属性使用不当。通过具体示例和源码分析,帮助开发者更好地理解和应用Spring事务机制,避免线上事故。适合所有使用Spring进行业务开发的工程师参考。
29 2
|
1月前
|
Java 程序员 Spring
Spring事务的1道面试题
每次聊起Spring事务,好像很熟悉,又好像很陌生。本篇通过一道面试题和一些实践,来拆解几个Spring事务的常见坑点。
Spring事务的1道面试题