1. 程式人生 > >《深入理解mybatis原理(十二)》 mybatis深入理解之#與$區別

《深入理解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的檢視作用域