Mybatis總結

一,概述:
就是對jdbc數據庫操作進行封裝,使用戶開發者只用關注sql語句。通過xml或者註解的方式,將要執行的各種sql語句配置起來,並通過Java對象和statement中的sql語句映射生成最終的sql語句,最後由mybatis框架執行sql語句,並將結果映射成Java對象返回。
二. 工作原理:
1,分層:
a,接口層:接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理
b,數據處理層:SQL查找、SQL解析、SQL執行和執行結果映射處理
c,基礎支撐層:功能支撐,包括連接管理、事務管理、配置加載和緩存處理
2,實現過程:
1.讀取配置文件
連數據庫的相關信息
2.有了這些信息就能創建SqlSessionFactory
SqlSessionFactory的生命週期是程序級,程序運行的時候建立起來,程序結束的時候消亡
3.SqlSessionFactory建立SqlSession,目的執行sql語句
SqlSession是過程級,一個方法中建立,方法結束應該關閉
4.調用MyBatis的statementHandler提供的Api執行Sql語句
5.SQL語句放在Map配置文件裏面
6.執行SQl語句,不同的SQl語句返回不同的結果
1、 mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了數據源、事務等信息;映射文件配置了SQL執行相關的 信息。
2、 mybatis通過讀取配置文件信息(全局配置文件和映射文件),構造出SqlSessionFactory,即會話工廠。
3、 通過SqlSessionFactory,可以創建SqlSession即會話。Mybatis是通過SqlSession來操作數據庫的。
4、 SqlSession本身不能直接操作數據庫,它是通過底層的Executor執行器接口來操作數據庫的。Executor接口有兩個實現類,一個是普通執行器,一個是緩存執行器(默認)。
5、 Executor執行器要處理的SQL信息是封裝到一個底層對象MappedStatement中。該對象包括:SQL語句、輸入參數映射信息、輸出結果集映射信息。其中輸入參數和輸出結果的映射類型包括java的簡單類型、HashMap集合對象、POJO對象類型
這裏寫圖片描述

Configuration.xml:該配置文件是MyBatis的全局配置文件,在這個文件中可以配置諸多項目,但是一般項目中,並不會配置太多內容,常用的內容是別名設置,攔截器設置等,至於環境設置與Mapper映射文件的註冊會轉移到Spring配置文件中(SSM整合之後),而其餘大部分的配置項都採用默認的配置。
  XMLConfigBuilder:該類是XML配置構建者類,是用來通過XML配置文件來構建Configuration對象實例,構建的過程就是解析Configuration.xml配置文件的過程,期間會將從配置文件中獲取到的指定標籤的值逐個添加到之前創建好的默認Configuration對象實例中。
  Configuration:該類是MyBatis的配置類,創建這個類的目的就是爲了使用其對象作爲項目全局配置對象,這樣通過配置文件配置的信息可以保存在這個配置對象中,而這個配置對象在創建好之後是保存在JVM的Heap內存中的,方便隨時讀取。不然每次需要配置信息的時候都要臨時從磁盤配置文件中獲取,代碼複用性差的同時,也不利於開發。
  SqlSessionFactoryBuilder:該類是SqlSessionFactory(會話工廠)的構建者類,之前描述的操作其實全是從這裏面開啓的,首先就是調用XMLConfigBuilder類的構造器來創建一個XML配置構建器對象,利用這個構建器對象來調用其解析方法parse()來完成Configuration對象的創建,之後以這個配置對象爲參數調用會話工廠構建者類中的build(Configuration config)方法來完成會話工廠對象的構建。
  SqlsessionFactory:該接口是會話工廠,是用來生產會話的工廠接口,DefaultSqlSessionFactory是其實現類,是真正生產會話的工廠類,這個類的實例的生命週期是全局的,它只會在首次調用時生成一個實例(單例模式),就一直存在直到服務器關閉。
  openSession():在最後的build(Configuration config)方法中會返回一個DefaultSqlSessionFactory類的實例,這個類是MyBatis提供的默認會話工廠類,而我們使用的也正是這個類中的來openSession()方法來完成SqlSession對象的創建。
  SqlSession:該接口是會話,是項目與數據庫之間的會話,類似於客戶端與服務器之間的會話(session),這個SqlSession的生命週期是方法級的,因爲他是非線程安全的,針對每一次數據庫訪問都要創建一個SqlSession,獲取到返回結果之後,這個SqlSession就會被廢棄。這區別於SqlSessionFactory的生命週期。
  Executor:執行器接口,SqlSession會話是面向程序員的,而內部真正執行數據庫操作的卻是Executor執行器,可以將Executor看作是面向MyBatis執行環境的,SqlSession就是門面貨,Executor纔是實幹家。通過SqlSession產生的數據庫操作,全部是通過調用Executor執行器來完成的。
  StatementHandler:該類是Statement處理器,封裝了Statement的各種數據庫操作方法execute(),可見MyBatis其實就是將操作數據庫的JDBC操作封裝起來的一個框架,同時還實現了ORM罷了。
  ResultSetHandler:結果集處理器,如果是查詢操作,必定會有返回結果,針對返回結果的操作,就要使用ResultSetHandler來進行處理,這個是由StatementHandler來進行調用的。這個處理器的作用就是對返回結果進行處理。
三,
1,Environment

<environments default="development">
 2     <environment id="development">
 3         <transactionManager type="JDBC"/>
 4         <dataSource type="POOLED">
 5             <property name="driver" value="com.mysql.jdbc.Driver"/>
 6             <property name="url" value="jdbc:mysql://localhost:3306/mbtest"/>
 7             <property name="username" value="root"/>
 8             <property name="password" value="123456"/>
 9         </dataSource>
10     </environment>
11 </environments>
 在其下級節點還需要配置兩個內容:transactionManager和DataSource,前者是事務管理器,後者是數據源。“JDBC”表示事務管理器是JDBC類型了,這個標籤對應Configuration類創建時在其無參構造器中註冊的類型別名,通過這個類型別名註冊信息可以找到實際的JDBC事務工廠類,。而數據源的類型爲“POOLED”類型,同樣可以在Configuration類的無參構造器中找到對應的註冊信息。,構建Configuration之前,第一步是進行類型別名註冊,第二步就是將Environment配置內容從配置文件中讀入Environment類中(這一步是在XMLConfigBuilder中完成的),並將其組合到Configuration類中。Environment類內部有一個靜態內部類Builder,這顯然是一個構建器類,所以Environgment實例的創建使用了構建者模式(也叫建造者模式。這個實例的創建最顯然的使用位置就是在XMLConfigBuilder構建器中解析構建Configuration類時在解析了Configuration.xml配置文件中environment標籤的內容之後,這個位置用於將讀自於配置文件的配置信息配置到了Environment對象中

(1)事務模塊,抽象工廠模式
(2)數據源:數據源接口中定義了兩個獲取數據庫連接Connection的方法,可見數據源的目的所在,不論其使用什麼原理實現,其目的就是爲了對外提供數據庫連接的獲取接口。unpooled:非池型數據源。pooled:同步的線程安全的池型數據源。jndi:託管型
四,問題:
1,#{}和${}的區別是什麼?

{}是預編譯處理,${}是字符串替換。

Mybatis在處理#{}時,會將sql中的#{}替換爲?號,調用PreparedStatement的set方法來賦值;
Mybatis在處理 {}替換成變量的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
2,當實體類中的屬性名和表中的字段名不一樣 ,怎麼辦
第1種: 通過在查詢的sql語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致
第2種: 通過來映射字段名和實體類屬性名的一一對應的關係
3,通常一個Xml映射文件,都會寫一個Dao接口與之對應,請問,這個Dao接口的工作原理是什麼?Dao接口裏的方法,參數不同時,方法能重載嗎
Dao接口,就是人們常說的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法內的參數,就是傳遞給sql的參數。Mapper接口是沒有實現類的,當調用接口方法時,接口全限名+方法名拼接字符串作爲key值,可唯一定位一個MappedStatement,舉例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace爲com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一個、、、標籤,都會被解析爲一個MappedStatement對象。

Dao接口裏的方法,是不能重載的,因爲是全限名+方法名的保存和尋找策略。

Dao接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理爲Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行MappedStatement所代表的sql,然後將sql執行結果返回。
4,Mybatis是如何進行分頁的
Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁,可以在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。
5,在mapper中如何傳遞多個參數
對應的xml,#{0}代表接收的是dao層中的第一個參數,#{1}代表dao層中第二參數,更多參數一致往後加即可,
6,緩存問題:
Mybatis在查詢時會採用緩存機制,分爲一級緩存和二級緩存,一級緩存默認就會開啓,二級緩存需要配置纔可以使用。
一級緩存基於 PerpetualCache 的 HashMap 本地緩存,其存儲作用域爲 Session,當 Session flush 或 close 之後,該Session中的所有 Cache 就將清空。
二級緩存與一級緩存其機制相同,默認也是採用 PerpetualCache,HashMap存儲,不同在於其存儲作用域爲 Mapper(Namespace),並且可自定義存儲源,如 Ehcache、Hazelcast等。
對於緩存數據更新機制,當某一個作用域(一級緩存Session/二級緩存Namespaces)的進行了 C/U/D 操作後,默認該作用域下所有 select 中的緩存將被clear。
在緩存的作用域中,如果調用的方法的參數一樣,就會使用緩存中查詢的結果,而不會再次查詢數據庫。
7,延遲加載:
我們在某項業務裏需要同時獲取A、B兩份數據,但是B這份數據又不需要立即使(或者存在壓根就不會使用的情況),當程序需要加載B時,再去請求數據庫來獲取B數據,而不是一次性將數據全部取出來或者重新發送一份請求,這就是延遲加載

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