溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

深入淺出MyBatis:MyBatis與Spring集成及實(shí)用場(chǎng)景

發(fā)布時(shí)間:2020-08-11 18:54:00 來(lái)源:網(wǎng)絡(luò) 閱讀:951 作者:情情說(shuō) 欄目:開(kāi)發(fā)技術(shù)

本系列是「深入淺出MyBatis:技術(shù)原理與實(shí)踐」書(shū)籍的總結(jié)筆記。

本篇是「深入淺出MyBatis」系列的最后一篇,主要介紹與Spring的集成,以及工作中的一些實(shí)用場(chǎng)景。

介紹之前,先整體總結(jié)下該系列的內(nèi)容和寫(xiě)作思路。

MyBatis是一個(gè)框架,封裝了數(shù)據(jù)庫(kù)相關(guān)的操作,給我們開(kāi)發(fā)人員帶來(lái)了極大地便利,相對(duì)于Hibernate,有很大的靈活性和擴(kuò)展性,在高并發(fā)高性能應(yīng)用中,這點(diǎn)很重要。

首先介紹了JDBC的規(guī)范,了解我們最原始最熟悉的操作數(shù)據(jù)庫(kù)的方式,MyBatis就是在此基礎(chǔ)上進(jìn)行封裝和抽象。

然后,介紹了MyBatis的特性和核心組件,對(duì)其有個(gè)整體了解。

之后,詳解介紹了MyBatis的配置、映射器,它們是平時(shí)使用、接觸最多的,可以很好的使用MyBatis進(jìn)行開(kāi)發(fā)了。

最后,回顧了反射和動(dòng)態(tài)代理基礎(chǔ),深入分析了MyBatis的解析和運(yùn)行原理,插件及開(kāi)發(fā)過(guò)程,一方面對(duì)MyBatis的核心組件有更深入的了解,一方面可以更好進(jìn)行插件的開(kāi)發(fā),對(duì)sql進(jìn)行統(tǒng)一處理。

實(shí)際使用中,往往會(huì)和Spring集成一起使用,可以減少我們的工作量,通過(guò)本篇的介紹,你會(huì)了解到:

  • Spring的基礎(chǔ)知識(shí):IOC、AOP、事務(wù)管理;
  • MyBatis-Spring應(yīng)用:配置和集成
  • 實(shí)用場(chǎng)景介紹
Spring IOC和AOP

了解Spring的基礎(chǔ),有助于理解集成配置,Spring技術(shù)主要由IOC和AOP兩個(gè)基礎(chǔ)功能構(gòu)成。

IOC

IOC稱(chēng)為控制反轉(zhuǎn),可以這樣理解:以前我們獲取一個(gè)類(lèi)的對(duì)象,都是去new一個(gè),必須確定實(shí)現(xiàn)類(lèi)是哪個(gè),有了IOC,所有配置為Spring管理的對(duì)象都由Spring管理,包括對(duì)象的創(chuàng)建和生命周期,這樣,去獲取類(lèi)的對(duì)象時(shí),不需要顯示指定,由Spring去決定返回哪個(gè)對(duì)象。

這樣,對(duì)象的創(chuàng)建,控制權(quán)由業(yè)務(wù)代碼轉(zhuǎn)向給了Spring,稱(chēng)為控制反轉(zhuǎn)。

AOP

AOP稱(chēng)為面向切面編程,所謂切面,是說(shuō)在正常邏輯中插入一些邏輯處理代碼,比如插入日志記錄、事務(wù)管理等代碼,其中,日志記錄和事務(wù)管理就是切面。Spring AOP可以在不修改原有方法邏輯的情況下,通過(guò)簡(jiǎn)單配置,對(duì)受影響的類(lèi)方法統(tǒng)一插入切面處理代碼。

Spring AOP是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)的,當(dāng)Spring的服務(wù)包含接口描述時(shí),采用JDK動(dòng)態(tài)代理,否則采用CGLIB代理。

最后,簡(jiǎn)單說(shuō)明下AOP相關(guān)的概念,便于理解它的配置:

  • 切入點(diǎn):Spring生成代理對(duì)象后,當(dāng)調(diào)用服務(wù)方法時(shí),會(huì)調(diào)用InvitationHandler的invoke方法,需要攔截哪些方法,進(jìn)行特殊處理呢,這就是切入點(diǎn),Spring可以通過(guò)正則進(jìn)行配置;
  • 切面:上面已經(jīng)介紹了,日志記錄、事務(wù)管理等需要處理的邏輯對(duì)象,就是切面;
  • 連接點(diǎn):它是在程序運(yùn)行中根據(jù)不同的通知來(lái)實(shí)現(xiàn)的程序段,通知包括,前置通知、后置通知、異常后通知、正常返回后通知、環(huán)繞通知;
Spring 事務(wù)管理

在編寫(xiě)業(yè)務(wù)代碼時(shí),一個(gè)業(yè)務(wù)方法可能涉及多張表或多條sql語(yǔ)句,同一條表數(shù)據(jù)可能會(huì)被同時(shí)訪問(wèn),數(shù)據(jù)庫(kù)的事務(wù)控制很重要,通過(guò)Spring AOP和Spring 事務(wù)管理,可以大量減少我們的代碼,對(duì)各種場(chǎng)景的事務(wù)管理也很方便。

事務(wù)隔離級(jí)別
  • 讀未提交:可能出現(xiàn)臟讀問(wèn)題,一個(gè)事務(wù)讀取另一個(gè)事務(wù)未提交的數(shù)據(jù);
  • 讀已提交:可能出現(xiàn)不可重復(fù)讀問(wèn)題,針對(duì)同一條記錄,同一個(gè)事務(wù)前后可能讀取不同的數(shù)據(jù);
  • 可重復(fù)讀:可能出現(xiàn)幻讀問(wèn)題,針對(duì)刪除和插入記錄,同一個(gè)查詢條件,同一個(gè)事務(wù)返回的記錄數(shù)可能不同;
  • 序列化:所有操作會(huì)按順序執(zhí)行;

MySql默認(rèn)隔離級(jí)別為可重復(fù)讀。

傳播行為

傳播行為,是指方法之間的調(diào)用,事務(wù)如何傳遞,在Spring中定義了7種傳播行為,可根據(jù)不同場(chǎng)景進(jìn)行配置,不一一介紹了,舉幾個(gè)說(shuō)明下:

  • PROPAGATION_REQUIRED:如果存在一個(gè)事務(wù),則使用當(dāng)前事務(wù),否則開(kāi)啟一個(gè)事務(wù);
  • PROPAGATION_SUPPORTS:如果存在一個(gè)事務(wù),則支持當(dāng)前事務(wù),否則以非事務(wù)執(zhí)行;
  • PROPAGATION_REQUIRES_NEW:總是開(kāi)啟一個(gè)新的事務(wù),即使有一個(gè)事務(wù)存在;
  • PROPAGATION_NOT_SUPPORTED:總是以非事務(wù)執(zhí)行,掛起已存在的事物;

Spring默認(rèn)的傳播行為為PROPAGATION_REQUIRED。

MyBatis-Spring集成配置

了解了Spring的IOC,進(jìn)行集成配置就比較簡(jiǎn)單了,另外,除了業(yè)務(wù)SQL的編寫(xiě),事務(wù)是很重要的一部分,Spring AOP和事務(wù)管理幫我們解決了。

MyBatis提供了和Spring無(wú)縫對(duì)接的功能,主要通過(guò)mybatis-spring-x.x.x.jar實(shí)現(xiàn),下面說(shuō)下集成配置的過(guò)程:

配置數(shù)據(jù)源

使用c3p0的實(shí)現(xiàn),只要實(shí)現(xiàn)javax.sql.DataSource接口都可以。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${c3p0.driverClass}"></property>
        <property name="jdbcUrl" value="${c3p0.jdbcUrl}"></property>
        <property name="user" value="${c3p0.user}"></property>
        <property name="password" value="${c3p0.password}"></property>
        <property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
        <property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
        <property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
        <property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
</bean>
配置SqlSessionFactory

它是生成SqlSession的,組件提供了org.mybatis.spring.SqlSessionFactoryBean類(lèi)給我們?nèi)ヅ渲谩?/p>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自動(dòng)掃描entity目錄以匹配別名 -->
        <property name="typeAliasesPackage" value="com.xiaomi.kfs.mcc.persistence, com.xiaomi.kfs.authority.core" />
        <!-- 顯式指定Mapper文件位置 -->
        <property name="mapperLocations" value="classpath*:context/mybatis/*Mapper.xml" />
        <!-- 指定mybatis配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>

配置文件mybatis-config.xml前面文章介紹了,就不再次寫(xiě)了。

配置自動(dòng)掃描mapper bean:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.xiaomi.kfs.mcc.persistence,com.xiaomi.kfs.mcc.workorder, com.xiaomi.kfs.authority.core" />
        <property name="annotationClass" value="com.xiaomi.common.annotation.MyBatisRepository" />
</bean>
配置事務(wù)

使用Spring AOP管理事務(wù)。

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- 使用annotation定義事務(wù) @Transactional -->
<tx:annotation-driven transaction-manager="transactionManager" />
使用場(chǎng)景介紹

實(shí)際工作中,可能有很多使用場(chǎng)景,下面會(huì)簡(jiǎn)單介紹些這些場(chǎng)景,說(shuō)明實(shí)現(xiàn)思路。

數(shù)據(jù)庫(kù)BLOB字段讀寫(xiě)

對(duì)于文件,在數(shù)據(jù)庫(kù)中,一般通過(guò)BLOB字段存儲(chǔ),MyBatis提供了BlobTypeHandler進(jìn)行類(lèi)型映射,可以把byte[]類(lèi)型和BLOB類(lèi)型自動(dòng)轉(zhuǎn)換。

但更多的時(shí)候,我們會(huì)把文件專(zhuān)門(mén)存放在一個(gè)文件服務(wù)器中,數(shù)據(jù)庫(kù)存儲(chǔ)文件路徑即可。

批量更新

批量更新有助于提高數(shù)據(jù)庫(kù)性能,可以修改defaultExecutorType,設(shè)置為BATCH,這樣一個(gè)事務(wù)如果有多條sql,只有在commit后才會(huì)發(fā)送SQL到數(shù)據(jù)庫(kù)。

但要注意,如果程序上下文中,依賴插入的數(shù)據(jù)主鍵,可以通過(guò)調(diào)用sqlSession的flushStatements方法主動(dòng)將當(dāng)前緩存的sql發(fā)送給數(shù)據(jù)庫(kù)執(zhí)行。

調(diào)用存儲(chǔ)過(guò)程

MyBatis支持存儲(chǔ)過(guò)程,對(duì)其進(jìn)行了封裝,具體配置過(guò)程在此不做詳細(xì)介紹了。

分表

如果系統(tǒng)數(shù)據(jù)庫(kù)比較大,可通過(guò)分表減少單表的壓力,MyBatis允許把表名作為參數(shù)傳遞到SQL中,很容易實(shí)現(xiàn)。

分頁(yè)

MyBatis具有分頁(yè)功能,通過(guò)RowBounds實(shí)現(xiàn),但它有個(gè)問(wèn)題,會(huì)在一條SQL中查詢所有的結(jié)果,再根據(jù)從第幾條到第幾條取數(shù)據(jù)返回??梢酝ㄟ^(guò)編寫(xiě)一個(gè)插件,重寫(xiě)SQL進(jìn)行分頁(yè),進(jìn)行統(tǒng)一處理。

使用枚舉類(lèi)型

之前文章介紹過(guò),通過(guò)自定義typeHandler可以很容易的實(shí)現(xiàn)。

后續(xù)開(kāi)始閱讀「RabbitMQ實(shí)戰(zhàn):高效部署分布式消息隊(duì)列」,并進(jìn)行總結(jié)和分享。

歡迎掃描下方二維碼,關(guān)注我的個(gè)人微信公眾號(hào) ~

深入淺出MyBatis:MyBatis與Spring集成及實(shí)用場(chǎng)景

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI