在Mapper层使@Select注解进行SQL语句查询时,往往需要进行参数传入和拼接,一般情况下使用两种占位符#{参数名}和${参数名},两者的区别为:

一、两种占位符的区别

1、参数传入方式的区别

#{}是预编译处理,后台输出的日志会将SQL语句中的#{}占位符输出为?,将传入的Parameter传入SQL语句。

${}是字符串硬替换,会直接将传入的参数直接替换${}占位符,不进行预处理。有SQL注入的风险。

2、参数传入后处理的区别

#{}传入参数后,会自动给参数加上' '(引号),例如:

@Select("select name from user where id = #{id}")
String queryNameById(String id);

在传入id为1001之后,输出的sql为:

select name from user where id ='1001'

${}传入的参数会硬替换字符串,不会有其他处理,例如:

@Select("select name from user where id = ${id}")
String queryNameById(String id);

在传入id为1001后输出的sql是:

select name from user where id = 1001

参数会直接替换${}而不进行其他处理,如果这里你需要给参数加上' ',则需要这么修改代码:

@Select("select name from user where id = '${id}'")
String queryNameById(String id);

这样进行替换后的sql就会变为参数加引号的sql语句。

二、常见报错处理

1、索引超出范围

详细报错为:
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

日志信息报错索引超出范围,可能是因为语句拼接后出现语法错误,往往造成该错误的是对语句中占位符处的引号处理问题。例如:

@Select("select  kunnr,name1 from openquery(hana2,'select top 10 * from SAPHANADB.kna1 where name1 like ''%${name}%'' and name1 not like ''冻结''')")
List<Biz> queryBizListByName(String name);

如果这里使用#{}进行占位符,那么组成的sql会变成 like ''%‘name’%'' and,参数会多一个' '进行包裹,语法就会出错。所以不管是使用concat进行拼接,还是直接进行替换,使用两种占位符时都要根据其使用特点,注意包裹的' ',来达到符合自己SQL语法的使用。在出现“索引超出范围”的报错时,可以通过检查自己sql的语法是否出错,来看看是否可以解决问题。

2、“@P0”附近有语法错误

详细报错为:
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语句中,使用了不支持#{}占位符的函数,例如Top和Order By等函数,是不支持使用#{}占位符的,可以将#{}改为${},使用字符串替换可以解决问题。但要注意#{}改为${}时引号包裹引起的语法问题。

提醒:代码中尽量使用#{}占位符,尽量避免使用${}占位符,因为#{}会更加安全。

MyBatis中使用#{}和${}占位符传递参数的各种报错信息处理的更多相关文章

  1. 在js中window.open通过“post”传递参数

    在js中window.open通过“post”传递参数的步骤如下: 如:在A.jsp中 有一个js方法 winow.open,目标地址是 xx.do 1.在A.jsp建一个form,把要设置的值通过j ...

  2. OC基础教程 C语言中的格式占位符:

    C语言中的格式占位符: %a,%A 读入一个浮点值(仅C99有效) %c 读入一个字符 %d 读入十进制整数 %i 读入十进制,八进制,十六进制整数 %o 读入八进制整数 %x,%X 读入十六进制整数 ...

  3. mvc中view与controll之间传递参数时,可以使用url进行传递

    mvc中view与controller之间传递参数时,可以使用url进行传递,但是在url的地址中需要加上“id=123”这样的东西才行. 具体如代码: window.location.href = ...

  4. 在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案

    1. 单元测试 在单元测试中,每个测试方法都需要执行相同的前置代码和后置代码,则可以自定义2个方法,分别在这2个方法中执行前置代码和后置代码,并为这2个方法添加@Before和@After注解,然后, ...

  5. 快速理解Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容的区别

    <Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?>老猿介绍了二者的区别,为了快速理解,老猿在此使用另外一种方式补充说明一下: 1.使用%r是调用objec ...

  6. Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?

    Python中使用百分号占位符的字符串格式化方法中%s和%r表示需要显示的数据对应变量x会以str(x)还是repr(x)输出内容展示. 关于str和repr的关系请见: <Python中rep ...

  7. idea中 参数没有描述报错 @param XX tag description is missing错误,去除黄色警告

    最近在使用idea开发工具,在方法备注中参数没有描述报错就会报一些黄色警告: @param XX tag description is missing,下面展示去除黄色警告的方法 File--sett ...

  8. MySQL在windows系统中修改datadir路径后无法启动问题,报错1067

    windows server2008下如何更改MySQL数据库的目录的帖子已经很多了,这里简单介绍一个步骤,如果不成功请先查看其它帖子. 更改默认的mysql数据库目录 将 C:\Documents ...

  9. 关于Oxygen版 Eclipse JSP或html 中<option>标签嵌入jstl 如<c:if>出现报错

    Oxygen版 Eclipse JSP或html 中<option>标签嵌入jstl 如<c:if>出现报错 好好的学框架的整合,结果在<option>中加入< ...

  10. 【adb命令】在cmd窗口中使用adb install命令安装 中文名字apk报错的解决办法

    1.在cmd窗口中使用adb install命令安装中文名字apk报错,安装英文名字apk就正常,详细报错如下图: 2.查看adb版本号:adb version 3.怀疑是adb版本的原因,尝试换个最 ...

随机推荐

  1. Jmeter将响应数据的结果保存到本地的一个文件(xls和csv)

    打印excel和csv文件的区别?? 第一种:打印excel 第二种:打印csv文件 创建beanshell后置处理器  import org.json.*;import java.io.*; Str ...

  2. 【RocketMQ】数据的清理机制

    Broker在启动的时候会注册定时任务,定时清理过期的数据,默认是每10s执行一次,分别清理CommitLog文件和ConsumeQueue文件: public class DefaultMessag ...

  3. Android dumpsys介绍

    目录 一.需求 二.环境 三.相关概念 3.1 dumpsys 3.2 Binder 3.3 管道 四.dumpsys指令的使用 4.1 dumpsys使用 4.2 dumpsys指令语法 五.详细设 ...

  4. c#使用正则表达式匹配提取日期

    string target_p ="2021/09/18"; string target_q ="2021-09-18"; 格式yyyy/MM/dd: Matc ...

  5. [Python急救站]草莓熊的绘制

    草莓熊也是一个热门的图案,今天就用Python绘制一下 import turtle as t # 设置背景颜色,窗口位置以及大小 t.colormode(255) # 颜色模式 t.speed(0) ...

  6. postgresql 最近优化的SQL集合案例、(不写过程了只记录案例,PG优化器问题还是不少)

    案例1: -- 原SQL + 执行计划: explain analyze SELECT G.PID, G.FLOW_ID, G.STATUS, G.ID, AAAAAA.INFO_ID, G.CREA ...

  7. java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)

    报错信息:java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符) 解决方案:如下 1.file --> p ...

  8. 2007年对Youtube小视频的分析文章

    Understanding the Characteristics of Internet Short Video Sharing: YouTube as a Case Study 视频的种类 该研究 ...

  9. 【scipy 基础】--图像处理

    SciPy库本身是针对科学计算而不是图像处理的,只是图像处理也包含了很多数学计算,所以Scipy也提供了一个专门的模块ndimage用于图像处理. ndimage模块提供的功能包括输入/输出图像.显示 ...

  10. Java八股面试整理(2)

    11.int和integer有什么区别,两者在做==运算时会得到什么结果? int是基本数据类型,Integer是int的包装类. 二者在做==运算时,Integer会自动拆箱为int类型,然后再进行 ...