你真的瞭解MyBatis中${}和#{}的區別嗎?

来源:https://www.cnblogs.com/wuneng/archive/2019/09/06/11478208.html
-Advertisement-
Play Games

動態sql是mybatis的主要特性之一。在mapper中定義的參數傳到xml中之後,在查詢之前mybatis會對其進行動態解析。 mybatis提供了兩種支持動態sql的語法: {} 和 ${}。 username傳參一致的話,這兩種執行的結果是一樣的,但是這兩種方式在動態sql解析階段的處理是不 ...


動態sql是mybatis的主要特性之一。在mapper中定義的參數傳到xml中之後,在查詢之前mybatis會對其進行動態解析。

mybatis提供了兩種支持動態sql的語法:#{} 和 ${}。

select * from t_user where username = '${username}';
select * from t_user where username = #{username};

username傳參一致的話,這兩種執行的結果是一樣的,但是這兩種方式在動態sql解析階段的處理是不一樣的。

1、#{}

解析為一個JDBC預編譯語句(prepared statement)的參數標記符,把參數部分用占位符 ? 代替。動態解析為:

select * from t_user where username = ?;

而傳入的參數將會經過PreparedStatement方法的強制類型檢查和安全檢查等處理,最後作為一個合法的字元串傳入。

2、${}

這種方式只會做簡單的字元串替換,在動態SQL解析階段將會進行變數替換,假如傳遞的參數為二師兄,最終處理結果如下:

select * from t_user where username = '二師兄' ;

這樣在預編譯之前的sql語句已經不包含變數了,因此可以看出 ${} 變數的替換階段是在動態SQL解析階段。

3、#{}與${}兩種方式對比

1)是否預防SQL註入

以上不同的處理方式可以看出

  • {} 預處理之後可以預防SQL註入

  • ${} 預編譯之前就已經被替換,有被註入的風險

舉個慄子:

如果傳入的username 為 a' or '1=1,那麼使用 ${} 處理後直接替換字元串的sql就解析為:

select * from t_user where username = 'a' or '1=1' ;

這樣的話所有的用戶數據就被查出來了,這樣就屬於SQL註入.

如果使用#{},經過sql動態解析和預編譯,會把單引號轉義為 \' 那麼sql最終解析為:

select * from t_user where username = "a\' or \'1=1 ";//這樣會查不出任何數據,有效阻止sql註入

有的業務場景經常用到模糊查詢,也就是like處理,推薦使用以下處理方式:
t_user.username like #username#

if (!StringUtil.isEmpty(this.username)) {
table.setUsername("%" + this.username + "%");
}

或者也可以使用資料庫函數進行連接處理:

select * from t_user u where username  like CONCAT('%', #username#, '%')

註意:
以上就可以發現在某些特定場景下只能用${},比如order by後的排序欄位,表名、列名,因為需要替換為不變的常量。如果表名中使用#{}的話,會變成如下:
select * from #{tablename}-->tablename傳參為t_user --->處理後變成 select * from 't_user',沒有這樣的表名,這樣的話就會報錯了,order by 同理。

2)性能考慮

因為預編譯語句對象可以重覆利用,把一個sql預編譯後產生的PreparedStatement對象緩存下來,下次對於同一個sql,可以直接使用緩存的PreparedStatement對象,mybatis預設情況下,對所有的sql進行預編譯,這樣的話 #{}的處理方式性能會相對高些。

總結:

能使用#{}的時候儘量使用#{}表名。
order by的排序欄位作為變數時,使用${}。

來源:https://dwz.cn/tQwJGPbP
關註微信公眾號【悟能之能】瞭解更多編程技巧。
回覆"面經"獲取面試資料


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、什麼是SEO? SEO是英文Search Engine Optimization的縮寫,中文譯為“搜索引擎優化”。簡單的定義是從自然搜索結果獲得網站流量的技術和過程,從而改進網站在搜索引擎中自然排名的一種技術,也叫SEO優化。百度搜索一個關鍵詞,在搜索的結果中排名靠前的,不是廣告的,就是靠著SE ...
  • 1.背景介紹 隨著 Internet 的快速發展和業務量的不斷提高,基於網路的數據訪問流量迅速增長,特別是對數據 中心、大型企業以及門戶網站等的訪問,其訪問流量甚至達到了 10Gb/s 的級別;同時,伺服器網 站藉助 HTTP、FTP、SMTP 等應用程式,為訪問者提供了越來越豐富的內容和信息,服務 ...
  • 在vim 中輸入 :set mouse=r 就行了 ,還不行的話 :set mouse=v. ...
  • 本文源碼: "GitHub·點這裡" || "GitEE·點這裡" 一、配置詳解 場景描述:MySQL數據表以全量和增量的方式向ElasticSearch搜索引擎同步。 1、下載內容 elasticsearch 版本 6.3.2 logstash 版本 6.3.2 mysql connector j ...
  • 這些都是比較有實用性的系統配置,收藏下,以備不時之需!以下是etc下重要配置文件解釋: 1、/etc/hosts #文件格式: IPaddress hostname aliases #文件功能: 提供主機名到IP地址的對應關係,建議將自己經常使用的主機 # 加入此文件中,也可將沒有DNS記錄的機器加 ...
  • windows系統安裝虛擬機,常見的是利用VMware Workstation這款軟體來進行安裝。在未接觸Docker之前,我一直通過這款軟體來進行管理的。docker是運行在linux環境下的,那怎樣才能讓docker運行在Windows環境下呢,於是windows提供了Hyper-V管理器並自動 ...
  • 在JDBC中實現SQL語句的模糊查詢 在大多數情況下我們可以在JDBC中寫入sql語句通過占位符的方式來直接查詢,但是如果要進行模糊查詢,需要轉義字元才能夠正常查詢。 sql語句: 在大多數情況下我們可以在JDBC中寫入sql語句通過占位符的方式來直接查詢,但是如果要進行模糊查詢,需要轉義字元才能夠 ...
  • Photon Server 和 Unity3D 數據交互: Photon Server 服務端編程 Unity3D 客戶端編程 VS2017 之 MYSQL實體數據模型 一、新建資料庫連接後,點擊下一步可能出現閃退。 原因:引用Mysql.Data和Mysql.Data.Entity版本和安裝的My ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...