mybatis執行過程及經典面試題


Mybatis執行流程

  mybatis中xml解析是通過SqlSessionFactoryBuilder.build()方法。

  初始化mybatis(解析xml文件構建成Configuration對象)並初始化SqlSessionFactory對象

    •   在解析xml時會同時根據其中節點做相應的初始化操作
    •   關鍵節點:  settings、typeAliases、mappers

  通過SqlSesssionFactory.openSession()方法打開一個SqlSession對象

    •   SqlSessionFactory對象的作用是里面存了全局的配置信息以及初始化環境和DataSource,DataSource對象可以用來開辟連接,SqlSessionFactory對象是用來保存全局信息並且打開數據庫連接
    •   在打開SqlSession對象的時候就會開辟一個連接對象並傳給SqlSession對象,和數據庫打交道的操作入口在於SqlSession對象

  通過SqlSession.getMapper()根據傳入的Mapper對象類型動態代理並返回一個動態代理后的Mapper對象

  由SqlSession.select()/update(),MapperProxy對象的invoke()方法執行后再執行execure方法,再根據情況選擇執行select/update

  Executor執行Query/queryFromDatabase,在前面經過參數名封裝和緩存查詢之后(緩存為空),會調用queryFromDatabase方法去數據庫當中查

  SimpleExecurot執行doQuery()方法,初始化prepareStatement並且給#{}參數賦值

  StatementHandler執行query()方法,執行sql語句

  ResuletHandler.handleResultSets()方法封裝結果集

  具體執行流程如下圖:

mybatis面試題

  1. spring和mybatis整合之后為什么一級緩存會失效?

 

    一級緩存使用者可以隨時使用或者銷毀緩存,從SqlSession對象打開時緩存就已經存在。當關閉SqlSession對象緩存就失效。

    當與spring整合的時候,直接跳過SqlSession對象,無法直接操作到SqlSession對象,spring在操作SqlSession的時候,不知道用戶什么時候關閉,所以每調用完一個dao方法就關閉了,所以導致一級緩存失效。

    如果開啟了事務,一級緩存就會生效,因為開啟了事務,執行完dao就不會銷毀,因為一旦銷毀,事務就沒有了,你開啟了事務,spring就知道你什么時候需要結束

  2. 二級緩存中要注意的事情?

    二級緩存里面的數據不能存放那種一直累加到很大的數據

    二級緩存是基於命名空間的,當多個命名空間操作同一張表的時候,最好不要用二級緩存,當一個命名空間insert之的一,不會刷新緩存,用另一個命名空間select的時候還是會查詢緩存

  3. ResultMap和ResultType的區別?

    ResultMap是自己指定返回值與對象及與對象內部屬性名和數據庫列名的綁定

    ResultType是直接返回值與別名庫當中的java對象的映射

  4. #{}和${}的區別?

    #{}將傳入的數據都當成一個字符串,會對自動傳的數據加一個雙引號,#{}方式能夠很大程度防止sql注入

    ${}將傳入的數據是直接顯示生成在sql中,${}無法防止sql注入

    ${}方式一般用於傳入數據庫對象,例如傳入表名

    一般能用#{}的就別用${},Mybaits排序時使用order by動態參數時需要注意,用${}而不能用#{}

  5. MyBatis與Hibernate有哪些不同?

    MyBatis是一個半自動ORM而Hibernate是一個完全的ORM框架

    因為MyBatis需要自己編寫sql語句,不過MyBatis可以通過xml或注解方式配置要運行的sql語句,並將java對象和sql語句映射生成最終執行的sql,最后將sql執行的結果再映射生成java對象。可嚴格控制sql執行性能,靈活度高。但是靈活的前提是 Mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的則需要自定義多套sql映射文件。

    Hibernate對象/關系映射能力強,數據庫無關性好,對於關系模型要求高,如果用Hibernate開發可以節省很多代碼,提高效率。但是hibernate學習門檻高,要精通門檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力。

  6. 為什么說Mybatis是半自動ORM映射工具?它與全自動的區別在哪里?

    Hibernate屬於全自動ORM映射工具,使用Hibernate查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。

    Mybatis在查詢關系或關聯集合對象時需要手動編寫sql來完成,所以稱之為半自動ORM映射工具。

  7. Mybatis是如何進行分頁的?分頁插件的原理是什么?

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

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

 

  8. Mybatis映射文件中,如果A標簽通過include引用B標簽的內容,請問B標簽能否定詢問在A標簽的后面,還是說必須定義在A標簽的前面?

    雖然Mybatis解析xml映射文件是按照順序解析的,但是被引用的B標簽依然可以定義在任何地方,Mybatis都可以正常識別。原理是Mybatis解析A標簽時發現A標簽引用了B標簽,但是B標簽尚未解析到,此時,Mybatis會將A標簽標記為未解析狀態,然后繼續解析余下的標簽,包含B 標簽,待所有標簽解析完畢,Mybatis會重新解析那些被標記為未解析的標簽,此時再解析A標簽時,B標簽已經存在,A標簽就可以正常解析完成了。

  9. 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功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM