在MyBatis中$和#有什么區別

在 MyBatis 中,${}#{} 是兩種處理 SQL 參數的占位符,它們在實現機制、安全性、使用場景上存在顯著差異。以下是詳細對比:

核心區別對比

特性#{}${}
底層機制預編譯占位符(PreparedStatement字符串直接替換
安全性? 防止 SQL 注入? 存在 SQL 注入風險
參數處理自動添加引號(字符串/日期類型)需手動添加引號(否則語法錯誤)
性能較低(預編譯開銷)較高(直接拼接 SQL)
適用場景動態參數值(如 WHERE id = ?動態 SQL 片段(如表名、排序字段)

機制詳解

  1. #{}(預編譯占位符)

    • MyBatis 會將其解析為 JDBC 的?占位符,通過PreparedStatement預編譯 SQL。

    • 參數值會被安全轉義,例如:

      SELECT * FROM users WHERE name = #{name}  -- 轉換為:SELECT * FROM users WHERE name = ?

      若name = "John",實際執行時參數值會被安全綁定為'John'。

  2. ${}(字符串替換)

    • 直接替換為參數值的字面量,無預編譯或轉義。

    • 例如:

      SELECT * FROM users WHERE id = ${id}  -- 若 id=1,替換為:SELECT * FROM users WHERE id = 1

      若id = "1 OR 1=1",則 SQL 會變為:

      SELECT * FROM users WHERE id = 1 OR 1=1  -- 查詢所有數據,存在 SQL 注入風險[1,5](@ref)

安全性問題

  • #{}:天然防 SQL 注入,適用于用戶輸入或外部參數。

  • ${}:高風險!僅適用于完全可控的靜態值(如內部生成的表名、列名)。

    錯誤示例(模糊查詢):

    SELECT * FROM products WHERE name LIKE '%${keyword}%' -- 若 keyword="' OR 1=1 --",導致數據泄露!

使用場景對比

? #{} 的適用場景
  • 普通條件查詢(值動態傳遞):

    SELECT * FROM orders WHERE user_id = #{userId} [1,4](@ref)
  • 日期/字符串參數(自動添加引號):

    INSERT INTO logs (content) VALUES (#{logContent})  -- 自動轉為 'xxx' [7,8](@ref)
  • 模糊查詢(安全寫法):

    SELECT * FROM products WHERE name LIKE CONCAT('%', #{keyword}, '%') [2,3](@ref)
?? ${} 的適用場景
  • 動態表名/列名(SQL 片段不可預編譯):

    SELECT * FROM ${tableName} WHERE ${column} = 1 [3,5,7](@ref)
  • 排序字段(如ORDER BY ${sortField}):

    SELECT * FROM users ORDER BY ${orderBy} DESC [3,7](@ref)
  • 批量操作(如IN子句):

    DELETE FROM cart WHERE id IN (${ids})  -- ids="1,2,3" [7](@ref)

最佳實踐與避坑指南

  1. 默認使用 #{}:除非必須動態拼接 SQL 片段,否則一律用#{}確保安全。

  2. ${} 的防御措施:

    • 僅允許傳入白名單值(如預定義表名列表)。

    • 手動過濾危險字符(如空格、分號)。

  3. 模糊查詢的替代方案:

    • 用CONCAT函數(推薦):

      SELECT * FROM table WHERE name LIKE CONCAT('%', #{text}, '%')
    • 程序層拼接(Java 中生成"%text%"再傳入)。


💎 總結

  • #{} = 安全優先:處理動態值(用戶輸入、條件參數),預編譯防注入

  • ${} = 謹慎使用:處理動態 SQL 片段(表名、排序),需嚴格校驗輸入

關鍵口訣:**“值用井號(#),結構用刀($)”——值動態用 #{},SQL 結構動態用 ${}。實際開發中,95% 的場景應使用#{},僅在必要時(如分表)謹慎使用${}。

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

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

相關文章

湖北理元理律師事務所債務優化方案:平衡還款與生活的法律實踐

在個人債務問題日益突出的當下,如何科學規劃還款路徑成為社會性難題。湖北理元理律師事務所基于多年實務經驗,提出“可持續債務優化”模型,其核心在于通過法律工具實現三重平衡: 債權債務的法律平衡:嚴格依據《民法典…

使用 Isaac Sim 模擬機器人

前言 將 2D 激光雷達數據從 Isaac Sim 流式傳輸至 ROS 2,并通過 RViz 進行可視化。通過激光雷達數據監控機器人與環境的交互,從而在仿真環境中提升機器人的感知能力。 概覽 歡迎來到 入門指南:在 Isaac Sim 中模擬您的第一個機器人 課程。我…

quartz 表達式最近10次執行時間接口編寫

Nuget安裝 <PackageReference Include"CronExpressionDescriptor" Version"2.41.0" /> <PackageReference Include"CronExpressionDescriptor-zh-CN" Version"2.32.0" /> <PackageReference Include"Quartz"…

解鎖數據寶藏:數據挖掘之數據預處理全解析

目錄 一、引言&#xff1a;數據預處理 —— 數據挖掘的基石二、數據預處理的重要性2.1 現實數據的問題剖析2.2 數據預處理的關鍵作用 三、數據預處理的核心方法3.1 數據清洗3.1.1 缺失值處理3.1.2 離群點處理3.1.3 噪聲處理 3.2 數據集成3.2.1 實體識別3.2.2 冗余處理3.2.3 數據…

React+Taro創建小程序

第一步&#xff1a;首先確認是否安裝Node.js和npm 如果已安裝Node.js和npm,以下可以查詢 node -v npm -v 第二步&#xff1a;安裝Taro CLI npm install -g tarojs/cli 第三步&#xff1a;創建項目 taro init my-react-taro-app 然后可以看到&#xff0c;下圖 第四步&…

佳能Canon TS3100 Series打印機信息

打印功能 打印速度&#xff1a;黑白約 7.7 頁 / 分鐘&#xff0c;彩色約 4 頁 / 分鐘。打印分辨率&#xff1a;最高可達 48001200dpi&#xff0c;墨滴最小間距為 1/4800 英寸&#xff0c;能夠保證高質量的輸出&#xff0c;使文字清晰、色彩鮮艷。打印寬度&#xff1a;203.2 毫米…

家用電腦搭建可外網訪問的網站服務器操作流程

在互聯網時代&#xff0c;擁有一個屬于自己的網站是展示個人風采、分享知識經驗、開展線上業務的絕佳方式。你是否想過&#xff0c;利用家中閑置的電腦&#xff0c;就能搭建出一個可以被外網訪問的網站服務器&#xff1f;這不僅能滿足個性化需求&#xff0c;還能節省租用專業服…

CSS知識補充 --- 控制繼承

每天學習一點點&#xff01;&#xff01;&#xff01; 總所周知&#xff0c;CSS某些屬性可以繼承&#xff0c;然后今天看到MDN的時候看到了CSS也可以控制繼承&#xff0c;感覺很有意思&#xff0c;所以記錄一下&#xff1a; 控制繼承有5個屬性值&#xff0c;分別&#xff1a;in…

如何使用Ant Design Blazor組件在列表頁彈窗增加修改數據

在winform中首次使用net8做頁面。列表頁想使用Ant Design組件的彈窗組件實現。但第一次在winform項目中使用ant design組件&#xff0c;列表頁面&#xff0c;點擊新增&#xff0c;或者編輯操作實現彈窗頁面&#xff0c;彈窗頁面想使用模板頁razor頁來實現&#xff0c;而不是用m…

嵌入式學習 51單片機01

一、框架 1、CPU&#xff08;Central Processing Unit&#xff0c;中央處理單元&#xff09;?是計算機的核心部件&#xff0c;負責執行計算機指令和處理數據。 2、MCU&#xff08;Microcontroller Unit&#xff0c;微控制單元&#xff09;?是一種將中央處理器、內存、輸入輸出…

C語言之內存對齊

一、為什么要內存對齊 Arm對內存的訪問支持字&#xff08;4byte&#xff09;、半字&#xff08;2byte&#xff09;、字節&#xff08;1byte&#xff09;的直接訪問&#xff0c;但是呢他們是有一定的要求的&#xff1a; 存取字時要求地址按字對齊&#xff0c;也就是地址要是4的…

Python 基礎語法 -----函數

一、函數 1、函數是什么 編程中的函數和數學中的函數有一定的相似之處。 數學上的函數&#xff0c;比如 y sin x&#xff0c;x 取不同的值&#xff0c;y 就會得到不同的結果。 編程中的函數是一段可以被重復使用的代碼片段。 &#xff08;1&#xff09;求數列的和&#x…

Windows/Linux系統 Ollama部署deepseek 大模型

Ollama 是一個開源工具&#xff0c;專門用于在本地計算機上運行和操作大型語言模型&#xff08;LLM&#xff09; 官方下載網站&#xff08;https://ollama.ai/&#xff09; Windows系統安裝方法 建議命令行安裝&#xff08;默認安裝會直接安裝到C盤&#xff09; OllamaSetu…

用Tensorflow進行線性回歸和邏輯回歸(一)

這一章告訴你如何用TensorFlow構建簡單的機器學習系統。第一部分回顧構建機器學習系統的基礎特別是講函數&#xff0c;連續性&#xff0c;可微性。接著我們介紹損失函數&#xff0c;然后討論機器學習歸根于找到復雜的損失函數最小化的點的能力。我們然后講梯度下降&#xff0c;…

java/.net跨平臺UI瀏覽器SDK,瀏覽器控件開發包分析

在 Linux 系統中&#xff0c;雖然沒有完全等同于安卓 WebView 的內置瀏覽器 SDK&#xff0c;但存在多種基于開源瀏覽器引擎的解決方案&#xff0c;支持通過 Java 代碼控制網頁加載和執行 JavaScript。以下是具體實現方案和技術細節&#xff1a; 一、核心技術方案對比 方案名稱…

Taro 狀態管理全面指南:從本地狀態到全局方案

在跨端應用開發中&#xff0c;狀態管理是構建可維護、可擴展應用的核心環節。作為京東凹凸實驗室推出的多端統一開發框架&#xff0c;Taro 支持 React/Vue 等主流前端框架&#xff0c;自然也繼承了豐富的狀態管理生態。本文將全面剖析 Taro 中的各種狀態管理方案&#xff0c;從…

記錄一下jar做成windows服務問題

1、打包好jar 2、把jdk防止到和jar同一目錄下 3、下載winsw-x64.exe 和 sample-minimal.xml https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exehttps://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe sample-minimal.xmlhttps://…

【Dify 案例】【MCP實戰】【二】【超級助理】

我們創建一個工作流。你是一個超級助理,能夠根據輸入的指令,進行推理和自主調用工具,完成并輸出結果。 注意,需要判斷是否調用高德MCP來獲取對應工具協助你完成任務。 1.開始 2.策略大腦 2.1 AEGNT策略 2.2 工具列表 2.3 指令

Qt Quick 與 QML(二)qml中的頂級窗口

一、前言 在QML中&#xff0c;?頂級窗口不是絕對必需的?&#xff0c;但它在大多數應用場景中扮演著關鍵角色。 需要頂級窗口的典型場景&#xff1a; 1.獨立桌面/移動應用? 必須使用Window或ApplicationWindow作為根元素。 2.多窗口應用 每個獨立窗口都需要一個頂級窗口實例…

華為云Flexus+DeepSeek征文|DeepSeek-V3/R1 免費服務開通全流程與Rest API和OpenAI SDK調用詳解

華為云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 免費服務開通全流程與Rest API和OpenAI SDK調用詳解 前言 本文將詳細介紹DeepSeek-V3/R1 免費服務開通全流程&#xff0c;并且詳細講解通過本地方式Rest API和OpenAI SDK兩種方式調用DeepSeek-V3/R1 前提準備 1、訪問 Mod…