MyBatis完全使用指南

MyBatis

MyBatis作為一個輕量的SQL映射框架修档,確實很簡單,但是知識點挺多祝钢,實際使用中還是會有時想不起來某個標簽該怎么寫比规,所以整理了這篇文章,以備查詢拦英。由于MyBatis如此簡單蜒什,使得這一篇文章基本把實際使用中常碰到的事情都涵蓋了,包括:

  1. MyBatis中的一些概念
  2. MyBatis包含的內(nèi)容
  3. SQL映射
  4. 動態(tài)SQL

一疤估、 MyBatis中的一些概念

MyBatis的架構(gòu)

1. MyBatis是個什么東西

在使用MyBatis的項目里灾常,日志中往往會出現(xiàn)很多拼接SQL語句的log,這其實說明了MyBatis底層還是使用JDBC來實現(xiàn)的铃拇。在JDBC的基礎上钞瀑,為了性能考慮,所有的語句都是基于SqlSession慷荔。顧名思義雕什,維護這個類的實例其實就是維護了一個對于某個數(shù)據(jù)庫的連接的會話,在這個會話里可以有緩存啊什么之類的显晶。

2. mapper接口是怎么映射成SQL語句的

目前多數(shù)開發(fā)者還是會使用XML來進行MyBatis的配置贷岸,包括MyBatis的核心配置和SQL映射配置。其實和注解一樣磷雇,XML本身只不過是一個元數(shù)據(jù)的載體偿警,最終起作用的還是MyBatis的核心類。其中有這樣幾個比較重要的:

  1. SqlSessionFactoryBuilder倦春,用來創(chuàng)建SqlSessionFactory的實例户敬,之后就沒有用了落剪,其生命周期只是在初始化的時候有作用睁本。
  2. SqlSessionFactory,MyBatis最基礎的類忠怖,用來創(chuàng)建會話(即SqlSession的實例)呢堰,其生命周期與整個系統(tǒng)的生命周期相同,在系統(tǒng)運行的任何時候都可以使用它查詢到當前數(shù)據(jù)庫的配置信息等凡泣。
  3. SqlSession枉疼,真正的和數(shù)據(jù)庫之間的會話皮假,線程不安全,所以其生命周期和使用它的線程相同骂维。
  4. 各種Mapper惹资,承載了實際的業(yè)務邏輯,其生命周期比較短航闺,由SqlSession創(chuàng)建褪测。

3. Spring環(huán)境中MyBatis的初始化過程

實際情況中MyBatis往往是在Spring的環(huán)境中使用的,MyBatis本身并不依賴Spring潦刃,但是使用Spring可以極大的提高開發(fā)效率侮措,由于Spring進行了控制反轉(zhuǎn),所以其中MyBatis的初始化過程和正常過程稍稍有些不同:

  1. Spring發(fā)現(xiàn)需要創(chuàng)建SqlSessionFactory實例乖杠,會在classpath下找到MyBatis的核心配置文件分扎,使用它來初始化一個SqlSessionFactory實例。當然胧洒,這一步完全可以使用代碼來完成畏吓,或者使用注解,就更加清晰明了卫漫。
  2. 往往mapper類也會作為bean注入到代碼中去的庵佣,那么Spring會使用上一步中的SqlSessionFactory實例來創(chuàng)建SqlSession的實例。
  3. 然后再使用SqlSession嘗試創(chuàng)建各個mapper對象汛兜。
  4. 于此同時巴粪,MyBatis會掃描classpath下的mapper映射XML文件(此路徑可以自定義),對于每一個mapper接口粥谬,它的「類全名」會作為命名空間肛根,來和映射文件中的mapper標簽進行匹配。
  5. 對于每一個映射文件中的一個執(zhí)行語句標簽(如select漏策、delete)派哲,MyBatis會把他們映射到SqlSession的方法上,創(chuàng)建mapper接口的一個實現(xiàn)類掺喻。
  6. 如果mapper接口和其映射文件一一匹配芭届,則bean創(chuàng)建成功。

二感耙、MyBatis包含的內(nèi)容

MyBatis本身就是一個簡單的ORM框架褂乍,提供了SQL語句到方法、關系型數(shù)據(jù)表到對象的映射即硼。實際使用中與開發(fā)者相關的有兩個東西:

  1. MyBatis核心配置
    緩存逃片、數(shù)據(jù)源、日志等關系到MyBatis其本身行為的一些配置只酥。
  2. mapper接口的映射
    針對于具體業(yè)務邏輯的SQL映射褥实。

三呀狼、SQL映射

MyBatis也可以使用注解來實現(xiàn)映射,對于簡單的語句损离,使用注解可能會更加清晰簡單哥艇,但是其真正強大的地方還是XML。

1. select

屬性 描述
id 此命名空間內(nèi)的標識符
parameterType 參數(shù)的類的全名或者alias僻澎,可選她奥。默認為空。
parameterMap Deprecated
resultType 返回結(jié)果的類型全名或alias怎棱,如果結(jié)果是集合哩俭,此類型表示的是集合的成員類型。
resultMap 使用指定的resultMap來映射結(jié)果集拳恋。resultMap 和 resultType只能二選一凡资。
flushCache 如果為true,每次調(diào)用谬运,一級緩存和二級緩存都會回寫隙赁。select語句中默認為false。
useCache 如果為true梆暖,結(jié)果將在二級緩存中緩存伞访。select語句中默認為true
timeout 設置超時,若超時則拋出異常轰驳。
fetchSize 嘗試在獲取數(shù)據(jù)時分批獲取厚掷。
statementType STATEMENT,PREPARED或者CALLABLE. 分別對應JDBC中的Statement级解,PreparedStatement和CallableStatement respectively冒黑。默認PREPARED.
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE或者SCROLL_INSENSITIVE勤哗。默認為空抡爹。
databaseId 使用特定的databaseIdProvider
resultOrdered 嵌套查詢時使用。
resultSets 多返回集合時使用芒划。

2. 修改語句(insert冬竟,update,DELETE)

這3種語句的屬性基本和上邊select的一樣民逼,INSERT和UPDATE的語句有幾個特殊的屬性如下:

屬性 描述
useGeneratedKeys 將使用JDBC的getGeneratedKeys方法來獲取主鍵的值泵殴。默認為false。
keyProperty 主鍵缴挖。MyBatis會將生成的主鍵賦給這個列袋狞。聯(lián)合主鍵使用逗號隔開。
keyColumn 特定數(shù)據(jù)庫需要使用映屋。

3. SQl語句段(sql標簽)

<sql>標簽可以定義一段sql語句段苟鸯,可以在其他語句中引入使用。sql標簽可以包含參數(shù)棚点。示例如下:

<sql id="userColumns">${alias}.id,${alias}.username,${alias}.password </sql>
<select id="selectUsers" resultType="map">
    select
        <include refid="userColumns"><property name="alias" value="t1"/></include>,
        <include refid="userColumns"><property name="alias" value="t2"/></include>
    from some_table t1
        cross join some_table t2
</select>

參數(shù)(property)也可以在refid或者include進來的sql中使用早处。示例如下:

<sql id="sometable">
    ${prefix}Table
</sql>
<sql id="someinclude">
    from
    <include refid="${include_target}"/>
</sql>
<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include>
</select>

4. #{}${}的區(qū)別

  1. #{}在底層實現(xiàn)上使用?做占位符來生成PreparedStatement,然后將參數(shù)傳入瘫析,大多數(shù)情況都應使用這個砌梆,它更快、更安全贬循。

  2. ${}將傳入的數(shù)據(jù)直接顯示生成在sql中咸包。如:order by ${user_id},如果傳入的值是111,那么解析成sql時的值為order by 111, 如果傳入的值是id杖虾,則解析成的sql為order by id.

5. 類型別名

什么地方都少不了這種小技巧烂瘫,可以讓你少打很多字。

    <typeAlias type="com.someapp.model.User" alias="User"/>

6. ResultMap

官方文檔上說這個特性是整個MyBatis中最強大的特性(沒有之一)奇适。其實它做的就是映射結(jié)果集坟比。

MyBatis底層使用JDBC,所以查詢出來的結(jié)果是ResultSet嚷往,如果resultType是一個對象葛账,MyBatis底層就會創(chuàng)建一個resultMap,并根據(jù)字段名一一對應上這個對象皮仁。如果你有一個查詢籍琳,它的結(jié)果集非常復雜,可以使用resultMap來做映射贷祈。

cache和cach-ref

使用cache標簽在映射文件內(nèi)(某命名空間內(nèi))實現(xiàn)二級緩存巩割,其所有屬性都有缺省值,所以單單一個標簽就可以生效付燥。cach-ref可以在兩個映射文件之間共享緩存

    <cache
        eviction="LRU"http://緩存移除策略
        flushInterval="60000"http://默認不設置宣谈,不定時刷新
        size="1024"
        readOnly="false"/>

四、動態(tài)SQL

1. if

條件判斷键科,參數(shù)為test

2. choose (嵌套when闻丑,otherwise)

多選一,參數(shù)為test

3. trim (where勋颖,set)

  • trim標簽可以定制其他標簽嗦嗡,并且去頭去尾;
  • where標簽會自動生成where語句饭玲,并且可以去除頭部的and或者or侥祭;
  • set標簽可以自動生成set語句,并且可以去除尾部的逗號。

4. foreach

循環(huán)集合輸出矮冬,可以循環(huán)數(shù)組谈宛,Iterable對象,或者Map胎署,如果是Map吆录,則index會是key。

<foreach item="item" index="index" collection="list"
  open="(" separator="," close=")">
    #{item}
</foreach>

5. bind

聲明一個使用OGNL表達式生成的變量琼牧,在sql語句中使用恢筝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市巨坊,隨后出現(xiàn)的幾起案子撬槽,更是在濱河造成了極大的恐慌,老刑警劉巖趾撵,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侄柔,死亡現(xiàn)場離奇詭異,居然都是意外死亡鼓寺,警方通過查閱死者的電腦和手機勋拟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妈候,“玉大人敢靡,你說我怎么就攤上這事】嘁” “怎么了啸胧?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長幔虏。 經(jīng)常有香客問我纺念,道長,這世上最難降的妖魔是什么想括? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任陷谱,我火速辦了婚禮,結(jié)果婚禮上瑟蜈,老公的妹妹穿的比我還像新娘烟逊。我一直安慰自己,他們只是感情好铺根,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布宪躯。 她就那樣靜靜地躺著,像睡著了一般位迂。 火紅的嫁衣襯著肌膚如雪访雪。 梳的紋絲不亂的頭發(fā)上详瑞,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音臣缀,去河邊找鬼坝橡。 笑死,一個胖子當著我的面吹牛肝陪,可吹牛的內(nèi)容都是我干的驳庭。 我是一名探鬼主播刑顺,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼氯窍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹲堂?” 一聲冷哼從身側(cè)響起狼讨,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柒竞,沒想到半個月后政供,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡朽基,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年布隔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稼虎。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡衅檀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出霎俩,到底是詐尸還是另有隱情哀军,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布打却,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茅糜。R本人自食惡果不足惜莺葫,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捌肴。 院中可真熱鬧蹬叭,春花似錦、人聲如沸哭靖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽试幽。三九已至筝蚕,卻和暖如春卦碾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背起宽。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工洲胖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坯沪。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓绿映,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腐晾。 傳聞我的和親對象是個殘疾皇子叉弦,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容