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物件獲取;