Mybatis基礎

来源:http://www.cnblogs.com/niejunlei/archive/2017/03/14/6548087.html
-Advertisement-
Play Games

官方文檔:http://www.mybatis.org/mybatis-3/getting-started.html 安裝 要使用 MyBatis, 只需將 mybatis-x.x.x.jar 文件置於 classpath 中即可。 如果使用 Maven 來構建項目,則需將下麵的 dependenc ...


官方文檔:http://www.mybatis.org/mybatis-3/getting-started.html

安裝

要使用 MyBatis, 只需將 mybatis-x.x.x.jar 文件置於 classpath 中即可。

如果使用 Maven 來構建項目,則需將下麵的 dependency 代碼置於 pom.xml 文件中:

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

從 XML 中構建 SqlSessionFactory

每個基於 MyBatis 的應用都是以一個 SqlSessionFactory 的實例為中心的。SqlSessionFactory 的實例可以通過 SqlSessionFactoryBuilder 獲得。而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先定製的 Configuration 的實例構建出 SqlSessionFactory 的實例。

從 XML 文件中構建 SqlSessionFactory 的實例非常簡單,建議使用類路徑下的資源文件進行配置。但是也可以使用任意的輸入流(InputStream)實例,包括字元串形式的文件路徑或者 file:// 的 URL 形式的文件路徑來配置。MyBatis 包含一個名叫 Resources 的工具類,它包含一些實用方法,可使從 classpath 或其他位置載入資源文件更加容易。

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

XML 配置文件(configuration XML)中包含了對 MyBatis 系統的核心設置,包含獲取資料庫連接實例的數據源(DataSource)和決定事務作用域和控制方式的事務管理器(TransactionManager)。XML 配置文件的詳細內容後面再探討,這裡先給出一個簡單的示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

當然,還有很多可以在XML 文件中進行配置,上面的示例指出的則是最關鍵的部分。要註意 XML 頭部的聲明,用來驗證 XML 文檔正確性。environment 元素體中包含了事務管理和連接池的配置。mappers 元素則是包含一組 mapper 映射器(這些 mapper 的 XML 文件包含了 SQL 代碼和映射定義信息)。

不使用 XML 構建 SqlSessionFactory

如果你更願意直接從 Java 程式而不是 XML 文件中創建 configuration,或者創建你自己的 configuration 構建器,MyBatis 也提供了完整的配置類,提供所有和 XML 文件相同功能的配置項。

DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

註意該例中,configuration 添加了一個映射器類(mapper class)。映射器類是 Java 類,它們包含 SQL 映射語句的註解從而避免了 XML 文件的依賴。不過,由於 Java 註解的一些限制加之某些 MyBatis 映射的複雜性,XML 映射對於大多數高級映射(比如:嵌套 Join 映射)來說仍然是必須的。有鑒於此,如果存在一個對等的 XML 配置文件的話,MyBatis 會自動查找並載入它(這種情況下, BlogMapper.xml 將會基於類路徑和 BlogMapper.class 的類名被載入進來)。具體細節稍後討論。

從 SqlSessionFactory 中獲取 SqlSession

既然有了 SqlSessionFactory ,顧名思義,我們就可以從中獲得 SqlSession 的實例了。SqlSession 完全包含了面向資料庫執行 SQL 命令所需的所有方法。你可以通過 SqlSession 實例來直接執行已映射的 SQL 語句。例如:

SqlSession session = sqlSessionFactory.openSession();
try {
  Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
} finally {
  session.close();
}

誠然這種方式能夠正常工作,並且對於使用舊版本 MyBatis 的用戶來說也比較熟悉,不過現在有了一種更直白的方式。使用對於給定語句能夠合理描述參數和返回值的介面(比如說BlogMapper.class),你現在不但可以執行更清晰和類型安全的代碼,而且還不用擔心易錯的字元串字面值以及強制類型轉換。

例如:

SqlSession session = sqlSessionFactory.openSession();
try {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
} finally {
  session.close();
}

現在我們來探究一下這裡到底是怎麼執行的。

探究已映射的 SQL 語句

現在,或許你很想知道 SqlSession 和 Mapper 到底執行了什麼操作,而 SQL 語句映射是個相當大的話題,可能會占去文檔的大部分篇幅。不過為了讓你能夠瞭解個大概,這裡會給出幾個例子。

在上面提到的兩個例子中,一個語句應該是通過 XML 定義,而另外一個則是通過註解定義。先看 XML 定義這個,事實上 MyBatis 提供的全部特性可以利用基於 XML 的映射語言來實現,這使得 MyBatis 在過去的數年間得以流行。如果你以前用過 MyBatis,這個概念應該會比較熟悉。不過 XML 映射文件已經有了很多的改進,隨著文檔的進行會愈發清晰。這裡給出一個基於 XML 映射語句的示例,它應該可以滿足上述示例中 SqlSession 的調用。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

對於這個簡單的例子來說似乎有點小題大做了,但實際上它是非常輕量級的。在一個 XML 映射文件中,你想定義多少個映射語句都是可以的,這樣下來,XML 頭部和文檔類型聲明占去的部分就顯得微不足道了。文件的剩餘部分具有很好的自解釋性。在命名空間“org.mybatis.example.BlogMapper”中定義了一個名為“selectBlog”的映射語句,這樣它就允許你使用指定的完全限定名“org.mybatis.example.BlogMapper.selectBlog”來調用映射語句,就像上面的例子中做的那樣:

Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);

你可能註意到這和使用完全限定名調用 Java 對象的方法是相似的,之所以這樣做是有原因的。這個命名可以直接映射到在命名空間中同名的 Mapper 類,併在已映射的 select 語句中的名字、參數和返回類型匹配成方法。這樣你就可以向上面那樣很容易地調用這個對應 Mapper 介面的方法。不過讓我們再看一遍下麵的例子:

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);

第二種方法有很多優勢,首先它不是基於字元串常量的,就會更安全;其次,如果你的 IDE 有代碼補全功能,那麼你可以在有了已映射 SQL 語句的基礎之上利用這個功能。


提示命名空間的一點註釋

命名空間(Namespaces)在之前版本的 MyBatis 中是可選的,容易引起混淆因此是沒有益處的。現在的命名空間則是必須的,目的是希望能比只是簡單的使用更長的完全限定名來區分語句更進一步。

命名空間使得你所見到的介面綁定成為可能,儘管你覺得這些東西未必用得上,你還是應該遵循這裡的規定以防哪天你改變了主意。出於長遠考慮,使用命名空間,並將它置於合適的 Java 包命名空間之下,你將擁有一份更加整潔的代碼並提高了 MyBatis 的可用性。

命名解析:為了減少輸入量,MyBatis 對所有的命名配置元素(包括語句,結果映射,緩存等)使用瞭如下的命名解析規則。

  • 完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)將被直接查找並且找到即用。
  • 短名稱(比如“selectAllThings”)如果全局唯一也可以作為一個單獨的引用。如果不唯一,有兩個或兩個以上的相同名稱(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那麼使用時就會收到錯誤報告說短名稱是不唯一的,這種情況下就必須使用完全限定名。

對於像 BlogMapper 這樣的映射器類(Mapper class)來說,還有另一招來處理。它們的映射的語句可以不需要用 XML 來做,取而代之的是可以使用 Java 註解。比如,上面的 XML 示例可被替換如下:

package org.mybatis.example;
public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

對於簡單語句來說,註解使代碼顯得更加簡潔,然而 Java 註解對於稍微複雜的語句就會力不從心並且會顯得更加混亂。因此,如果你需要做很複雜的事情,那麼最好使用 XML 來映射語句。

選擇何種方式以及映射語句的定義的一致性對你來說有多重要這些完全取決於你和你的團隊。換句話說,永遠不要拘泥於一種方式,你可以很輕鬆的在基於註解和 XML 的語句映射方式間自由移植和切換。

作用域(Scope)和生命周期

理解我們目前已經討論過的不同作用域和生命周期類是至關重要的,因為錯誤的使用會導致非常嚴重的併發問題。


提示 對象生命周期和依賴註入框架

依賴註入框架可以創建線程安全的、基於事務的 SqlSession 和映射器(mapper)並將它們直接註入到你的 bean 中,因此可以直接忽略它們的生命周期。如果對如何通過依賴註入框架來使用 MyBatis 感興趣可以研究一下 MyBatis-Spring 或 MyBatis-Guice 兩個子項目。


SqlSessionFactoryBuilder

這個類可以被實例化、使用和丟棄,一旦創建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 實例的最佳作用域是方法作用域(也就是局部方法變數)。你可以重用 SqlSessionFactoryBuilder 來創建多個 SqlSessionFactory 實例,但是最好還是不要讓其一直存在以保證所有的 XML 解析資源開放給更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被創建就應該在應用的運行期間一直存在,沒有任何理由對它進行清除或重建。使用 SqlSessionFactory 的最佳實踐是在應用運行期間不要重覆創建多次,多次重建 SqlSessionFactory 被視為一種代碼“壞味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是應用作用域。有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

SqlSession

每個線程都應該有它自己的 SqlSession 實例。SqlSession 的實例不是線程安全的,因此是不能被共用的,所以它的最佳的作用域是請求或方法作用域。絕對不能將 SqlSession 實例的引用放在一個類的靜態域,甚至一個類的實例變數也不行。也絕不能將 SqlSession 實例的引用放在任何類型的管理作用域中,比如 Serlvet 架構中的 HttpSession。如果你現在正在使用一種 Web 框架,要考慮 SqlSession 放在一個和 HTTP 請求對象相似的作用域中。換句話說,每次收到的 HTTP 請求,就可以打開一個 SqlSession,返回一個響應,就關閉它。這個關閉操作是很重要的,你應該把這個關閉操作放到 finally 塊中以確保每次都能執行關閉。下麵的示例就是一個確保 SqlSession 關閉的標準模式:

SqlSession session = sqlSessionFactory.openSession();
try {
  // do work
} finally {
  session.close();
}

在你的所有的代碼中一致性地使用這種模式來保證所有資料庫資源都能被正確地關閉。

映射器實例(Mapper Instances)

映射器是創建用來綁定映射語句的介面。映射器介面的實例是從 SqlSession 中獲得的。因此從技術層面講,映射器實例的最大作用域是和 SqlSession 相同的,因為它們都是從 SqlSession 里被請求的。儘管如此,映射器實例的最佳作用域是方法作用域。也就是說,映射器實例應該在調用它們的方法中被請求,用過之後即可廢棄。並不需要顯式地關閉映射器實例,儘管在整個請求作用域(request scope)保持映射器實例也不會有什麼問題,但是很快你會發現,像 SqlSession 一樣,在這個作用域上管理太多的資源的話會難於控制。所以要保持簡單,最好把映射器放在方法作用域(method scope)內。下麵的示例就展示了這個實踐:

SqlSession session = sqlSessionFactory.openSession();
try {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  // do work
} finally {
  session.close();
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.查看表歷史時刻數據 select * from tab_test AS OF TIMESTAMP to_timestamp('20140917 10:00:00','yyyymmdd hh24:mi:ss'); 2、利用flashback table恢復表到過去某一時刻 alter table ...
  • 最近在做一個RAC升級測試11.2.0.1升級到11.2.0.4,為保證業務能在11.2.0.4版本下正常運行,現需要將資料庫還原至11.2.0.4的單機環境下,資料庫大小為1.04T左右,在這裡總結下步驟。 環境簡介: 1.本次試驗的環境為11.2.0.4的單機環境,存儲為Windows NTFS ...
  • 1.創建DBLINK 2.創建物化視圖日誌(遠程主機操作) 3.創建物化視圖 4.刪除物化視圖和日誌 日誌和物化視圖要分開刪除 5.物化視圖更新 註意: 5.1、如果需要同時刷新多個物化視圖,必須用逗號把各個物化視圖名稱連接起來,並對每個視圖都要指明刷新方式 (f、增量刷新,c、完全刷新,?、強制刷 ...
  • 可以修改類不用重啟Tomcat載入整個項目(手工啟動) 配置reloadable=true(自動重載) 使用Debug模式,前提是僅限於局部修改。(修改類不用重啟--熱載入) Tomcat輕小,而WebLogic、WebSphere對硬體要求比較高,吃記憶體、耗CUP。JBoss類更改不會重啟(傳說, ...
  • 項目中用到了cassandra,用來存儲海量數據,且要有高效的查詢;本博客就進行簡單的介紹和進行一些基本的操作 一、使用場景: 是一款分散式的結構化數據存儲方案(NoSql資料庫),存儲結構比Key-Value資料庫(像Redis)更豐富,但是比Document資料庫(如Mongodb)支持度有限; ...
  • 存儲數據的安全性和可靠性是生產資料庫的關註重點,本文為大家分析了目前採用較多的保障MySQL可用性方案。 ...
  • 運行Hadoop時出現了: 導致運行失敗。仔細分析後發現,這是因為以前192.168.1.201的主機名為master,後來把192.168.1.202改名為master,由於兩台主機的公鑰不一樣,所以提示DNS欺騙(網路中有主機冒充master),或者master的IP地址和公鑰同時改變了。 解決 ...
  • ElasticSearch是文檔型資料庫,索引(Index)定義了文檔的邏輯存儲和欄位類型,每個索引可以包含多個文檔類型,文檔類型是文檔的集合,文檔以索引定義的邏輯存儲模型,比如,指定分片和副本的數量,配置刷新頻率,分配分析器等,存儲在索引中的海量文檔分散式存儲在ElasticSearch集群中。 ... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...