MyBatis學習筆記1——MyBatis簡介
什麼是 MyBatis
MyBatis
是一款優秀的持久層框架,它支援定製化 SQL
、儲存過程以及高階對映。MyBatis
避免了幾乎所有的 JDBC
程式碼和手動設定引數以及獲取結果集。MyBatis
可以使用簡單的 XML
或註解來配置和對映原生資訊,將介面和 Java
的 POJOs
(Plain Old Java Objects
,普通的 Java
物件)對映成資料庫中的記錄。
MyBatis
讓程式設計師將主要精力放在SQL
上,通過MyBatis
提供的對映方式,自由靈活生成(半自動化,大部分需要程式設計師編寫SQL
)滿足需要的SQL
語句。
MyBatis
可以將向preparedStatement
MyBatis框架
SqlMapConfig.xml
(是MyBatis
的全域性配置檔案,名稱不固定),配置了資料來源、事務等MyBatis
執行環境,配置對映檔案(配置SQL
語句)。SqlSessionFactory
(會話工廠),根據配置檔案建立工廠。作用:建立SqlSession
。SqlSession
(會話),是一個介面,面向使用者(程式設計師)的介面。作用:操作資料庫(發出SQL增、刪、改、查)。Executor
(執行器),是一個介面(基本執行器、快取執行器)。作用:SqlSession
內部通過執行器操作資料庫mapped statement
(底層封裝物件)。作用:對操作資料庫儲存封裝,包括SQL語句、輸入引數、輸出結果型別。
安裝
要使用 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
配置檔案(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 語句
在上面提到的兩個例子中,一個語句應該是通過 XML
定義,而另外一個則是通過註解定義。
先看 XML
定義這個,事實上 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
介面的方法。
- 名稱空間(
Namespaces
)在之前版本的MyBatis
中是可選的,這樣容易引起混淆因此毫無益處。現在名稱空間則是必須的,且意於簡單地用更長的完全限定名來隔離語句。 - 名稱空間使得你所見到的介面繫結成為可能,儘管你覺得這些東西未必用得上,你還是應該遵循這裡的規定以防哪天你改變了主意。出於長遠考慮,使用名稱空間,並將它置於合適的 Java 包名稱空間之下,你將擁有一份更加整潔的程式碼並提高了
MyBatis
的可用性。
命名解析:為了減少輸入量,MyBatis
對所有的命名配置元素(包括語句,結果對映,快取等)使用瞭如下的命名解析規則:
- 完全限定名(比如“
com.mypackage.MyMapper.selectAllThings
”)將被直接查詢並且找到即用。 - 短名稱(比如“
selectAllThings
”)如果全域性唯一也可以作為一個單獨的引用。如果不唯一,有兩個或兩個以上的相同名稱(比如“com.foo.selectAllThings
”和“com.bar.selectAllThings
”),那麼使用時就會收到錯誤報告說短名稱是不唯一的,這種情況下就必須使用完全限定名。
讓我們再看一遍下面的例子:
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
第二種方法(通過註解定義)有很多優勢,首先它不是基於字串常量的,就會更安全;其次,如果你的 IDE
有程式碼補全功能,那麼你可以在有了已對映 SQL
語句的基礎之上利用這個功能。
對於像 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
的語句對映方式間自由移植和切換。