1. 程式人生 > 其它 >5、MyBatis中的設計模式

5、MyBatis中的設計模式

設計模式

我們都知道設計模式分為3類23種設計模式,Mybatis至少用到了以下的設計模式的使用

BUildeer構建者模式

Builder模式,屬於建立類模式它的定義是"將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表 示。”一般來說,如果一個物件的構建比較複雜,超出了建構函式所能包含的範 圍,就可以使用工廠模式和Builder模式,相對於工廠模式會產出一個完整的產品,Builder應用於更加 複雜的物件的構建,甚至只會構建產品的一個部分,直白來說,就是使用多個簡單的物件一步一步構建 成一個複雜的物件

主要步驟:

  • 將需要構建的目標類分成多個部件(電腦可以分為主機、顯示器、鍵盤、音箱等部件);
  • 建立構建類;
  • 依次建立部件;
  • 將部件組裝成目標物件
// 建立目標類物件
public class Computer {
    // 顯示器
    private String displayer;
    // 主機
    private String mainUnit;
    // 滑鼠
    private String mouse;
    // 鍵盤
    private String keyboard;
}
// 建立構建類物件
public class ComputerBuilder {
    Computer computer = new Computer();	
    public void installDisplayer(String displayer) {
        computer.setDisplayer(displayer);
    }
    public void installMainUnit(String mianUnit) {
        computer.setMainUnit(mianUnit);
    }
    public void installMouse(String mouse) {
        computer.setMouse(mouse);
    }
    public void installKeyboard(String keyboard) {
        computer.setKeyboard(keyboard);
    }
    public Computer Builder() {
        return computer;
    }
}
// 將部分類組裝
    public static void main(String[] args) {
        ComputerBuilder computerBuilder = new ComputerBuilder();
        computerBuilder.installDisplayer("顯萬器");
        computerBuilder.installMainUnit("主機");
        computerBuilder.installKeyboard("鍵盤");
        computerBuilder.installMouse("滑鼠");
        Computer computer = computerBuilder.Builder();
        System.out.println(computer);
    }

Mybaits使用的構建者模式

SqlSessionFactory 的構建過程:Mybatis的初始化工作非常複雜,不是隻用一個建構函式就能搞定的。所以使用了建造者模式,使用了 大 量的Builder,進行分層構造,核心物件Configuration使用了 XmlConfigBuilder來進行構造

在Mybatis環境的初始化過程中,SqlSessionFactoryBuilder會呼叫XMLConfigBuilder讀取所有的 MybatisMapConfig.xml 和所有的 *Mapper.xml 檔案,構建 Mybatis 執行的核心物件 Configuration 對 象,然後將該Configuration物件作為引數構建一個SqlSessionFactory物件。

其中 XMLConfigBuilder 在構建 Configuration 物件時,也會呼叫 XMLMapperBuilder 用於讀取 *Mapper 檔案,而XMLMapperBuilder會使用XMLStatementBuilder來讀取和build所有的SQL語句。

在這個過程中,有一個相似的特點,就是這些Builder會讀取檔案或者配置,然後做大量的XpathParser 解析、配置或語法的解析、反射生成物件、存入結果快取等步驟,這麼多的工作都不是一個建構函式所 能包括的,因此大量採用了 Builder模式來解決

SqlSessionFactoryBuilder類根據不同的輸入引數來構建SqlSessionFactory這個工廠物件

工廠模式

在Mybatis中比如SqlSessionFactory使用的是工廠模式,該工廠沒有那麼複雜的邏輯,是一個簡單工廠 模式

簡單工廠模式(Simple Factory Pattern):又稱為靜態工廠方法(Static Factory Method)模式,它屬於創 建型模式。

在簡單工廠模式中,可以根據引數的不同返回不同類的例項。簡單工廠模式專⻔定義一個類來負責建立
其他類的例項,被建立的例項通常都具有共同的父類

Mybatis 體現:

Mybatis中執行Sql語句、獲取Mappers、管理事務的核心介面SqlSession的建立過程使用到了工廠模

式。有一個 SqlSessionFactory 來負責 SqlSession 的建立

SqlSessionFactory
可以看到,該Factory的openSession ()方法過載了很多個,分別支 持autoCommitExecutorTransaction等引數的輸入,來構建核心的SqlSession物件。 在DefaultSqlSessionFactory的預設工廠實現裡,有一個方法可以看出工廠怎麼產出一個產品:

    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;
        try {
            // 獲得 Environment 物件
            final Environment environment = configuration.getEnvironment();
            // 建立 Transaction 物件
            final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            // 建立 Executor 物件
            final Executor executor = configuration.newExecutor(tx, execType);
            // 建立 DefaultSqlSession 物件
            return new DefaultSqlSession(configuration, executor, autoCommit);
        } catch (Exception e) {
            // 如果發生異常,則關閉 Transaction 物件
            closeTransaction(tx); // may have fetched a connection so lets call close()
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
        } finally {
            ErrorContext.instance().reset();
        }
    }

這是一個openSession呼叫的底層方法,該方法先從configuration讀取對應的環境配置,然後初始化 TransactionFactory 獲得一個 Transaction 物件,然後通過 Transaction 獲取一個 Executor 物件,最 後通過configuration、Executor、是否autoCommit三個引數構建了 SqlSession

代理模式

代理模式(Proxy Pattern):給某一個物件提供一個代理,並由代理物件控制對原物件的引用。代理模式 的英文叫做Proxy,它是一種物件結構型模式,代理模式分為靜態代理和動態代理,我們來介紹動態代 理

Mybatis中實現:

代理模式可以認為是Mybatis的核心使用的模式,正是由於這個模式,我們只需要編寫Mapper.java接 口,不需要實現,由Mybati s後臺幫我們完成具體SQL的執行。

當我們使用Configuration的getMapper方法時,會呼叫mapperRegistry.getMapper方法,而該方法又 會呼叫 mapperProxyFactory.newInstance(sqlSession)來生成一個具體的代理:

非常典型的,該MapperProxy類實現了InvocationHandler介面,並且實現了該介面的invoke方法。通 過這種方式,我們只需要編寫Mapper.java介面類,當真正執行一個Mapper介面的時候,就會轉發給 MapperProxy.invoke方法,而該方法則會呼叫後續的 sqlSession.cud>executor.execute>prepareStatement 等一系列方法,完成 SQL 的執行和返回