1. 程式人生 > 實用技巧 >mybatis基礎及原理

mybatis基礎及原理

IDEA建立mybatis配置檔案模板

IDEA提供了spring框架的配置模板,但是未提供mybatis配置檔案模板,因此需要自己建立模板,建立步驟如下:

settings -> Editor -> File and Code template -> Files 然後點選加號,檔案字尾名為xml,檔名為mybatis-config,檔案內容如下(mybatis配置基礎版,根據個人需求新增)

<?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> <!--環境配置,連線的資料庫,這裡使用的是MySQL--> <environments default="mysql"> <environment id="mysql"> <!--指定事務管理的型別,這裡簡單使用Java的JDBC的提交和回滾設定--> <transactionManager type="JDBC"></transactionManager> <!--
dataSource 指連線源配置,POOLED是JDBC連線物件的資料來源連線池的實現--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybbs"></property> <
property name="username" value="root"></property> <property name="password" value="root"></property> </dataSource> </environment> </environments> <mappers> <!--這是告訴Mybatis區哪找持久化類的對映檔案,對於在src下的檔案直接寫檔名, 如果在某包下,則要寫明路徑,如:com/mybatistest/config/User.xml--> <mapper resource="User.xml"></mapper> </mappers> </configuration>

這樣在新建檔案的選單中就能夠看到mybatis配置檔案的模板了

mybatis基礎工程

1、連線資料庫,建立table,通過EasyCode外掛建立entity類、mapper介面、mapper對映檔案(前面說過,不細說)

2、建立mybatis配置檔案

3、main方法如下:

public static void main(String[] args) throws IOException {
    String config = "mybatis-config.xml";

    Reader reader = Resources.getResourceAsReader(config);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    TableStudentDao mapper = sqlSession.getMapper(TableStudentDao.class);

    TableStudent tableStudent = mapper.queryById("bale");
    System.out.println(tableStudent);
}


4、執行結果如下:

mybatis主要構件及層次結構

mybatis執行解析基本原理

1、構造SqlSessionFactory

通過解析mybatis配置檔案以及mapper對映檔案,構造了SqlSessionFactory,很重要的一點,這一步構造了一個很重要的Configuration物件;

Configuration物件包含了所有的配置解析資訊

2、SqlSession

通過SqlSessionFactory以及配置的資料來源,可以得到一個SqlSession物件,SqlSession作為sql會話訪問的頂層API介面,提供完整的CRUD方法

帶著問題來了解SqlSession;

問題1:怎麼獲取到SqlSession?

預設情況下,SqlSessionFactory的實現類為DefaultSqlSessionFactory

DefaultSqlSessionFactory提供瞭如下方法來獲取SqlSession:

其中入參有如下幾個:是否自動提交、ExecutorType、事務隔離級別、資料庫連線物件;例子中使用的是:自動提交

問題2:getMapper方法獲取的mapper物件到底是什麼?

DefaultSqlSession通過Configuration物件獲取mapper,而Configuration類通過mapperRegistry獲取mapper

進一步跟蹤原始碼,可以看到:mapperRegistry先從knownMappers中獲取到MapperProxyFactory,然後呼叫MapperProxyFactory的newInstance方法獲取到mapper;

再進一步看,MapperProxyFactory的newInstance方法建立了一個MapperProxy物件,而MapperProxy類繼承了InvocationHandler介面,到這裡能夠清晰知道,mapper實際上是一個JDK動態代理物件

問題3:獲取到mapper物件後,為什麼指定mapper介面中定義的方法就能操作資料庫?

前面說到,mapper物件的實質是JDK動態代理物件,對應的InvocationHandler介面實現類為MapperProxy,所以呼叫mapper介面中的任意方法實質是呼叫MapperProxy的invoke方法;MapperProxy的invoke方法如下:

前面的判斷主要是為了保證toString等方法也能正常呼叫;實際的資料庫操作要看else分支;

由於java8增加了default方法,因此cachedInvoker方法相容了default方法的處理:

非default方法呼叫邏輯見PlainMethodInvoker類的invoke方法,PlainMethodInvoker為MapperProxy的一個靜態內部類

PlainMethodInvoker的invoke方法的實質是呼叫了MapperMethod的execute方法:

以insert操作為例,一路跟進(呼叫過程很簡單,不一一列出),最終定格到了SimpleStatementHandler類的update方法:

這裡呼叫了MySql驅動類的execute方法,到此找到了資料庫操作的程式碼;

問題4:mapper介面類和xml檔案如何形成對映關係?

Configuration物件存有一個Map物件,key為方法名,value為MappedStatement;MappedStatement存有xml檔案的解析資訊,在指行資料庫操作的方法中呼叫獲取;

問題5:我們知道JDBC操作離不開Connection物件,那麼在mybatis中,Connection物件體現在哪裡呢?

BaseExecutor類的getConnection方法中通過Transaction物件獲取;