专栏首页SpringBoot图文教程「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-20200603111758115

2.3 整合实战

准备工作,添加 mybatis-spring

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

初版配置:

<!-- 读取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>

最终配置:

<!-- 读取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依赖 <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 <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 <!-- 读取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. 实现 class XxxServiceImpl implements XxxService{ private XxxMapper xxxMapper; public void setXxxMapper(XxxMapper mapper){ this.xxxMapper = mapper; } 业务方法... }
  6. test
  7. action+jsp 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对象) <!-- 定义目标类对象--> <bean id="userService" class="com.bcl.service.impl.UserServiceImpl"> <property name="userMapper" ref="userMapper"/> </bean>
  2. 定义增强类,Spring内置有事务控制的增强 DataSourceTransactionManager事务增强类
  3. 配置增强类 <!-- 配置增强类:事务管理器--> <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. 编织组装 <!-- 定义切入点 编织组装 --> <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. 觉得不错的话,也可以关注 编程鹿 的个人公众号看更多文章和讲解视频(感谢大家的鼓励与支持🌹🌹🌹)

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

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

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

    鹿老师的Java笔记
  • SpringBoot图文教程12—SpringData Jpa的基本使用

    在之前的文章中介绍过了Mybatis,MBG 和 MybatisPlus 等一系列Mybatis相关的技术,有朋友在评论区提到了Jpa,也评论了SpringDa...

    鹿老师的Java笔记
  • SpringBoot图文教程7—SpringBoot拦截器的使用姿势这都有

    拦截器是Spring中的概念,和过滤器类似,可以对用户请求进行拦截过滤处理。但是相对于过滤器而言,拦截器要的控制更加的细节,拦截器可以在三个地方进行执行。

    鹿老师的Java笔记
  • 「2020最新」Spring最易学习教程 4—整合Mybatis 事务控制

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

    鹿老师的Java笔记
  • Spring Cloud Edgware新特性之九:Sleuth使用MQ方式整合Zipkin

    众所周知,Spring Cloud Sleuth有两种方式整合Zipkin: HTTP直连Zipkin方式 MQ方式,架构如下图: ? Spr...

    用户1516716
  • 【leetcode刷题】T210-最大交换

    https://leetcode-cn.com/problems/maximum-swap/

    木又AI帮
  • Zipkin全链路监控

    虽然在SpringBoot2.0以后官方不推荐我们自定义Zipkin服务端,而是使用官方提供的jar包。但是作为开发者来说,如果不能去看一看源码,修改一些自定义...

    Java学习录
  • SSH构造struts2项目

    ydymz
  • RocketMQ系列(一)基本概念

    RocketMQ是阿里出品的一款开源的消息中间件,让其声名大噪的就是它的事务消息的功能。在企业中,消息中间件选择使用RocketMQ的还是挺多的,这一系列的文章...

    小忽悠
  • RocketMQ系列(一)基本概念

    RocketMQ是阿里出品的一款开源的消息中间件,让其声名大噪的就是它的事务消息的功能。在企业中,消息中间件选择使用RocketMQ的还是挺多的,这一系列的文章...

    小忽悠

扫码关注云+社区

领取腾讯云代金券