《深入理解mybatis原理(十二)》 mybatis深入理解之#與$區別
一、介紹
mybatis 中使用 Mapper.xml裡面的配置進行 sql 查詢,經常需要動態傳遞引數,例如我們需要根據使用者的姓名來篩選使用者時,sql 如下:
select * from user where name = "Jack";
上述 sql 中,我們希望 name 後的引數 "Jack" 是動態可變的,即不同的時刻根據不同的姓名來查詢使用者。在
Mapper.xml檔案中使用如下的 sql 可以實現動態傳遞引數 name:
select * from user where name = #{name};
或者是:
select * from user where name = ${name};
二、$ 與 #
1. 區別 :
動態 SQL 是 mybatis 的強大特性之一,也是它優於其他 ORM 框架的一個重要原因。mybatis 在對 sql 語句進行預編譯之前,會對 sql 進行動態解析,解析為一個 BoundSql 物件,也是在此處對動態 SQL 進行處理的。在動態 SQL 解析階段, #{ } 和 ${ } 會有不同的表現。
#{ }:解析為一個 JDBC 預編譯語句(prepared statement)的引數標記符。
例如,Mapper.xml中如下的 sql 語句:
select * from user where name = #{name};
動態解析為:一個 #{ } 被解析為一個引數佔位符 ? 。select * from user where name = ?;
而${ } 僅僅為一個純碎的 string 替換,在動態 SQL 解析階段將會進行變數替換。
例如,Mapper.xml中如下的 sql:
select * from user where name = ${name};
當我們傳遞的引數為 "Jack" 時,上述 sql 的解析為:select * from user where name = "Jack";
預編譯之前的 SQL 語句已經不包含變量了,完全已經是常量資料了。
綜上所得, ${ } 變數的替換階段是在動態 SQL 解析階段,而 #{ }變數的替換是在 DBMS 中。
三、用法
1、能使用 #{ } 的地方就用 #{ }
首先這是為了效能考慮的,相同的預編譯 sql 可以重複利用。其次,${ } 在預編譯之前已經被變數替換了,這會存在 sql 注入問題。例如,如下的 sql:
select * from ${tableName} where name = #{name}
假如,我們的引數 tableName 為 user; delete user; --,那麼 SQL 動態解析階段之後,預編譯之前的 sql 將變為:
select * from user; delete user; -- where name = ?;
-- 之後的語句將作為註釋,不起作用,因此本來的一條查詢語句偷偷的包含了一個刪除表資料的 SQL。
2. 表名作為變數時,必須使用 ${ }
這是因為,表名是字串,使用 sql 佔位符替換字串時會帶上單引號 '',這會導致 sql 語法錯誤,例如:
select * from #{tableName} where name = #{name};
預編譯之後的sql 變為:select * from ? where name = ?;
假設我們傳入的引數為 tableName = "user" , name = "Jack",那麼在佔位符進行變數替換後,sql 語句變為:
select * from 'user' where name='Jack';
上述 sql 語句是存在語法錯誤的,表名不能加單引號 ''(注意,反引號 ``是可以的)。四、sql預編譯
1. 定義:
sql 預編譯指的是資料庫驅動在傳送 sql 語句和引數給 DBMS 之前對 sql 語句進行編譯,這樣 DBMS 執行 sql 時,就不需要重新編譯。
2. 為什麼需要預編譯
JDBC 中使用物件 PreparedStatement 來抽象預編譯語句,使用預編譯。預編譯階段可以優化 sql 的執行。預編譯之後的 sql 多數情況下可以直接執行,DBMS 不需要再次編譯,越複雜的sql,編譯的複雜度將越大,預編譯階段可以合併多次操作為一個操作。預編譯語句物件可以重複利用。把一個 sql 預編譯後產生的 PreparedStatement 物件快取下來,下次對於同一個sql,可以直接使用這個快取的 PreparedState 物件。mybatis 預設情況下,將對所有的 sql 進行預編譯。
相關推薦
《深入理解mybatis原理(十二)》 mybatis深入理解之#與$區別
一、介紹 mybatis 中使用 Mapper.xml裡面的配置進行 sql 查詢,經常需要動態傳遞引數,例如我們需要根據使用者的姓名來篩選使用者時,sql 如下: select * from user where name = "Jack";上述 sql 中,我們希
《深入理解mybatis原理(三)》 MyBatis的一級快取實現詳解 及使用注意事項
0.寫在前面 MyBatis是一個簡單,小巧但功能非常強大的ORM開源框架,它的功能強大也體現在它的快取機制上。MyBatis提供了一級快取、二級快取 這兩個快取機制,能夠很好地處理和維護快取,以提高系統的效能。本文的目的則是向讀者詳細介紹MyBatis的一級快取,深入原始碼,解析MyBa
《深入理解mybatis原理(七)》 MyBatis的架構設計以及例項分析
MyBatis是目前非常流行的ORM框架,它的功能很強大,然而其實現卻比較簡單、優雅。本文主要講述MyBatis的架構設計思路,並且討論MyBatis的幾個核心部件,然後結合一個select查詢例項,深入程式碼,來探究MyBatis的實現。 一、MyBatis的框架設計
深入剖析 mybatis 原理(二)
# 前言 在上篇文章中我們分析了 sqlSession.selectOne(“org.apache.ibatis.mybatis.UserInfoMapper.selectById”, parameter) 程式碼的執行過程,我們說,這種方式雖然更接近 myb
《深入理解mybatis原理7》 MyBatis的二級緩存的設計原理
data 是否 cat sch 定義 劃分 sel 博文 算法 《深入理解mybatis原理》 MyBatis的二級緩存的設計原理 MyBatis的二級緩存是Application級別的緩存,它可以提高對數據庫查詢的效率,以提高應用的性能。本文將全面分析MyBatis的二級
《深入理解mybatis原理4》 MyBatis緩存機制的設計與實現
針對 ces 機制 實現 ssi 查看 緩存機制 內存 完成 《深入理解mybatis原理》 MyBatis緩存機制的設計與實現 本文主要講解MyBatis非常棒的緩存機制的設計原理,給讀者們介紹一下MyBatis的緩存機制的輪廓,然後會分別針對緩存機制中的方方面面展開討論
《深入理解mybatis原理1》 MyBatis的架構設計以及實例分析
etx parent type start clean odin del 個數 eth 《深入理解mybatis原理》 MyBatis的架構設計以及實例分析 MyBatis是目前非常流行的ORM框架,它的功能很強大,然而其實現卻比較簡單、優雅。本文主要講述MyBatis
《深入理解mybatis原理3》 Mybatis數據源與連接池
Opens red and 分享 使用 wait dstat void var 《深入理解mybatis原理》 Mybatis數據源與連接池 對於ORM框架而言,數據源的組織是一個非常重要的一部分,這直接影響到框架的性能問題。本文將通過對MyBatis框架的數據源結構進行
《深入理解mybatis原理2》 Mybatis初始化機制詳解
and 文件創建 builder模式 處理器 XML iou info pro 兩種 《深入理解mybatis原理》 Mybatis初始化機制詳解 對於任何框架而言,在使用前都要進行一系列的初始化,MyBatis也不例外。本章將通過以下幾點詳細介紹MyBatis的初始化過
《深入理解mybatis原理6》 MyBatis的一級緩存實現詳解 及使用註意事項
net 特征值 session 成了 bool common 周期 當下 csdn 《深入理解mybatis原理》 MyBatis的一級緩存實現詳解 及使用註意事項 0.寫在前面 MyBatis是一個簡單,小巧但功能非常強大的ORM開源框架,它的功能強大也體現在它的
框架學習系列 mybatis 第十二篇 mapper映射文件之輸出映射
總結 www. XML 聲明 com 2.4 res rom 用戶 1: mapper映射文件輸出映射(輸入類型) 2:resultType的使用 3:resultMap的使用 3:總結&下節預告 本文是《凱哥陪你學系列-框架學習之mybatis框架學習》中第十二篇
企業分布式微服務雲SpringCloud SpringBoot mybatis (十二)斷路器監控(Hystrix Dashboard)
dash blog sta line The cat fcm 圖形 微服務 在我的第四篇文章斷路器講述了如何使用斷路器,並簡單的介紹了下Hystrix Dashboard組件,這篇文章更加詳細的介紹Hystrix Dashboard。 一、Hystrix Dashboar
Java程序員從笨鳥到菜鳥之(九十二)深入java虛擬機(一)——java虛擬機底層結構詳解
行為 計數 驗證 堆棧 第一個 精度 amp 語言 eight 本文來自:曹勝歡博客專欄。轉載請註明出處:http://blog.csdn.net/csh624366188 歡迎關註微信賬號:java那些事:csh624366188.每天一篇java相關的文
How Javascript works (Javascript工作原理) (十二) 網絡層探秘及如何提高其性能和安全性
work 隨機 edi 部分 提高 會話狀態 具體細節 內容 自我學習 個人總結:閱讀完這篇文章需要20分鐘,這篇文章主要講解了現代瀏覽器在網絡層傳輸所用到的一些技術。 這是 JavaScript 工作原理的第十二章。 正如在之前關於渲染引擎的文章中所講的那樣,我們相信
21天轉型容器實戰營(十二容器進階之Kubernetes 儲存管理原理分析)
大綱 為何需要儲存卷? 普通儲存卷 應用中使用普通卷 持久化儲存卷(PV) 持久化儲存卷申明(PVC) 應用中使用持久化卷 為何需要儲存卷? 容器部署過程中一般有以下三種資料: - 啟動時需要的初始資料,可以是配置檔案 - 啟動過程中產生的臨時資料,該臨時資料需要多個容器間共享 - 啟動過程中產
Spring3.1.0實現原理分析(二十二).Dao事務分析之事務管理器DataSourceTransactionManager
大家好,開篇先來談談spring事務的優點吧,即spring事務的存在價值。首先它提供了非侵入式編碼的事務實現,這個是通過aop實現的,具體的實現過程之前也寫部落格分析了。 另外,spring還提供了一套標準的事務管理工作流程。簡單的說,事務管理
Jmeter(三十二)Jmeter Question 之 亂碼解讀
直接 默認 進行 json 字符 blog 文件中 內容 錄制完成 眾所周知,編碼的問題影響著眾多開發者,當然見多不怪。 先扒了一個編碼的原因,也就是為什麽要編碼: 計算機中存儲信息的最小單元是一個字節即 8 個 bit,所以能表示的字符範圍是 0~255 個 人
第十二章-語義分析之語法糖去除
nbsp 語法糖 .com 增強for循環 sco 循環 .cn spa access 參考以下博文: (1)Javac語法糖之內部類 (2)Javac語法糖之EnumSwitch (3)Javac語法糖之TryCatchFinally (4)Javac語法糖之增強f
三十二、python學習之Flask框架(四)模板:jinja2模板、過濾器、模板複用(繼承、巨集、包含)、瞭解CSRF跨站請求攻擊
一、jinja2模板引擎的簡介: 1.模板: 1.1檢視函式的兩個作用: 處理業務邏輯; 返回響應內容; 1.3 什麼是模板: 模板其實是一個包含響應文字的檔案,不是特指的html檔案,其中用佔位符(變數)表示動態部分,告訴模板引擎其具體的
Jmeter (十二)除錯工具之--Debug Processor(轉載)
前置處理器或後置處理器中的 Debug Processor,也是常用的一個除錯工具,其可以獲取樣本執行緒的相關資訊進行展示,可通過檢視結果樹中的響應資料檢視對應樣本執行緒請求、響應及變數等資訊。在檢視的時候注意 Debug PostProcessor的檢視作用域