首页 > 其他分享 >MyBatis中使用#{}和${}占位符传递参数的各种报错信息处理

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

时间:2024-01-10 15:48:24浏览次数:32  
标签:name 占位 参数 MyBatis 报错 id String

在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等函数,是不支持使用#{}占位符的,可以将#{}改为${},使用字符串替换可以解决问题。但要注意#{}改为${}时引号包裹引起的语法问题。

 

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

 

标签:name,占位,参数,MyBatis,报错,id,String
From: https://www.cnblogs.com/JIAcheerful/p/17956614

相关文章

  • macOS Ventura 重启报错 panic(cpu 2 caller 0xffffff800f5b4f23)
    本子:macBookpro系统:macOSVentura13.6.3报错:panic(cpu2caller0xffffff800f5b4f23):Kerneltrapat0xffffff800f5af2a0,type14=pagefault,registers:CR0:0x000000008001003b,CR2:0xffffff7fef252228,CR3:0x000000020c00e175,CR4:0x00000000003626e0RAX:0x......
  • Unity3D 原始对象和占位对象详解
    Unity3D是一款强大的跨平台游戏引擎,提供了丰富的功能和工具,方便开发者创建各种类型的游戏。在Unity3D中,原始对象和占位对象是两个重要的概念。本文将详细介绍原始对象和占位对象的概念、技术详解以及代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小......
  • Mybatis 拦截器实现单数据源内多数据库切换 | 京东物流技术团队
    物流的分拣业务在某些分拣场地只有一个数据源,因为数据量比较大,将所有数据存在一张表内查询速度慢,也为了做不同设备数据的分库管理,便在这个数据源内创建了多个不同库名但表完全相同的数据库,如下图所示:现在需要上线报表服务来查询所有数据库中的数据进行统计,那么现在的问题来了,该如何......
  • 【Spring技术专题】「实战开发系列」保姆级教你SpringBoot整合Mybatis框架实现多数据
    Mybatis是什么Mybatis是一个基于JDBC实现的,支持普通SQL查询、存储过程和高级映射的优秀持久层框架,去掉了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。Mybatis主要思想是将程序中大量的SQL语句剥离出来,配置在配置文件中,以实现SQL的灵活配置。在所有ORM框......
  • MyBatis—Spring 动态数据源事务的处理
    在一般的Spring应用中,如果底层数据库访问采用的是MyBatis,那么在大多数情况下,只使用一个单独的数据源,Spring的事务管理在大多数情况下都是有效的。然而,在一些复杂的业务场景下,如需要在某一时刻访问不同的数据库,由于Spring对于事务管理实现的方式,可能不能达到预期的效果。本文......
  • MybatisPlus查询返回Map,其中一个字段为key,另一个字段或者实体为value
    一、需求背景项目中有一些基础数据,以国家为例,字段有国家代码、国家名称、国家面积等等信息。在项目中其他位置需要验证并使用国家数据,比如商品每次批量保存时,只能拿到国家的编码,你需要校验国家是否合法,并把国家的名称面积等字段放到商品表(案例可能不恰当,为了表达业务场景)二、遇到的......
  • SpringBoot: 通过MyBatis访问ClickHouse
    一、ClickHouse中建表,添加数据二、SpringBoot项目添加mybatis、clickhouse、druid相关依赖<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version><......
  • 【错误记录】C++ 字符串常量参数报错 ( 无法将参数 1 从“const char [4]”转换为“ch
    文章目录一、报错信息二、问题分析三、解决方案1、设置VisualStudio的兼容规则2、修改实参类型①3、修改实参类型②4、修改实参类型③5、修改形参类型一、报错信息定义了一个函数,接收char*类型的字符串参数;//接收字符串参数并打印voidfun(char*str){ cout<......
  • springcloud项项目使用脚本启动.sh,报错nested exception is org.apache.ibatis.excep
    问题:项目在使用java-jar启动每个jar包时,项目可正常访问,但要改为使用脚本,启动时,程序就报这个错了nestedexceptionisorg.apache.ibatis.exceptions.PersistenceException:###Errorqueryingdatabase.Cause:com.baomidou.dynamic.datasource.exception.CannotFindDataSource......
  • Dynamics 365 导入Excel报错:Server was unable to process request.
    Dynamics365导入Excel报错:Serverwasunabletoprocessrequest. F12查看调用,发现是调用GetImportMapXml报错,于是到高级设置-数据管理-导入去试试,提示字段Industry未找到,后来找一下字段Industry,居然又3个,一下子就清晰了,是因为有3个字段一样的显示名称,映射不了导致报错 ......