MyBatis中的占位符入?yún)⑷嬖斀?/h1>
更新時(shí)間:2023年03月01日 11:27:11 作者:半夏之沫
這篇文章主要為大家介紹了MyBatis中的占位符全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
前言
#{}
占位符會(huì)被解析為JDBC中的預(yù)編譯語(yǔ)句(Prepared Statement)中的參數(shù)占位符?
,一個(gè)#{}
會(huì)被解析為一個(gè)?
。
${}
占位符標(biāo)識(shí)的位置會(huì)直接被替換為入?yún)ⅲ呛?jiǎn)單的字符串替換。
本篇文章將結(jié)合不同的入?yún)?chǎng)景對(duì)#{}
和${}
進(jìn)行分析。
正文
一. 入?yún)⑹腔绢愋筒⑶覅?shù)個(gè)數(shù)為1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByNameUseWell(String infoName);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByNameUseDollar(String infoName);
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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ù)個(gè)數(shù)只有一個(gè)時(shí),使用#{}
和${}
占位符均不要求占位符指定的名稱與映射接口中的參數(shù)名相等,但是#{}
進(jìn)行占位符替換后參數(shù)會(huì)添加上''
號(hào),而${}
進(jìn)行占位符替換是直接進(jìn)行字符串替換,所以上述示例中,使用${}
占位符時(shí)需要在占位符兩側(cè)添加''
號(hào)。
二. 入?yún)⑹腔绢愋筒⑶覅?shù)個(gè)數(shù)大于1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByNameTypeUseWell(@Param("infoName") String infoName, @Param("infoType") String infoType);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByNameTypeUseDollar(@Param("infoName") String infoName, @Param("infoType") String infoType);
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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ù)個(gè)數(shù)大于一個(gè)時(shí),此時(shí)需要在映射接口的方法中使用@Param注解定義參數(shù)的名稱,并且要求占位符指定的名稱需要與@Param注解定義的名稱相等,否則報(bào)錯(cuò)。
三. 入?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;
}
}
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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類型時(shí),占位符指定的名稱需要與自定義類型中的字段名相同,否則報(bào)錯(cuò)。
四. 入?yún)⑹荕ap類型
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符
MyInfo getMyInfoByMapUseWell(Map<String, Object> queryParamMap);
// 使用${}作為參數(shù)占位符
MyInfo getMyInfoByMapUseDollar(Map<String, Object> queryParamMap);
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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時(shí),占位符指定的名稱需要與Map的key相等,這樣才能將key對(duì)應(yīng)的value與占位符進(jìn)行替換。
五. 只能使用${}的場(chǎng)景
通過(guò)上面幾點(diǎn)分析,發(fā)現(xiàn)大多數(shù)能夠使用${}
占位符的場(chǎng)景都可以使用#{}
占位符,而且#{}
占位符相比${}
占位符還具有能夠防止SQL注入和提高執(zhí)行速度的功能,但是如下幾種場(chǎng)景,只能夠使用${}
占位符。
1. 入?yún)⑹潜砻?/h4>
當(dāng)入?yún)⑹潜砻麜r(shí),此時(shí)如果表名的參數(shù)占位符使用#{}
,會(huì)報(bào)錯(cuò),因?yàn)楸砻淮_定時(shí),是無(wú)法進(jìn)行預(yù)編譯SQL的,所以這種場(chǎng)景只能使用${}
作為表名的參數(shù)占位符。下面是示例。
映射接口中的示例方法定義如下。
// 傳入表名實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建表
void createMyInfoTable(String tableName);
// 傳入表名動(dòng)態(tài)指定被查詢的表
MyInfo getMyInfoByNameUseWellDynmic(@Param("tableName") String tableName, @Param("infoName") String infoName);
與之對(duì)應(yīng)的映射文件中的標(biāo)簽定義如下。
<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>
當(dāng)入?yún)⑹橇忻麜r(shí),此時(shí)也只能使用${}
作為列名的參數(shù)占位符。下面是示例。
映射接口中的方法定義如下。
// 為數(shù)據(jù)庫(kù)表創(chuàng)建索引
// 表名,索引名,加索引的列的列名全部動(dòng)態(tài)指定
void createIndex(@Param("tableName") String tableName,
@Param("indexName") String indexName,
@Param("columnNames") List<String> columnNames);
// 對(duì)查詢結(jié)果集進(jìn)行排序并動(dòng)態(tài)指定排序的列名
List<MyInfo> getMyInfosSorted(String columnName);
與之對(duì)應(yīng)的映射文件中的標(biāo)簽定義如下。
<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ù)庫(kù)表創(chuàng)建索引的示例中,表名,索引名和加索引的列的列名全部都需要使用${}
作為參數(shù)占位符,否則會(huì)報(bào)錯(cuò)。在對(duì)查詢結(jié)果集進(jìn)行排序的示例中,如果列名占位符不使用${}
而使用#{}
,不會(huì)報(bào)錯(cuò),但是無(wú)法實(shí)現(xiàn)根據(jù)指定列進(jìn)行排序的功能。
總結(jié)
下面對(duì)#{}
和${}
這兩種占位符的使用進(jìn)行一個(gè)總結(jié)。
#{}
占位符會(huì)被解析為JDBC中的預(yù)編譯語(yǔ)句(Prepared Statement)中的參數(shù)占位符?
,一個(gè)#{}
會(huì)被解析為一個(gè)?
,而${}
占位符標(biāo)識(shí)的位置會(huì)直接被替換為入?yún)ⅲ呛?jiǎn)單的字符串替換;#{}
進(jìn)行占位符替換后參數(shù)會(huì)添加上''
號(hào),而${}
不會(huì);#{}
可以防止SQL注入,以及提高SQL語(yǔ)句執(zhí)行效率,而${}
不具備這些功能;- 當(dāng)入?yún)楸砻土忻麜r(shí),需要使用
${}
作為表名和列名的參數(shù)占位符。
以上就是MyBatis中的占位符全面詳解的詳細(xì)內(nèi)容,更多關(guān)于MyBatis占位符的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
-
SpringBoot應(yīng)用啟動(dòng)過(guò)程分析
這篇文章主要介紹了SpringBoot應(yīng)用啟動(dòng)過(guò)程分析,需要的朋友可以參考下 2017-08-08
-
java.lang.IllegalStateException:方法有太多主體參數(shù)問(wèn)題
這篇文章主要介紹了java.lang.IllegalStateException:方法有太多主體參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2024-07-07
-
Spring Boot 簡(jiǎn)介(入門(mén)篇)
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程。下面通過(guò)本文給大家介紹spring boot相關(guān)知識(shí),需要的的朋友參考下吧 2017-04-04
-
Java中的時(shí)間日期API知識(shí)點(diǎn)總結(jié)
本文給大家總結(jié)了Java中的時(shí)間日期API知識(shí)點(diǎn)以及相關(guān)的實(shí)例代碼分享,有興趣的朋友參考學(xué)習(xí)下。 2018-04-04
-
springboot2.6.3讀取不到nacos上的配置文件問(wèn)題
這篇文章主要介紹了springboot2.6.3讀取不到nacos上的配置文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2023-07-07
-
Java實(shí)現(xiàn)畫(huà)圖 給圖片底部添加文字標(biāo)題
這篇文章主要介紹了Java實(shí)現(xiàn)畫(huà)圖 給圖片底部添加文字標(biāo)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2021-11-11
最新評(píng)論
前言
#{}
占位符會(huì)被解析為JDBC中的預(yù)編譯語(yǔ)句(Prepared Statement)中的參數(shù)占位符?
,一個(gè)#{}
會(huì)被解析為一個(gè)?
。
${}
占位符標(biāo)識(shí)的位置會(huì)直接被替換為入?yún)ⅲ呛?jiǎn)單的字符串替換。
本篇文章將結(jié)合不同的入?yún)?chǎng)景對(duì)#{}
和${}
進(jìn)行分析。
正文
一. 入?yún)⑹腔绢愋筒⑶覅?shù)個(gè)數(shù)為1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符 MyInfo getMyInfoByNameUseWell(String infoName); // 使用${}作為參數(shù)占位符 MyInfo getMyInfoByNameUseDollar(String infoName);
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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ù)個(gè)數(shù)只有一個(gè)時(shí),使用#{}
和${}
占位符均不要求占位符指定的名稱與映射接口中的參數(shù)名相等,但是#{}
進(jìn)行占位符替換后參數(shù)會(huì)添加上''
號(hào),而${}
進(jìn)行占位符替換是直接進(jìn)行字符串替換,所以上述示例中,使用${}
占位符時(shí)需要在占位符兩側(cè)添加''
號(hào)。
二. 入?yún)⑹腔绢愋筒⑶覅?shù)個(gè)數(shù)大于1
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符 MyInfo getMyInfoByNameTypeUseWell(@Param("infoName") String infoName, @Param("infoType") String infoType); // 使用${}作為參數(shù)占位符 MyInfo getMyInfoByNameTypeUseDollar(@Param("infoName") String infoName, @Param("infoType") String infoType);
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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ù)個(gè)數(shù)大于一個(gè)時(shí),此時(shí)需要在映射接口的方法中使用@Param注解定義參數(shù)的名稱,并且要求占位符指定的名稱需要與@Param注解定義的名稱相等,否則報(bào)錯(cuò)。
三. 入?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; } }
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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類型時(shí),占位符指定的名稱需要與自定義類型中的字段名相同,否則報(bào)錯(cuò)。
四. 入?yún)⑹荕ap類型
映射接口中查詢單條記錄的方法定義如下。
// 使用#{}作為參數(shù)占位符 MyInfo getMyInfoByMapUseWell(Map<String, Object> queryParamMap); // 使用${}作為參數(shù)占位符 MyInfo getMyInfoByMapUseDollar(Map<String, Object> queryParamMap);
與之對(duì)應(yīng)的映射文件中的查詢標(biāo)簽定義如下。
<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時(shí),占位符指定的名稱需要與Map的key相等,這樣才能將key對(duì)應(yīng)的value與占位符進(jìn)行替換。
五. 只能使用${}的場(chǎng)景
通過(guò)上面幾點(diǎn)分析,發(fā)現(xiàn)大多數(shù)能夠使用${}
占位符的場(chǎng)景都可以使用#{}
占位符,而且#{}
占位符相比${}
占位符還具有能夠防止SQL注入和提高執(zhí)行速度的功能,但是如下幾種場(chǎng)景,只能夠使用${}
占位符。
1. 入?yún)⑹潜砻?/h4>
當(dāng)入?yún)⑹潜砻麜r(shí),此時(shí)如果表名的參數(shù)占位符使用#{}
,會(huì)報(bào)錯(cuò),因?yàn)楸砻淮_定時(shí),是無(wú)法進(jìn)行預(yù)編譯SQL的,所以這種場(chǎng)景只能使用${}
作為表名的參數(shù)占位符。下面是示例。
映射接口中的示例方法定義如下。
// 傳入表名實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建表 void createMyInfoTable(String tableName); // 傳入表名動(dòng)態(tài)指定被查詢的表 MyInfo getMyInfoByNameUseWellDynmic(@Param("tableName") String tableName, @Param("infoName") String infoName);
與之對(duì)應(yīng)的映射文件中的標(biāo)簽定義如下。
<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>
當(dāng)入?yún)⑹橇忻麜r(shí),此時(shí)也只能使用${}
作為列名的參數(shù)占位符。下面是示例。
映射接口中的方法定義如下。
// 為數(shù)據(jù)庫(kù)表創(chuàng)建索引 // 表名,索引名,加索引的列的列名全部動(dòng)態(tài)指定 void createIndex(@Param("tableName") String tableName, @Param("indexName") String indexName, @Param("columnNames") List<String> columnNames); // 對(duì)查詢結(jié)果集進(jìn)行排序并動(dòng)態(tài)指定排序的列名 List<MyInfo> getMyInfosSorted(String columnName);
與之對(duì)應(yīng)的映射文件中的標(biāo)簽定義如下。
<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ù)庫(kù)表創(chuàng)建索引的示例中,表名,索引名和加索引的列的列名全部都需要使用${}
作為參數(shù)占位符,否則會(huì)報(bào)錯(cuò)。在對(duì)查詢結(jié)果集進(jìn)行排序的示例中,如果列名占位符不使用${}
而使用#{}
,不會(huì)報(bào)錯(cuò),但是無(wú)法實(shí)現(xiàn)根據(jù)指定列進(jìn)行排序的功能。
總結(jié)
下面對(duì)#{}
和${}
這兩種占位符的使用進(jìn)行一個(gè)總結(jié)。
#{}
占位符會(huì)被解析為JDBC中的預(yù)編譯語(yǔ)句(Prepared Statement)中的參數(shù)占位符?
,一個(gè)#{}
會(huì)被解析為一個(gè)?
,而${}
占位符標(biāo)識(shí)的位置會(huì)直接被替換為入?yún)ⅲ呛?jiǎn)單的字符串替換;#{}
進(jìn)行占位符替換后參數(shù)會(huì)添加上''
號(hào),而${}
不會(huì);#{}
可以防止SQL注入,以及提高SQL語(yǔ)句執(zhí)行效率,而${}
不具備這些功能;- 當(dāng)入?yún)楸砻土忻麜r(shí),需要使用
${}
作為表名和列名的參數(shù)占位符。
以上就是MyBatis中的占位符全面詳解的詳細(xì)內(nèi)容,更多關(guān)于MyBatis占位符的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot應(yīng)用啟動(dòng)過(guò)程分析
這篇文章主要介紹了SpringBoot應(yīng)用啟動(dòng)過(guò)程分析,需要的朋友可以參考下2017-08-08java.lang.IllegalStateException:方法有太多主體參數(shù)問(wèn)題
這篇文章主要介紹了java.lang.IllegalStateException:方法有太多主體參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Spring Boot 簡(jiǎn)介(入門(mén)篇)
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程。下面通過(guò)本文給大家介紹spring boot相關(guān)知識(shí),需要的的朋友參考下吧2017-04-04Java中的時(shí)間日期API知識(shí)點(diǎn)總結(jié)
本文給大家總結(jié)了Java中的時(shí)間日期API知識(shí)點(diǎn)以及相關(guān)的實(shí)例代碼分享,有興趣的朋友參考學(xué)習(xí)下。2018-04-04springboot2.6.3讀取不到nacos上的配置文件問(wèn)題
這篇文章主要介紹了springboot2.6.3讀取不到nacos上的配置文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07Java實(shí)現(xiàn)畫(huà)圖 給圖片底部添加文字標(biāo)題
這篇文章主要介紹了Java實(shí)現(xiàn)畫(huà)圖 給圖片底部添加文字標(biāo)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11