天天看點

「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. 實作:

      SqlSession sqlSession = MyBatisUtils.openSession();

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

  6. test
  7. action+jsp
  8. 內建測試

2.2 整合思路

「2020最新」Spring最易學習教程 4—整合Mybatis 事務控制

image-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. 建立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. 導入配置檔案
      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>
                 
      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>
                 
    1. 實作
      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;
          }
          
          業務方法...
      }
                 
  1. 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;
        }
        
        服務方法...
    }
               

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. 覺得不錯的話,也可以關注 程式設計鹿 的個人公衆号看更多文章和講解視訊(感謝大家的鼓勵與支援🌹🌹🌹)