MyBatis是第一個支持自定義SQL、存儲過程和高級映射的類持久框架。MyBatis消除了大部分JDBC的樣板代碼、手動設置參數以及檢索結果。MyBatis可以支持簡單的XML和註解配置規則。使Map接口和POJO類映射到數據庫字段和記錄。java
下面咱們經過一個簡單的項目搭建來帶你認識一下MyBatis的使用和一些核心組件的講解。mysql
爲了快速構建一個MyBatis項目,咱們採用SpringBoot快速搭建的方式。搭建好後在對應的pom.xml下添加以下的maven依賴,主要做用在於引入mybatis一些jar包和類庫sql
主要分爲四個步驟:數據庫
config.properties
數據庫驅動等配置mybatis-config.xml
,引入數據庫驅動,映射Mapper類<!-- mybatis 核心依賴--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!-- 數據庫驅動包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> </dependency> <!-- 單元測試包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
爲了便於更好的說明文章的主旨,這裏就不貼出所有代碼了,會貼出核心代碼部分編程
編寫對應的POJO類和接口式編程Mapper類,這裏咱們以部門業務邏輯爲例,構建一個部門類,有三個屬性即部門編號、部門名稱、位置,下面是部分代碼:緩存
Dept.javamybatis
package com.mybatis.beans; public class Dept { private Integer deptNo; private String dname; private String loc; public Dept() {} public Dept(Integer deptNo, String dname, String loc) { this.deptNo = deptNo; this.dname = dname; this.loc = loc; } get and set... }
MyBatis最核心的功能之一就是接口式編程,它可讓咱們編寫Mapper接口和XML文件,從而把參數和返回結果映射到對應的字段中。架構
DeptDao.javaapp
package com.mybatis.dao; public interface DeptDao { // 經過部門名稱查詢 public Dept findByDname(String Dname); // 經過部門編號查詢 public Dept findByDeptNo(Integer deptno); }
在/resources 下新建com.mybatis.dao 包,在其內編寫對應的XML配置文件,此XML配置文件和Mapper互爲映射關係。
<mapper namespace="com.mybatis.dao.DeptDao" > <sql id="DeptFindSql"> select * from dept </sql> <select id="findByDeptNo" resultType="com.mybatis.beans.Dept"> <include refid="DeptFindSql"></include> where deptno = #{deptNo} </select> <select id="findByDname" resultType="com.mybatis.beans.Dept"> <include refid="DeptFindSql"></include> where dname = #{dname} </select> </mapper>
上述的
就是映射到Mapper接口類的命名空間
<select>
標籤用於編寫查詢語句,查詢完成以後須要把結果映射到對象或者map集合等,須要用到resultType
屬性指定對應的結果集。上述採用了
和 的標籤寫法,爲了方便的映射到實體類,須要修改的話統一修改便可,下降耦合性。
構建完成基礎的SQL語句和映射以後,下面來構建MySQL數據庫驅動,在/resources 下建立config.properties
類
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=123456
在/resources 下編寫MyBatis核心配置文件myBatis-config.xml
,引入數據庫驅動,映射Mapper類
<configuration> <!-- 設置導入外部properties文件位置 --> <properties resource="config.properties"></properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <package name="com.mybatis.dao"/> </mappers> </configuration>
configuration 標籤很像是Spring 中的 beans 標籤或者是基於註解的配置@Configuration,也就是MyBatis的核心配置環境,使用 properties 標籤引入外部屬性環境,也就是數據庫驅動配置,使用 mappers 映射到Mapper所在的包,這裏指的就是DeptDao.java所在的包。
在test包下面新建一個Junit單元測試類,主要流程以下:
MyBatisTest.java 代碼以下:
public class MyBatisTest { private SqlSession sqlSession; /** * 讀取配置文件,建立SQL工廠,打開會話 * @throws Exception */ @Before public void start() throws Exception{ InputStream is = Resources.getResourceAsStream("myBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); sqlSession = factory.openSession(); } /** * 銷燬會話 */ @After public void destroy() { if(sqlSession != null){ sqlSession.close(); } } @Test public void test(){ DeptDao deptDao = sqlSession.getMapper(DeptDao.class); Dept dept = deptDao.findByDeptNo(1); System.out.println(dept.getDname()); } }
@Before 和 @After 是junit工具包中的類,@Before在執行@Test 測試其主要業務以前加載,@After 在執行@Test 測試完成以後加載。
總體結構以下:
MyBatis的架構大概是這樣的,最上面是接口層,接口層就是開發人員在Mapper或者是Dao接口中的接口定義,是查詢、新增、更新仍是刪除操做;中間層是數據處理層,主要是配置Mapper -> xml層級之間的參數映射,SQL解析,SQL執行,結果映射的過程。上述兩種流程都由基礎支持層來提供功能支撐,基礎支持層包括鏈接管理,事務管理,配置加載,緩存處理。
在不與Spring 集成的狀況下,使用MyBatis執行數據庫的操做主要以下:
InputStream is = Resources.getResourceAsStream("myBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); sqlSession = factory.openSession();
其中的SqlSessionFactory
,SqlSession
是MyBatis接口的核心類,尤爲是SqlSession,這個接口是MyBatis中最重要的接口,這個接口可以讓你執行命令,獲取映射,管理事務。
在Mybatis初始化過程當中,會加載mybatis-config.xml配置文件、映射配置文件以及Mapper接口中的註解信息,解析後的配置信息會造成相應的對象並保存到Configration對象中。以後,根據該對象建立SqlSessionFactory對象。待Mybatis初始化完成後,能夠經過SqlSessionFactory建立SqlSession對象並開始數據庫操做。
Mybatis實現的動態SQL語句,幾乎能夠編寫出全部知足須要的SQL。
Mybatis中scripting模塊會根據用戶傳入的參數,解析映射文件中定義的動態SQL節點,造成數據庫能執行的sql語句。
SQL語句的執行涉及多個組件,包括MyBatis的四大神器,它們是: Executor
、StatementHandler
、ParameterHandler
、ResultSetHandler
。SQL的執行過程能夠
用下面這幅圖來表示
MyBatis層級結構各個組件的介紹(這裏只是簡單介紹,具體介紹在後面):
該層保護mybatis的基礎模塊,它們爲核心處理層提供了良好的支撐。
(1)反射模塊
Mybatis中的反射模塊,對Java原生的反射進行了很好的封裝,提供了簡易的API,方便上層調用,而且對反射操做進行了一系列的優化,好比,緩存了類的元數據(MetaClass)和對象的元數據(MetaObject),提升了反射操做的性能。
(2)類型轉換模塊
Mybatis的別名機制,是爲了簡化配置文件的,該機制是類型轉換模塊的主要功能之一。類型轉換模塊的另外一個功能是實現JDBC類型與Java類型間的轉換。該功能在SQL語句綁定實參和映射查詢結果集時都會涉及。在SQL語句綁定實參時,會將數據有Java類型轉換成JDBC類型;在映射結果集時,會將數據有JDBC類型轉換成Java類型。
(3)日誌模塊
Java世界裏,有不少優秀的日誌框架,如Log4j、Log4j二、slf4j等。Mybatis除了提供了詳細的日誌輸出信息,還可以集成多種日誌框架,其日誌模塊的主要功能就是集成第三方日誌框架。
(4)資源加載模塊
該模塊主要封裝了類加載器,肯定了類加載器的使用順序,並提供了加載類文件和其它資源文件的功能。
(5) 解析器模塊
該模塊有兩個主要功能:一個是封裝了XPath,爲Mybatis初始化時解析mybatis-config.xml配置文件以及映射配置文件提供支持;另外一個爲處理動態SQL語句中的佔位符提供支持。
(6)數據源模塊
在數據源模塊中,Mybatis自身提供了相應的數據源實現,也提供了與第三方數據源集成的接口。數據源是開發中的經常使用組件之一,不少開源的數據源都提供了豐富的功能,如,鏈接池、檢測鏈接狀態等,選擇性能優秀的數據源組件,對於提供ORM框架以及整個應用的性能都是很是重要的。
(7)事務管理模塊
通常地,Mybatis與Spring框架集成,由Spring框架管理事務。但Mybatis自身對數據庫事務進行了抽象,提供了相應的事務接口和簡單實現。
(8)緩存模塊
Mybatis中有一級緩存和二級緩存,這兩級緩存都依賴於緩存模塊中的實現。可是,須要注意,這兩級緩存與Mybatis以及整個應用是運行在同一個JVM中的,共享同一塊內存,若是這兩級緩存中的數據量較大,則可能影響系統中其它功能,因此須要緩存大量數據時,優先考慮使用Redis、Memcache等緩存產品。
(9)Binding模塊
在調用SqlSession相應方法執行數據庫操做時,須要制定映射文件中定義的SQL節點,若是sql中出現了拼寫錯誤,那就只能在運行時才能發現。爲了能儘早發現這種錯誤,Mybatis經過Binding模塊將用戶自定義的Mapper接口與映射文件關聯起來,系統能夠經過調用自定義Mapper接口中的方法執行相應的SQL語句完成數據庫操做,從而避免上述問題。注意,在開發中,咱們只是建立了Mapper接口,而並無編寫實現類,這是由於Mybatis自動爲Mapper接口建立了動態代理對象。有時,自定義的Mapper接口能夠徹底代替映射配置文件,但好比動態SQL語句啊等,仍是寫在映射配置文件中更好。
相關參考:
mybatis的總體架構 https://my.oschina.net/liuyuantao/blog/1860807
MyBatis框架的使用及源碼分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor
《深刻理解mybatis原理》 MyBatis的架構設計以及實例分析 https://blog.csdn.net/luanlouis/article/details/40422941