MyBatis常見面試題和答案

MyBatis是什麼?

MyBatis 是一款持久層框架,一個半 ORM(對象關係映射)框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可使用簡單的 XML 或註解來配置和映射原生類型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。java

ORM是什麼

ORM(Object Relational Mapping),對象關係映射,是一種爲了解決關係型數據庫數據與簡單Java對象(POJO)的映射關係的技術。簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係型數據庫中。spring

**爲何說Mybatis是半自動ORM映射工具?**它與全自動的區別在哪裏?

Hibernate屬於全自動ORM映射工具,使用Hibernate查詢關聯對象或者關聯集合對象時,能夠根據對象關係模型直接獲取,因此它是全自動的。sql

而Mybatis在查詢關聯對象或關聯集合對象時,須要手動編寫sql來完成,因此,稱之爲半自動ORM映射工具。數據庫

JDBC編程有哪些不足之處,MyBatis是如何解決這些問題的?

一、數據庫連接建立、釋放頻繁形成系統資源浪費從而影響系統性能,若是使用數據庫鏈接池可解決此問題。編程

解決:在mybatis-config.xml中配置數據連接池,使用鏈接池管理數據庫鏈接。緩存

二、Sql語句寫在代碼中形成代碼不易維護,實際應用sql變化的可能較大,sql變更須要改變java代碼。安全

解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。session

三、向sql語句傳參數麻煩,由於sql語句的where條件不必定,可能多也可能少,佔位符須要和參數一一對應。mybatis

解決:Mybatis自動將java對象映射至sql語句。架構

四、對結果集解析麻煩,sql變化致使解析代碼變化,且解析前須要遍歷,若是能將數據庫記錄封裝成pojo對象解析比較方便。

解決:Mybatis自動將sql執行結果映射至java對象。

Mybatis優缺點

優勢:

  • 基於SQL語句編程,至關靈活,不會對應用程序或者數據庫的現有設計形成任何影響,SQL寫在XML裏,解耦合,便於統一管理;提供XML標籤,支持編寫動態SQL語句,可重用

  • 與JDBC相比,減小了50%以上的代碼量,消除了JDBC大量冗餘的代碼,不須要手動開關鏈接

  • 很好的與各類數據庫兼容(由於MyBatis使用JDBC來鏈接數據庫,因此只要JDBC支持的數據庫MyBatis都支持)

  • 提供映射標籤,支持對象與數據庫的ORM字段關係映射;提供對象關係映射標籤,支持對象關係組件維護

  • 可以與Spring很好的集成

缺點:

  • SQL語句的編寫工做量較大,尤爲當字段多、關聯表多時,對開發人員編寫SQL語句的功底有必定要求

  • SQL語句依賴於數據庫,致使數據庫移植性差,不能隨意更換數據庫

MyBatis框架適用場景

MyBatis專一於SQL自己,對性能的要求很高,或者需求變化較多的項目,如互聯網項目,MyBatis將是不錯的選擇。

Hibernate 和 MyBatis 的區別

相同點:

  • 都是對jdbc的封裝,都是持久層的框架,都用於Dao層的開發。

不一樣點:

  • MyBatis 是一個半自動映射的框架,配置Java對象與sql語句執行結果的對應關係,多表關聯關係配置簡單Hibernate 是一個全表映射的框架,配置Java對象與數據庫表的對應關係,多表關聯關係配置複雜

  • Hibernate 對SQL語句封裝,提供了日誌、緩存、級聯等特性,但會多消耗性能。代碼開發量少,但SQL語句優化困難。

  • MyBatis 須要手動編寫 SQL,支持動態 SQL、處理列表、動態生成表名、支持存儲過程。開發工做量相對大些。直接使用SQL語句操做數據庫,不支持數據庫無關性,但sql語句優化容易。

  • Hibernate 是重量級框架,學習使用門檻高,適合於需求相對穩定,中小型的項目,好比:辦公自動化系統MyBatis 是輕量級框架,學習使用門檻低,適合於需求變化頻繁,大型的項目,好比:互聯網電子商務系統

總結

MyBatis 是一個小巧、方便、高效、簡單、直接、半自動化的持久層框架,

Hibernate 是一個強大、方便、高效、複雜、間接、全自動化的持久層框架。

MyBatis編程步驟是什麼樣的?

一、 建立SqlSessionFactory

二、 經過SqlSessionFactory建立SqlSession

三、 經過sqlsession執行數據庫操做

四、 調用session.commit()提交事務

五、 調用session.close()關閉會話

請說說MyBatis的工做原理

1)讀取 MyBatis 配置文件

2)加載映射文件。

3)構造會話工廠

4)建立會話對象

5)Executor 執行器操做數據庫

6)MappedStatement 對象存儲要映射的 SQL 語句的 id、參數

7)輸入參數映射

8)輸出結果映射

MyBatis的功能架構是怎樣的

img

咱們把Mybatis的功能架構分爲三層:

API接口層:提供給外部使用的接口API,開發人員經過這些本地API來操縱數據庫。接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理。

數據處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次數據庫操做。

基礎支撐層:負責最基礎的功能支撐,包括鏈接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,將他們抽取出來做爲最基礎的組件。爲上層的數據處理層提供最基礎的支撐。

**Mybatis都有哪些Executor執行器?**它們之間的區別是什麼?

Mybatis有三種基本的Executor執行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每執行一次update或select,就開啓一個Statement對象,用完馬上關閉Statement對象。

ReuseExecutor:執行update或select,以sql做爲key查找Statement對象,存在就使用,不存在就建立,用完後,不關閉Statement對象,而是放置於Map<String, Statement>內,供下一次使用。簡言之,就是重複使用Statement對象。

BatchExecutor:執行update(沒有select,JDBC批處理不支持select),將全部sql都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個Statement對象,每一個Statement對象都是addBatch()完畢後,等待逐一執行executeBatch()批處理。與JDBC批處理相同。

做用範圍:Executor的這些特色,都嚴格限制在SqlSession生命週期範圍內。

Mybatis中如何指定使用哪種Executor執行器?

在Mybatis配置文件中,在設置(settings)能夠指定默認的ExecutorType執行器類型,也能夠手動給DefaultSqlSessionFactory的建立SqlSession的方法傳遞ExecutorType類型參數,如SqlSession openSession(ExecutorType execType)。

配置默認的執行器。SIMPLE 就是普通的執行器;REUSE 執行器會重用預處理語句(prepared statements);BATCH 執行器將重用語句並執行批量更新。

**Mybatis是否支持延遲加載?**若是支持,它的實現原理是什麼?

Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載。

association指的就是一對一,collection指的就是一對多查詢。

在Mybatis配置文件中,能夠配置是否啓用延遲加載lazyLoadingEnabled=true|false。

#{}和${}的區別

  • #{}是佔位符,預編譯處理

  • ${}是拼接符,字符串替換,沒有預編譯處理。

  • Mybatis在處理#{}時,#{}傳入參數是以字符串傳入,會將SQL中的#{}替換爲?號,調用PreparedStatement的set方法來賦值。Mybatis在處理時,是原值傳入,就是把{}時,是原值傳入,就是把時,是原值傳入,就是把{}替換成變量的值,至關於JDBC中的Statement編譯

  • 變量替換後,#{} 對應的變量自動加上單引號 ‘’;${} 對應的變量不會加上單引號 ‘’

  • #{} 能夠有效的防止SQL注入,提升系統安全性;${} 不能防止SQL 注入

Mapper 編寫有哪幾種方式?

第一種:接口實現類繼承 SqlSessionDaoSupport:使用此種方法須要編寫mapper 接口,mapper 接口實現類、mapper.xml 文件。

(1)在 sqlMapConfig.xml 中配置 mapper.xml 的位置

(2)定義 mapper 接口

(3)實現類集成 SqlSessionDaoSupport

mapper 方法中能夠 this.getSqlSession()進行數據增刪改查。

(4)spring 配置

**什麼是MyBatis的接口綁定?**有哪些實現方式?

接口綁定,就是在MyBatis中任意定義接口,而後把接口裏面的方法和SQL語句綁定,咱們直接調用接口方法就能夠,這樣比起原來了SqlSession提供的方法咱們能夠有更加靈活的選擇和設置。

接口綁定有兩種實現方式

經過註解綁定,就是在接口的方法上面加上 @Select、@Update等註解,裏面包含Sql語句來綁定;

經過xml裏面寫SQL來綁定, 在這種狀況下,要指定xml映射文件裏面的namespace必須爲接口的全路徑名。當Sql語句比較簡單時候,用註解綁定, 當SQL語句比較複雜時候,用xml綁定,通常用xml綁定的比較多。

使用MyBatis的mapper接口調用時有哪些要求?

一、Mapper接口方法名和mapper.xml中定義的每一個sql的id相同。

二、Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同。

三、Mapper接口方法的輸出參數類型和mapper.xml中定義的每一個sql的resultType的類型相同。

四、Mapper.xml文件中的namespace便是mapper接口的類路徑。

**最佳實踐中,一般一個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中,每個<select>、<insert>、<update>、<delete>標籤,都會被解析爲一個MappedStatement對象。

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

Dao接口的工做原理是JDK動態代理,Mybatis運行時會使用JDK動態代理爲Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行MappedStatement所表明的sql,而後將sql執行結果返回。

**Mybatis動態sql是作什麼的?**都有哪些動態sql?能簡述一下動態sql的執行原理不?

Mybatis動態sql可讓咱們在Xml映射文件內,以標籤的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能,Mybatis提供了9種動態sql標籤trim|where|set|foreach|if|choose|when|otherwise|bind。

其執行原理爲,使用OGNL從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此來完成動態sql的功能。

**Mybatis是如何進行分頁的?**分頁插件的原理是什麼?

Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁,能夠在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可使用分頁插件來完成物理分頁。

分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,而後重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。

舉例:select * from student,攔截sql後重寫爲:select t.* from (select * from student) t limit 0, 10

簡述Mybatis的插件運行原理,以及如何編寫一個插件。

Mybatis僅能夠編寫針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這4種接口的插件,Mybatis使用JDK的動態代理,爲須要攔截的接口生成代理對象以實現接口方法攔截功能,每當執行這4種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke()方法,固然,只會攔截那些你指定須要攔截的方法。

實現Mybatis的Interceptor接口並複寫intercept()方法,而後在給插件編寫註解,指定要攔截哪個接口的哪些方法便可,記住,別忘了在配置文件中配置你編寫的插件。

緩存Mybatis的一級、二級緩存

1)一級緩存: 基於 PerpetualCache 的 HashMap 本地緩存,其存儲做用域爲 Session,當 Session flush 或 close 以後,該 Session 中的全部 Cache 就將清空,默認打開一級緩存。

2)二級緩存與一級緩存其機制相同,默認也是採用 PerpetualCache,HashMap 存儲,不一樣在於其存儲做用域爲 Mapper(Namespace),而且可自定義存儲源,如 Ehcache。默認不打開二級緩存,要開啓二級緩存,使用二級緩存屬性類須要實現Serializable序列化接口(可用來保存對象的狀態),可在它的映射文件中配置<cache/> ;

3)對於緩存數據更新機制,當某一個做用域(一級緩存 Session/二級緩存Namespaces)的進行了C/U/D 操做後,默認該做用域下全部 select 中的緩存將被 clear。

相關文章
相關標籤/搜索