MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報錯信息處理方案
在Mapper層使@Select注解進(jìn)行SQL語句查詢時,往往需要進(jìn)行參數(shù)傳入和拼接,一般情況下使用兩種占位符#{參數(shù)名}和${參數(shù)名},兩者的區(qū)別為:
一、兩種占位符的區(qū)別
1、參數(shù)傳入方式的區(qū)別
#{}是預(yù)編譯處理,后臺輸出的日志會將SQL語句中的#{}占位符輸出為?,將傳入的Parameter傳入SQL語句。
${}是字符串硬替換,會直接將傳入的參數(shù)直接替換${}占位符,不進(jìn)行預(yù)處理。有SQL注入的風(fēng)險。
2、參數(shù)傳入后處理的區(qū)別
#{}傳入?yún)?shù)后,會自動給參數(shù)加上' '(引號),例如:
@Select("select name from user where id = #{id}") String queryNameById(String id);
在傳入id為1001之后,輸出的sql為:
select name from user where id ='1001'
${}傳入的參數(shù)會硬替換字符串,不會有其他處理,例如:
@Select("select name from user where id = ${id}") String queryNameById(String id);
在傳入id為1001后輸出的sql是:
select name from user where id = 1001
參數(shù)會直接替換${}而不進(jìn)行其他處理,如果這里你需要給參數(shù)加上' ',則需要這么修改代碼:
@Select("select name from user where id = '${id}'") String queryNameById(String id);
這樣進(jìn)行替換后的sql就會變?yōu)閰?shù)加引號的sql語句。
二、常見報錯處理
1、索引超出范圍
詳細(xì)報錯為:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='name', mode=IN, javaType=class java.lang.String, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 索引 1 超出范圍。] with root cause
日志信息報錯索引超出范圍,可能是因為語句拼接后出現(xiàn)語法錯誤,往往造成該錯誤的是對語句中占位符處的引號處理問題。例如:
@Select("select kunnr,name1 from openquery(hana2,'select top 10 * from SAPHANADB.kna1 where name1 like ''%${name}%'' and name1 not like ''凍結(jié)''')")
List<Biz> queryBizListByName(String name);
如果這里使用#{}進(jìn)行占位符,那么組成的sql會變成 like ''%‘name’%'' and,參數(shù)會多一個' '進(jìn)行包裹,語法就會出錯。所以不管是使用concat進(jìn)行拼接,還是直接進(jìn)行替換,使用兩種占位符時都要根據(jù)其使用特點(diǎn),注意包裹的' ',來達(dá)到符合自己SQL語法的使用。在出現(xiàn)“索引超出范圍”的報錯時,可以通過檢查自己sql的語法是否出錯,來看看是否可以解決問題。
2、“@P0”附近有語法錯誤
詳細(xì)報錯為:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: “@P0”附近有語法錯誤。
日志報這個錯誤,可能是由于你的sql語句中,使用了不支持#{}占位符的函數(shù),例如Top和Order By等函數(shù),是不支持使用#{}占位符的,可以將#{}改為${},使用字符串替換可以解決問題。但要注意#{}改為${}時引號包裹引起的語法問題。
提醒:代碼中盡量使用#{}占位符,盡量避免使用${}占位符,因為#{}會更加安全。
到此這篇關(guān)于MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報錯信息處理的文章就介紹到這了,更多相關(guān)MyBatis #{}和${}占位符傳遞參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis中#{}?和?${}?的區(qū)別和動態(tài)?SQL詳解
- mybatis中${}和#{}的區(qū)別以及底層原理分析
- MyBatis #{}和${} |與數(shù)據(jù)庫連接池使用詳解
- Mybatis關(guān)于動態(tài)排序 #{} ${}問題
- mybatis中#{}和${}的區(qū)別詳解
- MyBatis中#{}和${}有哪些區(qū)別
- mybatis中${}和#{}取值的區(qū)別分析
- MyBatis中#{}占位符與${}拼接符的用法說明
- 詳解Mybatis中的 ${} 和 #{}區(qū)別與用法
- Mybatis之#{}與${}的區(qū)別使用詳解
- Mybatis中#{}與${}的區(qū)別詳解
- MyBatis中 #{} 和 ${} 的區(qū)別小結(jié)
相關(guān)文章
Java 實現(xiàn)多線程切換等待喚醒交替打印奇偶數(shù)
這篇文章主要介紹了Java 實現(xiàn)多線程切換等待喚醒交替打印奇偶數(shù) ,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05Springmvc ViewResolver設(shè)計實現(xiàn)過程解析
這篇文章主要介紹了Springmvc ViewResolver設(shè)計實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10SpringCloud Gateway網(wǎng)關(guān)功能介紹與使用
SpringCloud Gateway 是 Spring Cloud 的一個全新項目,它旨在為微服務(wù)架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式。這篇文章主要介紹了SpringCloud Gateway網(wǎng)關(guān)作用,需要的朋友可以參考下2022-12-12SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實現(xiàn)流程
這篇文章主要介紹了SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10