天天看點

Spring Boot 進階-詳解Mybatis資料層原理(一)

作者:架構師面試寶典
Spring Boot 進階-詳解Mybatis資料層原理(一)

Mybatis作為一款比較優秀的持久層架構,支援了定制化SQL開發、存儲過程以及進階映射等功能,幾乎避免了所有的JDBC代碼和手動設定參數擷取結果的操作,可以通過簡單的XML檔案或者是使用主機的的方式來配置映射關系,将接口與Java的POJO對象進行映射。實作了簡單高效的持久層開發。下面我們就來一起詳細了解一下關于MyBatis相關的知識。

簡述

MyBatis的前身是Apache的開源項目iBatis,2010年的時候改名成Mybatis。IBatis是一個Java持久層架構,提供了SQL Map 以及Data Access Object等功能。

在Mybatis中采用面向對象程式設計的方式對資料庫進行CRUD的操作,這樣簡化了通過映射關系來進行資料庫操作的方式。通過支援XML配置檔案掃描和注解的方式來實作對于SQL語句的映射執行以及結果回報,極大的提高了ORM的執行效率。

早起的ORM架構例如Hibernate等,提供了從資料庫到POJO對象的全套映射,開發者定義好了POJO對象與資料庫表結構的關聯之後,就可以通過Hibernate提供的方法進行持久化的操作,并且不需要對SQL語句有太多的掌握,Hibernate架構會更具具體的調用操作來實作SQL與JDBC的操作關系并且執行SQL映射結果。

這樣的操作往往帶來的問題就是再有些複雜情況下,Hibernate的查詢執行效率就有點太低下了。當面對一些複雜查詢的時候Hibernate就不再适用了。當然我們可以使用JDBC操作執行對資料庫進行操作,但是這樣的操作就會帶來很多的性能上的損耗。

相比較于Hibernate這種全自動化的ROM架構Mybatis被稱為是半自動的ORM架構,為什麼這麼說呢?

相比較Hibernate,Mybatis通過XML以及注解等方式提供了使用者自定義的SQL語句,隻有執行了對應的語句才會有對應的結果進行映射,這個時候這個操作是由程式員來完成的。而對于編寫好的SQL語句以及映射關系等,又是由架構自動進行封裝映射的。是以被稱為是半自動的ORM架構。

Mybatis架構的組成

如下圖所示,圖檔來源網絡。我們對每個層進行一個簡單的介紹。

Spring Boot 進階-詳解Mybatis資料層原理(一)

接口層

首先Mybatis是用來封裝對于資料庫的通路操作,而對于資料庫的通路操作,一般都是通過接口層來進行的。而接口層一般就是由一個會話來進行調用操作。這個時候就需要我們了解一下SqlSession對象。

在我們進行Mybatis配置的時候會在配置檔案中添加如下的一個配置Bean

@Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
    {
        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis.mapperLocations");
        String configLocation = env.getProperty("mybatis.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);

        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
        return sessionFactory.getObject();
    }           

這裡就是用來給容器中生成SqlSession的工廠類,而我們需要的SqlSession則是在org.apache.ibatis.session.SqlSession包下的接口。在這個接口中提供了我們操作資料庫所有的方法。

Spring Boot 進階-詳解Mybatis資料層原理(一)

總清單上看,SqlSession中提供了對于資料庫的基本的CRUD操作。同時還提供了一些事務復原相關的操作。以及資料庫連接配接、配置、緩存、Mapper映射等相關配置操作的API。我們可以根據具體的配置通過SqlSessionFactory來生成對應的SqlSession來進行對資料庫的操作。

根據上面的介紹在SqlSession的建立過程中Configuration是比較關鍵的類。在這個類中定義了所有關于SqlSession配置的相關屬性資訊,而隻有了解了這些屬性資訊才能更好的使用Mybatis相關的配置。在Mybatis中提供了對SqlSession的預設實作DefaultSqlSession,并且也提供了對于DefaultSqlSession的預設實作工廠DefaultSqlSessionFactory,當然除了可以靜态的通過配置檔案進行配置之外,我們還可通過上面代碼中所展示那個樣來實作動态的配置。

資料處理層

當項目啟動的時候,Mybatis會去加載并且解析兩種配置。

  • SQLMapConfig.xml
  • Mapper.xml

其中SQLMapConfig 配置是在XMLConfigBuilder類中進行解析的,而Mapper配置檔案則是在XMLMapperBuilder即解析完成,從兩個類的名稱中可以知道一個是用來解析關于Mybatis的的配置,一個是用來解析MapperSQL映射相關的配置,而這些配置都是可以通過注解的方式來進行設定的。如下圖所示。

Spring Boot 進階-詳解Mybatis資料層原理(一)

圖檔來源網絡

XMLMapperBuilder将SQL語句進行解析之後委托給了XMLStatementBuilder來進行對于SQL語句的解析操作。而在XMLStatementBuilder有一個parseStatementNode的方法,這個方法中就是對Mapper檔案進行了解析。代碼如下,這裡隻是截取了一部分代碼,其中有我們熟悉的parameterMap、resultType、resultMap等屬性感興趣的讀者可以閱讀源碼,加深影響。

// 部分代碼
		SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
    StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
    Integer fetchSize = context.getIntAttribute("fetchSize");
    Integer timeout = context.getIntAttribute("timeout");
    String parameterMap = context.getStringAttribute("parameterMap");
    String resultType = context.getStringAttribute("resultType");
    Class<?> resultTypeClass = resolveClass(resultType);
    String resultMap = context.getStringAttribute("resultMap");
    String resultSetType = context.getStringAttribute("resultSetType");
    ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
    if (resultSetTypeEnum == null) {
      resultSetTypeEnum = configuration.getDefaultResultSetType();
    }           

總結

到目前為止我們據介紹的都是關于需要程式員手動配置才能執行的部分的介紹,還有一些關于日志、IO、反射等相關的内容我們留在下一篇文章中進行介紹。希望大家可以多多關注。後續會為大家帶來更多的幹貨内容。

繼續閱讀