MyBatis中使用#{}和${}占位符传递参数的各种报错信息处理
在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中使用#{}和${}占位符传递参数的各种报错信息处理的更多相关文章
- 在js中window.open通过“post”传递参数
在js中window.open通过“post”传递参数的步骤如下: 如:在A.jsp中 有一个js方法 winow.open,目标地址是 xx.do 1.在A.jsp建一个form,把要设置的值通过j ...
- OC基础教程 C语言中的格式占位符:
C语言中的格式占位符: %a,%A 读入一个浮点值(仅C99有效) %c 读入一个字符 %d 读入十进制整数 %i 读入十进制,八进制,十六进制整数 %o 读入八进制整数 %x,%X 读入十六进制整数 ...
- mvc中view与controll之间传递参数时,可以使用url进行传递
mvc中view与controller之间传递参数时,可以使用url进行传递,但是在url的地址中需要加上“id=123”这样的东西才行. 具体如代码: window.location.href = ...
- 在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案
1. 单元测试 在单元测试中,每个测试方法都需要执行相同的前置代码和后置代码,则可以自定义2个方法,分别在这2个方法中执行前置代码和后置代码,并为这2个方法添加@Before和@After注解,然后, ...
- 快速理解Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容的区别
<Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?>老猿介绍了二者的区别,为了快速理解,老猿在此使用另外一种方式补充说明一下: 1.使用%r是调用objec ...
- Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?
Python中使用百分号占位符的字符串格式化方法中%s和%r表示需要显示的数据对应变量x会以str(x)还是repr(x)输出内容展示. 关于str和repr的关系请见: <Python中rep ...
- idea中 参数没有描述报错 @param XX tag description is missing错误,去除黄色警告
最近在使用idea开发工具,在方法备注中参数没有描述报错就会报一些黄色警告: @param XX tag description is missing,下面展示去除黄色警告的方法 File--sett ...
- MySQL在windows系统中修改datadir路径后无法启动问题,报错1067
windows server2008下如何更改MySQL数据库的目录的帖子已经很多了,这里简单介绍一个步骤,如果不成功请先查看其它帖子. 更改默认的mysql数据库目录 将 C:\Documents ...
- 关于Oxygen版 Eclipse JSP或html 中<option>标签嵌入jstl 如<c:if>出现报错
Oxygen版 Eclipse JSP或html 中<option>标签嵌入jstl 如<c:if>出现报错 好好的学框架的整合,结果在<option>中加入< ...
- 【adb命令】在cmd窗口中使用adb install命令安装 中文名字apk报错的解决办法
1.在cmd窗口中使用adb install命令安装中文名字apk报错,安装英文名字apk就正常,详细报错如下图: 2.查看adb版本号:adb version 3.怀疑是adb版本的原因,尝试换个最 ...
随机推荐
- PyCharm配置autopep8(自动格式化Python代码)
PyCharm配置autopep8(自动格式化Python代码) 1. 关于PEP 8 PEP 8,Style Guide for Python Code,是Python官方推出编码约定,主要是为 ...
- csps区间dp
加分二叉树 我们可以枚举中间这个 k 的位置,然后分别递归计算左右子树,这就让我们想到这是一个和区间有关的,我们可以用区间dp来解决. \(f[i][j]\) 表示 i, j 这个区间的最大分值.用一 ...
- 俄罗斯版IDM安装与破解以及解决B站视频网站不弹出下载浮窗
IDM 全称 Internet Download Manager,是一款非常优秀的多线程下载和视频嗅探工具,不仅可以显著提高文件下载速度,配合IDM浏览器扩展插件,还可以嗅探并下载YouTube.知乎 ...
- 深入理解 Netty FastThreadLocal
作者:vivo 互联网服务器团队- Jiang Zhu 本文以线上诡异问题为切入点,通过对比JDK ThreadLocal和Netty FastThreadLocal实现逻辑以及优缺点,并深入解读源码 ...
- 从输入URL到页面加载完都发生了什么
1.浏览器的地址栏输入URL并按下回车. 2.浏览器查找当前URL是否存在缓存,并比较缓存是否过期. 3.DNS解析URL对应的IP. 4.根据IP建立TCP连接(三次握手). 5.HTTP发起请求. ...
- ACAM 学习笔记 | 附 YbtOJ 全部题解
怎么有人现在才学 ACAM 呢. 好像比 SAM 简单挺多啊,也不记得当时是哪里看不懂. AC 自动机() 自动 AC 机(✘) 概述 ACAM(Aho–Corasick Automaton),是用来 ...
- 云端golang开发,无需本地配置,能上网就能开发和运行
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 需求 学习golang的时候,需要一个IDE,还需要一 ...
- Python 作用域:局部作用域、全局作用域和使用 global 关键字
变量只在创建它的区域内可用.这被称为作用域. 局部作用域 在函数内部创建的变量属于该函数的局部作用域,并且只能在该函数内部使用. 示例:在函数内部创建的变量在该函数内部可用: def myfunc() ...
- 一个基于Vue模型的表单生成器
哈喽,我是老鱼,一名致力于在技术道路上的终身学习者.实践者.分享者! Vuetify Form Base是一个基于模型的表单生成器,目的是提供一个工具,以便以较少的努力从任何模型数据生成可编辑的表单, ...
- 免费领取Python学习资料
话不多说,直接上Python学习资料 QQ·群: 894692354(不单独一一发了,要的人太多,实在忙不过来)