模仿與學習MyBatis - 1.1 綜述:MyBatis核心功能

本文收錄於模仿與學習MyBatis系列


系列的開始

在本系列的一開始,我還不打算記錄一個非常宏大的MyBatis世界的整體結構。原因很簡單,包括我在內的大部分初學者,在剛接觸這類框架前,都是一頭霧水的。像我當初去請教一些前輩,“MyBatis要怎麼學呢?”直接被一句“去把源碼和官方文檔看一遍”給堵了回來——那十幾個大模塊以及之間的交互,看了就讓人厭煩了,我還不懂MyBatis是什麼的情況下,又怎麼能體會這些架構和功能的意義和精妙呢?我想這種回答是不夠負責任的。
如果換作是我,以自己的學習經歷來說,我覺得不妨從最關心、最基礎的部分說起,比如:

一、 MyBatis拿來幹什麼?

MyBatis核心功能可以總結爲:當我調用一個Java方法時,等於在指定的數據庫,執行若干sql操作,並把執行結果轉爲一個Java類。 這段話可能有點繞 ,具體含義可以參考下面代碼裏寫的:

public interface BookMapper {
    @Select("select * from book where author=#{name}")
    List<Book> findByName(String name);

    @Delete("delete from book where author=#{name}")
    int deleteByName(String name);
}

public void test(SqlSession session) {
    BookMapper mapper = session.getMapper(BookMapper.class);
    List<Book> book = mapper.findByName("test");
}

注意test(session)方法。我們在MyBatis框架中,直接從一個接口(注意這是一個接口不是類),生成了一個可用的對象mapper。並且當我們執行mapper的方法findByName(“Mark”)時,等同於在我們的數據庫裏執行了select * from book where author=Mark,把book表中author=Mark的書全部返回了出來,返回了一個List。(此處Book類裏的成員變量需與數據庫中的book一一對應)

二、怎麼執行sql語句

當我們要執行sql語句的時候,在Java代碼中到底做了什麼呢?

  1. 首先需要連接到指定的數據庫(得到Connection
  2. 從連接中獲取sql容器(得到Statement
  3. 用此容器執行一條sql語句(得到ResultSet

    結果的ResultSet中可以取出表裏的列名與對應的值。由於一共只有三個操作,就列一下代碼吧:

Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);

三、Session又是什麼

經常在使用框架時看到Session,那這個Session又是個什麼東西呢?先看下圖:

這裏寫圖片描述

當我們通過數據庫信息(DataSource)訪問數據庫,並從數據庫取到一個連接(Connection)出來時,業務的執行還沒有真正開始。我們需要使用這個連接,執行一系列的sql語句,希望回滾、提交等等。而且最最重要的是,通常數據庫的返回值是這樣的:
這裏寫圖片描述
而實際上我想要的是一個這樣的Java類:
這裏寫圖片描述
那麼誰來負責:使用連接,執行sql,執行事務,把結果轉爲Java類等工作呢?在常規的這類框架中,我們把這一系列操作,全部抽象到與一個類對應,這個類的開始就是一切的開始,這個類的結束就是這一切的結束。通常我們將這個類稱爲Session,一個Session僅擁有一個對應的數據庫連接。


四、MyBatis中的Session

  <T> T selectOne(String statement);
  <T> T getMapper(Class<T> type);

雖然打開MyBatis的SqlSession接口,可以看到非常多方法,但歸納出來其實只有以上兩種。一是可以直接代入sql執行,另一種用法如下:

public interface BookMapper {
    @Select("select * from book where name=#{name}")
    Book findByName(String name);
}

public void test(SqlSession session) {
    // 在session中生成一個可用的類
    BookMapper mapper = session.getMapper(BookMapper.class);
    Book book = mapper.findByName("test");
}

可以看到,這裏使用一個Session與一個Mapper.class,生成了一個可用的mapper對象,只要mapper對象執行方法,就對應的執行了方法上的註解內容。
它是怎樣實現的呢?其實非常簡單,生成mapper對象時,在它裏面存了session值。這樣在執行mapper.findByName("xxx")時,實際上調用的是session.selectOne("select * from book where name=xxx"),大體流程如下圖:
這裏寫圖片描述

我們可以發現,MyBatis的核心功能其實不難。無非就是動態代理和jdbc操作,在後續的文章裏會逐個解釋這些概念,但在下一篇中,先實現一個基本的Session類。

下一篇:模仿與學習MyBatis - 1.2 DataSource與Session

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章