MyBatis中的占位符入?yún)⑷嬖斀?/h1>
更新時間:2023年03月01日 11:27:11 作者:半夏之沫
這篇文章主要為大家介紹了MyBatis中的占位符全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
前言
#{}占位符會被解析為JDBC中的預編譯語句(Prepared Statement)中的參數(shù)占位符?,一個#{}會被解析為一個?。
${}占位符標識的位置會直接被替換為入?yún)?,是簡單的字符串替換。
本篇文章將結(jié)合不同的入?yún)鼍皩?code>#{}和${}進行分析。
正文
一. 入?yún)⑹腔绢愋筒⑶覅?shù)個數(shù)為1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByNameUseWell(String infoName);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByNameUseDollar(String infoName);
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByNameUseWell" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = #{name}
</select>
<select id="getMyInfoByNameUseDollar" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = '${name}'
</select>
入?yún)⑹腔绢愋停ㄊ纠惺?strong>String類型)且參數(shù)個數(shù)只有一個時,使用#{}和${}占位符均不要求占位符指定的名稱與映射接口中的參數(shù)名相等,但是#{}進行占位符替換后參數(shù)會添加上''號,而${}進行占位符替換是直接進行字符串替換,所以上述示例中,使用${}占位符時需要在占位符兩側(cè)添加''號。
二. 入?yún)⑹腔绢愋筒⑶覅?shù)個數(shù)大于1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByNameTypeUseWell(@Param("infoName") String infoName, @Param("infoType") String infoType);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByNameTypeUseDollar(@Param("infoName") String infoName, @Param("infoType") String infoType);
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByNameTypeUseWell" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = #{infoName} AND info_type = #{infoType}
</select>
<select id="getMyInfoByNameTypeUseDollar" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = '${infoName}' AND info_type = '${infoType}'
</select>
入?yún)⑹腔绢愋颓覅?shù)個數(shù)大于一個時,此時需要在映射接口的方法中使用@Param注解定義參數(shù)的名稱,并且要求占位符指定的名稱需要與@Param注解定義的名稱相等,否則報錯。
三. 入?yún)⑹亲远x類型
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByQueryParamUseWell(QueryParam queryParam);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByQueryParamUseDollar(QueryParam queryParam);
其中自定義類型QueryParam定義如下。
@Data
public class QueryParam {
private String infoName;
private String infoType;
public QueryParam(String infoName, String infoType) {
this.infoName = infoName;
this.infoType = infoType;
}
}
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByQueryParamUseWell" resultMap="myInfoMap"
parameterType="com.learn.mybatis.dynamic.entity.QueryParam">
SELECT * FROM myinfo WHERE info_name = #{infoName} AND info_type = #{infoType}
</select>
<select id="getMyInfoByQueryParamUseDollar" resultMap="myInfoMap"
parameterType="com.learn.mybatis.dynamic.entity.QueryParam">
SELECT * FROM myinfo WHERE info_name = '${infoName}' AND info_type = '${infoType}'
</select>
入?yún)⑹亲远x類型時,占位符指定的名稱需要與自定義類型中的字段名相同,否則報錯。
四. 入?yún)⑹荕ap類型
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByMapUseWell(Map<String, Object> queryParamMap);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByMapUseDollar(Map<String, Object> queryParamMap);
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByMapUseWell" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = #{infoName} AND info_type = #{infoType}
</select>
<select id="getMyInfoByMapUseDollar" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = '${infoName}' AND info_type = '${infoType}'
</select>
入?yún)⑹?strong>Map時,占位符指定的名稱需要與Map的key相等,這樣才能將key對應的value與占位符進行替換。
五. 只能使用${}的場景
通過上面幾點分析,發(fā)現(xiàn)大多數(shù)能夠使用${}占位符的場景都可以使用#{}占位符,而且#{}占位符相比${}占位符還具有能夠防止SQL注入和提高執(zhí)行速度的功能,但是如下幾種場景,只能夠使用${}占位符。
1. 入?yún)⑹潜砻?/h4>
當入?yún)⑹潜砻麜r,此時如果表名的參數(shù)占位符使用#{},會報錯,因為表名不確定時,是無法進行預編譯SQL的,所以這種場景只能使用${}作為表名的參數(shù)占位符。下面是示例。
映射接口中的示例方法定義如下。
// 傳入表名實現(xiàn)動態(tài)創(chuàng)建表
void createMyInfoTable(String tableName);
// 傳入表名動態(tài)指定被查詢的表
MyInfo getMyInfoByNameUseWellDynmic(@Param("tableName") String tableName, @Param("infoName") String infoName);
與之對應的映射文件中的標簽定義如下。
<update id="createMyInfoTable">
CREATE TABLE ${tableName} (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
info_name VARCHAR(255),
info_type ENUM('USER', 'HOUSE', 'CAR'),
info_detail VARCHAR(255),
info_seq INT(11)
)
</update>
<select id="getMyInfoByNameUseWellDynmic" resultMap="myInfoMap">
SELECT * FROM ${tableName} WHERE info_name = #{infoName}
</select>
2. 入?yún)⑹橇忻?/h4>
當入?yún)⑹橇忻麜r,此時也只能使用${}作為列名的參數(shù)占位符。下面是示例。
映射接口中的方法定義如下。
// 為數(shù)據(jù)庫表創(chuàng)建索引
// 表名,索引名,加索引的列的列名全部動態(tài)指定
void createIndex(@Param("tableName") String tableName,
@Param("indexName") String indexName,
@Param("columnNames") List<String> columnNames);
// 對查詢結(jié)果集進行排序并動態(tài)指定排序的列名
List<MyInfo> getMyInfosSorted(String columnName);
與之對應的映射文件中的標簽定義如下。
<update id="createIndex">
CREATE INDEX
${indexName}
ON
${tableName}
<foreach collection="columnNames" item="columnName"
open="(" separator="," close=")">
${columnName}
</foreach>
</update>
<select id="getMyInfosSorted" resultMap="myInfoMap">
SELECT * FROM myinfo ORDER BY ${columnName} DESC
</select>
在為數(shù)據(jù)庫表創(chuàng)建索引的示例中,表名,索引名和加索引的列的列名全部都需要使用${}作為參數(shù)占位符,否則會報錯。在對查詢結(jié)果集進行排序的示例中,如果列名占位符不使用${}而使用#{},不會報錯,但是無法實現(xiàn)根據(jù)指定列進行排序的功能。
總結(jié)
下面對#{}和${}這兩種占位符的使用進行一個總結(jié)。
#{}占位符會被解析為JDBC中的預編譯語句(Prepared Statement)中的參數(shù)占位符?,一個#{}會被解析為一個?,而${}占位符標識的位置會直接被替換為入?yún)?,是簡單的字符串替換;#{}進行占位符替換后參數(shù)會添加上''號,而${}不會;#{}可以防止SQL注入,以及提高SQL語句執(zhí)行效率,而${}不具備這些功能;- 當入?yún)楸砻土忻麜r,需要使用
${}作為表名和列名的參數(shù)占位符。
以上就是MyBatis中的占位符全面詳解的詳細內(nèi)容,更多關于MyBatis占位符的資料請關注腳本之家其它相關文章!
相關文章
-
Springboot整合Mybatis傳值的常用方式總結(jié)
今天給大家?guī)淼氖顷P于Springboot的相關知識,文章圍繞著Springboot整合Mybatis傳值的常用方式展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下 2021-06-06
-
java?-jar命令及SpringBoot通過java?-jav啟動項目的過程
本篇文章將為大家講述關于 SpringBoot 項目工程完成后,是如何通過 java-jar 命令來啟動的,以及介紹 java-jar 命令的詳細內(nèi)容,對SpringBoot java?-jav啟動過程感興趣的朋友跟隨小編一起看看吧 2023-05-05
-
Spring?Boot?使用?Hutool-jwt?實現(xiàn)?token?驗證功能
JWT?就是一種網(wǎng)絡身份認證和信息交換格式,這篇文章主要介紹了Spring Boot使用Hutool-jwt實現(xiàn)token驗證,需要的朋友可以參考下 2023-07-07
-
IntelliJ?IDEA?2022.2最新版本激活教程(親測可用版)永久激活工具分享
Jetbrains官方發(fā)布了?IntelliJ?IDEA2022.2?正式版,每次大的版本更新,都會有較大的調(diào)整和優(yōu)化,除本次更新全面擁抱?Java?17?外,還有對IDE?UI界面,安全性,便捷性等都做了調(diào)整和優(yōu)化完善,用戶體驗提升不少,相信后面會有不少小伙伴跟著更新 2022-08-08
-
SpringBoot部署到外部Tomcat無法注冊到Nacos服務端的解決思路
這篇文章主要介紹了SpringBoot部署到外部Tomcat無法注冊到Nacos服務端,本文給大家分享完美解決思路,結(jié)合實例代碼給大家講解的非常詳細,需要的朋友可以參考下 2023-03-03
-
Java刪除指定文件夾下的所有內(nèi)容的方法(包括此文件夾)
下面小編就為大家?guī)硪黄狫ava刪除指定文件夾下的所有內(nèi)容的方法(包括此文件夾) 。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧 2016-12-12
最新評論
前言
#{}占位符會被解析為JDBC中的預編譯語句(Prepared Statement)中的參數(shù)占位符?,一個#{}會被解析為一個?。
${}占位符標識的位置會直接被替換為入?yún)?,是簡單的字符串替換。
本篇文章將結(jié)合不同的入?yún)鼍皩?code>#{}和${}進行分析。
正文
一. 入?yún)⑹腔绢愋筒⑶覅?shù)個數(shù)為1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByNameUseWell(String infoName);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByNameUseDollar(String infoName);
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByNameUseWell" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = #{name}
</select>
<select id="getMyInfoByNameUseDollar" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = '${name}'
</select>
入?yún)⑹腔绢愋停ㄊ纠惺?strong>String類型)且參數(shù)個數(shù)只有一個時,使用#{}和${}占位符均不要求占位符指定的名稱與映射接口中的參數(shù)名相等,但是#{}進行占位符替換后參數(shù)會添加上''號,而${}進行占位符替換是直接進行字符串替換,所以上述示例中,使用${}占位符時需要在占位符兩側(cè)添加''號。
二. 入?yún)⑹腔绢愋筒⑶覅?shù)個數(shù)大于1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByNameTypeUseWell(@Param("infoName") String infoName, @Param("infoType") String infoType);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByNameTypeUseDollar(@Param("infoName") String infoName, @Param("infoType") String infoType);
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByNameTypeUseWell" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = #{infoName} AND info_type = #{infoType}
</select>
<select id="getMyInfoByNameTypeUseDollar" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = '${infoName}' AND info_type = '${infoType}'
</select>
入?yún)⑹腔绢愋颓覅?shù)個數(shù)大于一個時,此時需要在映射接口的方法中使用@Param注解定義參數(shù)的名稱,并且要求占位符指定的名稱需要與@Param注解定義的名稱相等,否則報錯。
三. 入?yún)⑹亲远x類型
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByQueryParamUseWell(QueryParam queryParam);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByQueryParamUseDollar(QueryParam queryParam);
其中自定義類型QueryParam定義如下。
@Data
public class QueryParam {
private String infoName;
private String infoType;
public QueryParam(String infoName, String infoType) {
this.infoName = infoName;
this.infoType = infoType;
}
}
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByQueryParamUseWell" resultMap="myInfoMap"
parameterType="com.learn.mybatis.dynamic.entity.QueryParam">
SELECT * FROM myinfo WHERE info_name = #{infoName} AND info_type = #{infoType}
</select>
<select id="getMyInfoByQueryParamUseDollar" resultMap="myInfoMap"
parameterType="com.learn.mybatis.dynamic.entity.QueryParam">
SELECT * FROM myinfo WHERE info_name = '${infoName}' AND info_type = '${infoType}'
</select>
入?yún)⑹亲远x類型時,占位符指定的名稱需要與自定義類型中的字段名相同,否則報錯。
四. 入?yún)⑹荕ap類型
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByMapUseWell(Map<String, Object> queryParamMap);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByMapUseDollar(Map<String, Object> queryParamMap);
與之對應的映射文件中的查詢標簽定義如下。
<select id="getMyInfoByMapUseWell" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = #{infoName} AND info_type = #{infoType}
</select>
<select id="getMyInfoByMapUseDollar" resultMap="myInfoMap">
SELECT * FROM myinfo WHERE info_name = '${infoName}' AND info_type = '${infoType}'
</select>
入?yún)⑹?strong>Map時,占位符指定的名稱需要與Map的key相等,這樣才能將key對應的value與占位符進行替換。
五. 只能使用${}的場景
通過上面幾點分析,發(fā)現(xiàn)大多數(shù)能夠使用${}占位符的場景都可以使用#{}占位符,而且#{}占位符相比${}占位符還具有能夠防止SQL注入和提高執(zhí)行速度的功能,但是如下幾種場景,只能夠使用${}占位符。
1. 入?yún)⑹潜砻?/h4>
當入?yún)⑹潜砻麜r,此時如果表名的參數(shù)占位符使用#{},會報錯,因為表名不確定時,是無法進行預編譯SQL的,所以這種場景只能使用${}作為表名的參數(shù)占位符。下面是示例。
映射接口中的示例方法定義如下。
// 傳入表名實現(xiàn)動態(tài)創(chuàng)建表
void createMyInfoTable(String tableName);
// 傳入表名動態(tài)指定被查詢的表
MyInfo getMyInfoByNameUseWellDynmic(@Param("tableName") String tableName, @Param("infoName") String infoName);
與之對應的映射文件中的標簽定義如下。
<update id="createMyInfoTable">
CREATE TABLE ${tableName} (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
info_name VARCHAR(255),
info_type ENUM('USER', 'HOUSE', 'CAR'),
info_detail VARCHAR(255),
info_seq INT(11)
)
</update>
<select id="getMyInfoByNameUseWellDynmic" resultMap="myInfoMap">
SELECT * FROM ${tableName} WHERE info_name = #{infoName}
</select>
2. 入?yún)⑹橇忻?/h4>
當入?yún)⑹橇忻麜r,此時也只能使用${}作為列名的參數(shù)占位符。下面是示例。
映射接口中的方法定義如下。
// 為數(shù)據(jù)庫表創(chuàng)建索引
// 表名,索引名,加索引的列的列名全部動態(tài)指定
void createIndex(@Param("tableName") String tableName,
@Param("indexName") String indexName,
@Param("columnNames") List<String> columnNames);
// 對查詢結(jié)果集進行排序并動態(tài)指定排序的列名
List<MyInfo> getMyInfosSorted(String columnName);
與之對應的映射文件中的標簽定義如下。
<update id="createIndex">
CREATE INDEX
${indexName}
ON
${tableName}
<foreach collection="columnNames" item="columnName"
open="(" separator="," close=")">
${columnName}
</foreach>
</update>
<select id="getMyInfosSorted" resultMap="myInfoMap">
SELECT * FROM myinfo ORDER BY ${columnName} DESC
</select>
在為數(shù)據(jù)庫表創(chuàng)建索引的示例中,表名,索引名和加索引的列的列名全部都需要使用${}作為參數(shù)占位符,否則會報錯。在對查詢結(jié)果集進行排序的示例中,如果列名占位符不使用${}而使用#{},不會報錯,但是無法實現(xiàn)根據(jù)指定列進行排序的功能。
總結(jié)
下面對#{}和${}這兩種占位符的使用進行一個總結(jié)。
#{}占位符會被解析為JDBC中的預編譯語句(Prepared Statement)中的參數(shù)占位符?,一個#{}會被解析為一個?,而${}占位符標識的位置會直接被替換為入?yún)?,是簡單的字符串替換;#{}進行占位符替換后參數(shù)會添加上''號,而${}不會;#{}可以防止SQL注入,以及提高SQL語句執(zhí)行效率,而${}不具備這些功能;- 當入?yún)楸砻土忻麜r,需要使用
${}作為表名和列名的參數(shù)占位符。
以上就是MyBatis中的占位符全面詳解的詳細內(nèi)容,更多關于MyBatis占位符的資料請關注腳本之家其它相關文章!
相關文章
Springboot整合Mybatis傳值的常用方式總結(jié)
今天給大家?guī)淼氖顷P于Springboot的相關知識,文章圍繞著Springboot整合Mybatis傳值的常用方式展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06
java?-jar命令及SpringBoot通過java?-jav啟動項目的過程
本篇文章將為大家講述關于 SpringBoot 項目工程完成后,是如何通過 java-jar 命令來啟動的,以及介紹 java-jar 命令的詳細內(nèi)容,對SpringBoot java?-jav啟動過程感興趣的朋友跟隨小編一起看看吧2023-05-05
Spring?Boot?使用?Hutool-jwt?實現(xiàn)?token?驗證功能
JWT?就是一種網(wǎng)絡身份認證和信息交換格式,這篇文章主要介紹了Spring Boot使用Hutool-jwt實現(xiàn)token驗證,需要的朋友可以參考下2023-07-07
IntelliJ?IDEA?2022.2最新版本激活教程(親測可用版)永久激活工具分享
Jetbrains官方發(fā)布了?IntelliJ?IDEA2022.2?正式版,每次大的版本更新,都會有較大的調(diào)整和優(yōu)化,除本次更新全面擁抱?Java?17?外,還有對IDE?UI界面,安全性,便捷性等都做了調(diào)整和優(yōu)化完善,用戶體驗提升不少,相信后面會有不少小伙伴跟著更新2022-08-08
SpringBoot部署到外部Tomcat無法注冊到Nacos服務端的解決思路
這篇文章主要介紹了SpringBoot部署到外部Tomcat無法注冊到Nacos服務端,本文給大家分享完美解決思路,結(jié)合實例代碼給大家講解的非常詳細,需要的朋友可以參考下2023-03-03
Java刪除指定文件夾下的所有內(nèi)容的方法(包括此文件夾)
下面小編就為大家?guī)硪黄狫ava刪除指定文件夾下的所有內(nèi)容的方法(包括此文件夾) 。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12

