java面試題之mybatis篇

什么是ORM?

  • ORM(Object/Relational Mapping)即對象關系映射,是一種數據持久化技術。它在對象模型和關系型數據庫直接建立起對應關系,并且提供一種機制,通過JavaBean對象去操作數據庫表的數據。 MyBatis通過簡單的XML或者注解的方式進行配置和原始映射,將實體類和SQL語句之間建立映射關系,是一種半自動(之所以說是半自動,因為我們要自己寫SQL)的ORM實現。

MyBatis框架的優缺點及其適用的場合

優點

  1. 與JDBC相比,減少了50%以上的代碼量。
  2. MyBatis是易學的持久層框架,小巧并且簡單易學。
  3. MyBatis相當靈活,不會對應用程序或者數據庫的現有設計強加任何影響,SQL寫在XML文件里,從程序代碼中徹底分離,降低耦合度,便于統一的管理和優化,并可重用。
  4. 提供XML標簽,支持編寫動態的SQL,滿足不同的業務需求。
  5. 提供映射標簽,支持對象與數據庫的ORM字段關系映射。

缺點

  1. SQL語句的編寫工作量較大,對開發人員編寫SQL的能力有一定的要求。
  2. SQL語句依賴于數據庫,導致數據庫不具有好的移植性,不可以隨便更換數據庫。

適用場景

  • MyBatis專注于SQL自身,是一個足夠靈活的DAO層解決方案。對性能的要求很高,或者需求變化較多的項目,例如Web項目,那么MyBatis是不二的選擇。

MyBatis與Hibernate有哪些不同?

  1. Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句。
  2. Mybatis直接編寫原生態sql,可以嚴格控制sql執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,因為這類軟件需求變化頻繁,一但需求變化要求迅速輸出成果。但是靈活的前提是mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件,則需要自定義多套sql映射文件,工作量大。
  3. Hibernate對象/關系映射能力強,數據庫無關性好,對于關系模型要求高的軟件,如果用hibernate開發可以節省很多代碼,提高效率。

#{}和${}的區別是什么?

  1. #{}?是預編譯處理,${}是字符串替換。
  2. Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值;
  3. Mybatis在處理${}時,就是把${}替換成變量的值。
  4. 使用#{}可以有效的防止SQL注入,提高系統安全性。

當實體類中的屬性名和表中的字段名不一樣,怎么辦?

  1. 第1種: 通過在查詢的sql語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
  2. 第2種: 通過 `` 來映射字段名和實體類屬性名的一一對應的關系。

模糊查詢like語句該怎么寫?

  1. 第1種:在Java代碼中添加sql通配符。
  2. 第2種:在sql語句中拼接通配符,會引起sql注入

Dao接口的工作原理是什么?Dao接口里的方法,參數不同時,方法能重載嗎?

  • Dao接口即Mapper接口。接口的全限名,就是映射文件中的namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法內的參數,就是傳遞給sql的參數。 Mapper接口是沒有實現類的,當調用接口方法時,接口全限名+方法名拼接字符串作為key值,可唯一定位一個MapperStatement。在Mybatis中每、、、標簽,都會被解析為一個MapperStatement對象。 Mapper接口里的方法,是不能重載的,因為是使用 全限名+方法名 的保存和尋找策略。Mapper 接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Mapper接口生成代理對象proxy,代理對象會攔截接口方法,轉而執行MapperStatement所代表的sql,然后將sql執行結果返回。

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

  • Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁。可以在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。 分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。

Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式?

  1. 第一種是使用``標簽,逐一定義數據庫列名和對象屬性名之間的映射關系。
  2. 第二種是使用sql列的別名功能,將列的別名書寫為對象屬性名。
  • 有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性,是無法完成賦值的。

Mybatis動態sql有什么用?執行原理?有哪些動態sql?

  • Mybatis動態sql可以在Xml映射文件內,以標簽的形式編寫動態sql,執行原理是根據表達式的值完成邏輯判斷并動態拼接sql的功能。

Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復?

  • 不同的Xml映射文件,如果配置了namespace,那么id可以重復;如果沒有配置namespace,那么id不能重復; 原因就是namespace+id是作為Map <String,MapperStatement> 的key使用的,如果沒有namespace,就剩下id,那么,id重復會導致數據互相覆蓋。有了namespace,自然id就可以重復,namespace不同,namespace+id自然也就不同。

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

  • Hibernate屬于全自動ORM映射工具,使用Hibernate查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。而Mybatis在查詢關聯對象或關聯集合對象時,需要手動編寫sql來完成,所以,稱之為半自動ORM映射工具。

MyBatis實現一對一有幾種方式?具體怎么操作的?

  • 有聯合查詢和嵌套查詢,聯合查詢是幾個表聯合查詢,只查詢一次, 通過在resultMap里面配置association節點配置一對一的類就可以完成; 嵌套查詢是先查一個表,根據這個表里面的結果的 外鍵id,去再另外一個表里面查詢數據,也是通過association配置,但另外一個表的查詢通過select屬性配置。

MyBatis實現一對多有幾種方式,怎么操作的?

  • 有聯合查詢和嵌套查詢。聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap里面的collection節點配置一對多的類就可以完成;嵌套查詢是先查一個表,根據這個表里面的 結果的外鍵id,去再另外一個表里面查詢數據,也是通過配置collection,但另外一個表的查詢通過select節點配置。

Mybatis是否支持延遲加載?如果支持,它的實現原理是什么?

  • Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。 它的原理是,使用CGLIB創建目標對象的代理對象,當調用目標方法時,進入攔截器方法,比如調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那么就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,然后調用a.setB(b),于是a的對象b屬性就有值了,接著完成a.getB().getName()方法的調用。

Mybatis的一級、二級緩存

緩存就是內存中的數據,常常來自對數據庫查詢結果的保存。使用緩存,我們可以避免頻繁與數據庫進行交互,從而提高響應速度。

MyBatis 也提供了對緩存的支持,分為一級緩存和二級緩存,來看下下面這張圖:

1)一級緩存 Mybatis的一級緩存是指SQLSession,一級緩存的作用域是SQlSession, Myabits默認開啟一級緩存。

在同一個SqlSession中,執行相同的SQL查詢時;第一次會去查詢數據庫,并寫在緩存中,第二次會直接從緩存中取。 當執行SQL時候兩次查詢中間發生了增刪改的操作,則SQLSession的緩存會被清空。

每次查詢會先去緩存中找,如果找不到,再去數據庫查詢,然后把結果寫到緩存中。 Mybatis的內部緩存使用一個HashMap,key為hashcode+statementId+sql語句。Value為查詢出來的結果集映射成的java對象。 SqlSession執行insert、update、delete等操作commit后會清空該SQLSession緩存。

2) Mybatis二級緩存是默認不開啟的,作用于一個Application,是Mapper級別的,多個SqlSession使用同一個Mapper的sql能夠使用二級緩存。

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

  • 接口綁定,就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定, 我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置。 接口綁定有兩種實現方式:
  1. 注解綁定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql語句來綁定;
  2. 外一種就是通過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接口的類路徑。

mybatis是如何防止SQL注入的?

  • 首先看一下下面兩個sql語句的區別:
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">select id, username, passwordfrom userwhere username = #{username,jdbcType=VARCHAR} andpassword = #{password,jdbcType=VARCHAR}
</select>
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">select id, username, password,from userwhere username = ${username,jdbcType=VARCHAR} andpassword = ${password,jdbcType=VARCHAR}
</select>

mybatis中的#和$的區別:

  • #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。 如:where username=#{username},如果傳入的值是111,那么解析成sql時的值為where username="111", 如果傳入的值是id,則解析成的sql為where username="id".
  • $將傳入的數據直接顯示生成在sql中。如:where username=${username},如果傳入的值是111,那么解析成sql時的值為where username=111;如果傳入的值是:drop table user;,則解析成的sql為:select id, username, password, role from user where username=;drop table user;
  • #方式能夠很大程度防止sql注入,$方式無法防止Sql注入。
  • $方式一般用于傳入數據庫對象,例如傳入表名.
  • 一般能用#的就別用$,若不得不使用“${xxx}”這樣的參數,要手工地做好過濾工作,來防止sql注入攻擊。
  • 在MyBatis中,“${xxx}”這樣格式的參數會直接參與SQL編譯,從而不能避免注入攻擊。但涉及到動態表名和列名時,只能使用“${xxx}”這樣的參數格式。所以,這樣的參數需要我們在代碼中手工進行處理來防止注入。

sql注入:

  • SQL注入,大家都不陌生,是一種常見的攻擊方式。攻擊者在界面的表單信息或URL上輸入一些奇怪的SQL片段(例如“or ‘1’=’1’”這樣的語句),有可能入侵參數檢驗不足的應用程序。所以,在我們的應用中需要做一些工作,來防備這樣的攻擊方式。在一些安全性要求很高的應用中(比如銀行軟件),經常使用將SQL語句全部替換為存儲過程這樣的方式,來防止SQL注入。這當然是一種很安全的方式,但我們平時開發中,可能不需要這種死板的方式。

mybatis是如何做到防止sql注入的

  • MyBatis框架作為一款半自動化的持久層框架,其SQL語句都要我們自己手動編寫,這個時候當然需要防止SQL注入。其實,MyBatis的SQL是一個具有“輸入+輸出”的功能,類似于函數的結構,參考上面的兩個例子。其中,parameterType表示了輸入的參數類型,resultType表示了輸出的參數類型。回應上文,如果我們想防止SQL注入,理所當然地要在輸入參數上下功夫。上面代碼中使用#的即輸入參數在SQL中拼接的部分,傳入參數后,打印出執行的SQL語句,會看到SQL是這樣的:
select id, username, password from user where username=? and password=?
  • 不管輸入什么參數,打印出的SQL都是這樣的。這是因為MyBatis啟用了預編譯功能,在SQL執行前,會先將上面的SQL發送給數據庫進行編譯;執行時,直接使用編譯好的SQL,替換占位符“?”就可以了。因為SQL注入只能對編譯過程起作用,所以這樣的方式就很好地避免了SQL注入的問題。

底層實現原理

  • MyBatis是如何做到SQL預編譯的呢?其實在框架底層,是JDBC中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的SQL語句。這種“準備好”的方式不僅能提高安全性,而且在多次執行同一個SQL時,能夠提高效率。原因是SQL已編譯好,再次執行時無需再編譯。

結論:

#{}:相當于JDBC中的PreparedStatement
${}:是輸出變量的值

  • 簡單說,#{}是經過預編譯的,是安全的;${}是未經過預編譯的,僅僅是取變量的值,是非安全的,存在SQL注入。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697494.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697494.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697494.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MATLAB練習題:randperm函數的練習題

?講解視頻&#xff1a;可以在bilibili搜索《MATLAB教程新手入門篇——數學建模清風主講》。? MATLAB教程新手入門篇&#xff08;數學建模清風主講&#xff0c;適合零基礎同學觀看&#xff09;_嗶哩嗶哩_bilibili MATLAB中有一個非常有用的函數&#xff1a;randperm函數&…

華為算法題 go語言或者ptython

1 給定一個整數數組 nums 和一個整數目標值 target&#xff0c;請你在該數組中找出 和為目標值 target 的那 兩個 整數&#xff0c;并返回它們的數組下標。 你可以假設每種輸入只會對應一個答案。但是&#xff0c;數組中同一個元素在答案里不能重復出現。 你可以按任意順序返…

如何進行高性能架構的設計

一、前端優化 減少請求次數頁面靜態化邊緣計算 增加緩存控制&#xff1a;請求頭 減少圖像請求次數&#xff1a;多張圖片變成 一張。 減少腳本的請求次數&#xff1a;css和js壓縮&#xff0c;將多個文件壓縮成一個文件。 二、頁面靜態化 三、邊緣計算 后端優化 從三個方面進…

adb-monkey命令

目錄 adb shell monkey -p/-v 包名 次數 1、指定一個包 2、指定多個包 3、不指定包 Event percentages&#xff08;事件百分比&#xff09; 常見參數 --throttle 延遲時間 單位毫秒 --pct-touch 設定觸屏事件生成的百分比 --pct-motion 設定滑動事件生成…

面試前端性能優化八股文十問十答第二期

面試前端性能優化八股文十問十答第二期 作者&#xff1a;程序員小白條&#xff0c;個人博客 相信看了本文后&#xff0c;對你的面試是有一定幫助的&#xff01;關注專欄后就能收到持續更新&#xff01; ?點贊?收藏?不迷路&#xff01;? 1&#xff09;如何優化動畫&#x…

c語言中的大小寫字母轉換怎么轉?

在C語言中&#xff0c;大小寫字母轉換是基于ASCII碼表的特性實現的。ASCII碼中&#xff0c;小寫字母從’a’到’z’的ASCII碼值是連續的&#xff08;97到122&#xff09;&#xff0c;而大寫字母從’A’到’Z’的ASCII碼值也是連續的&#xff08;65到90&#xff09;。它們之間有…

Redis高性能原理

redis大家都知道擁有很高的性能&#xff0c;每秒可以支持上萬個請求&#xff0c;這里探討下它高性能的原理。單線程架構和io多路復用技術。 一&#xff0c;單線程架構 單線程架構指的是命令執行核心線程是單線程的&#xff0c;數據持久化、同步、異步刪除是其他線程在跑的。re…

獲取視頻第一幀,以及后續上傳

// 獲取視頻基本信息 const getVideoBasicInfo (videoSrc) > {return new Promise((resolve, reject) > {const video document.createElement("video");video.src videoSrc;// 視頻一定要添加預加載video.preload "auto";// 視頻一定要同源或者…

什么是系統工程(字幕)35

0 00:00:01,190 --> 00:00:02,840 下面的內容 1 00:00:04,850 --> 00:00:06,520 接下來呢就是 2 00:00:08,180 --> 00:00:09,830 16.6.1 3 00:00:11,070 --> 00:00:13,440 項流熱平衡分析 4 00:00:15,350 --> 00:00:16,730 這一節 5 00:00:18,860 --> 0…

億道丨三防平板丨加固平板丨三防加固平板丨改善資產管理

庫存資產管理中最重要的部分之一是準確性&#xff1b;過時的庫存管理技術會增加運輸過程中人為錯誤、物品丟失或紙張損壞的風險。如今隨著三防平板電腦的廣泛使用&#xff0c;庫存管理也迎來了好幫手&#xff0c;通過使用三防平板電腦能夠確保庫存管理、數據存儲和記錄保存的準…

React18源碼: React調度中的3種優先級類型和Lane的位運算

優先級類型 React內部對于優先級的管理&#xff0c;貫穿運作流程的4個階段&#xff08;從輸入到輸出&#xff09;&#xff0c;根據其功能的不同&#xff0c;可以分為3種類型&#xff1a; 1 &#xff09;fiber優先級(LanePriority) 位于 react-reconciler包&#xff0c;也就是L…

掌握 Android 中的 RecyclerView 優化

掌握 Android 中的 RecyclerView 優化 一、RecyclerView Pool以及何時使用它二、onCreateViewHolder 和 onBindViewHolder三、優化 RecyclerView 的不同方法四、視圖無效與請求布局五、ViewHolder模式六、默認的廢料和臟視圖類型七、結論 RecyclerView 是 Android 中一個功能強…

【操作系統】磁盤存儲空間的管理

實驗5 磁盤存儲空間的管理 一、實驗目的 磁盤是用戶存放程序和數據的存儲設備&#xff0c;磁盤管理的主要目的是充分有效地利用磁盤空間。本實驗模擬實現磁盤空間的分配與回收&#xff0c;使學生對磁盤空間的管理有一個較深入的理解。 二、實驗內容 實驗任務&#xff1a;用位…

FreeSWITCH debian11/12 apt安裝

官方給的easy way安裝方式如下&#xff1a; # 換成自己的token TOKENpat_ZrPXJQ8JNWsVQW2ubhnUwi7gapt-get update && apt-get install -y gnupg2 wget lsb-releasewget --http-usersignalwire --http-password$TOKEN -O /usr/share/keyrings/signalwire-freeswitch-…

#LLM入門|Prompt#1.2_提示原則_Guidelines

提示原則 一、編寫清晰、具體的指令 使用分隔符清晰地表示輸入的不同部分&#xff1a; 在Prompt中使用分隔符&#xff0c;如、“”"、< >、 、:等&#xff0c;將不同的文本部分區分開來&#xff0c;避免混淆和意外的結果。分隔符能夠防止提示詞注入&#xff0c;提…

petalinux_zynq7 驅動DAC以及ADC模塊之四:python實現http_api

前文&#xff1a; petalinux_zynq7 C語言驅動DAC以及ADC模塊之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C語言驅動DAC以及ADC模塊之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…

Java觀察者模式:實現高效的事件驅動編程

Java中的裝飾者模式&#xff1a;靈活地為對象添加功能 一、引言 在軟件設計中&#xff0c;我們經常需要為對象動態地添加功能或行為。裝飾者模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許我們在運行時將功能動態地添加到對象上&…

串的相關題目

于是他錯誤的點名開始了 我發現有關hash得題目有些是可以通過map數組來完成的&#xff1a;何為map數組&#xff0c;我們先思考一下最簡單的桶的排序&#xff0c;桶排序是將我們需要數字最為下標輸進數組中&#xff0c;而數組是存放的數字是這個數字出現的次數&#xff0c;但是由…

Matlab論文插圖繪制模板第137期—極坐標分組氣泡圖

在之前的文章中&#xff0c;分享了Matlab極坐標氣泡圖的繪制模板&#xff1a; 進一步&#xff0c;再來分享一下極坐標分組氣泡圖。 先來看一下成品效果&#xff1a; ? 特別提示&#xff1a;本期內容『數據代碼』已上傳資源群中&#xff0c;加群的朋友請自行下載。有需要的朋…

解決SSH遠程登錄開飯板出現密碼錯誤問題

輸入“adduser Zhanggong回車”&#xff0c;使用adduser命令創建開發板用戶名為Zhanggong 輸入密碼“123456” 輸入密碼“123456”