文章目录
- 1. 引出问题
- 2. 分析问题
- 3. 解决问题
- 4. 解决该问题的其他方法
- 4.1 方法1
- 4.2 方法2
- 4.3 方法3
- 4.4 方法4
如果你遇到的问题不是我所遇到的问题,可以使用最下面的方法解决你遇到的这个错误。
1. 引出问题
今天在写“Mybatis-Plus
中分页插件PaginationInterceptor, MybatisPlusInterceptor
在SpringBoot
中的使用”的博文时,遇到了如下问题:
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@498d7c57] will not be managed by Spring
==> Preparing: SELECT COUNT(*) AS total FROM user
==> Parameters:
<== Columns: total
<== Row: 24
<== Total: 1
==> Preparing: select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6f5c4fa1]
org.springframework.jdbc.UncategorizedSQLException:
### Error querying database. Cause: java.sql.SQLException: sql injection violation, dbType mysql, , druid-version 1.2.11, syntax error: not supported.pos 89, line 1, column 85, token LIMIT : select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?
### The error may exist in com/cloud/lowcode/mapper/UserMapper.java (best guess)
### The error may involve com.cloud.lowcode.mapper.UserMapper.findPageUsers
### The error occurred while executing a query
### SQL: select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?
### Cause: java.sql.SQLException: sql injection violation, dbType mysql, , druid-version 1.2.11, syntax error: not supported.pos 89, line 1, column 85, token LIMIT : select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?
; uncategorized SQLException; SQL state [null]; error code [0]; sql injection violation, dbType mysql, , druid-version 1.2.11, syntax error: not supported.pos 89, line 1, column 85, token LIMIT : select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?; nested exception is java.sql.SQLException: sql injection violation, dbType mysql, , druid-version 1.2.11, syntax error: not supported.pos 89, line 1, column 85, token LIMIT : select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
at com.sun.proxy.$Proxy157.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:166)
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
at com.sun.proxy.$Proxy161.findPageUsers(Unknown Source)
at com.cloud.lowcode.service.UserService.findPageUsers(UserService.java:52)
at com.cloud.lowcode.service.UserService$$FastClassBySpringCGLIB$$dd31034.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.cloud.lowcode.service.UserService$$EnhancerBySpringCGLIB$$c454c3ba.findPageUsers(<generated>)
at com.cloud.lowcode.controller.UserController.findPageUsers(UserController.java:71)
at com.cloud.lowcode.controller.UserController$$FastClassBySpringCGLIB$$6a5c21dc.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
at com.cloud.lowcode.controller.UserController$$EnhancerBySpringCGLIB$$bf8624f6.findPageUsers(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
......
2. 分析问题
通过报错信息sql injection violation
可知SQL
注入冲突,是哪里发生了冲突呢?别着急,继续往下分析报错的SQL
语句:
select username,nickname,user_type as userType from user order by create_time desc; LIMIT ?,?
原来SQL语句出现了错误,即在reate_time desc
和LIMIT ?,?
出现了;
。
正因为这个分号导致SQL执行异常,然而我的原SQL语句并没写LIMIT ?,?
,如下代码所示:
@Select("select " +
"username,nickname,user_type as userType " +
"from " +
"user " +
"order by " +
"create_time desc;"
)
可以清晰地看到,我的SQL语句加上了分号,但没有LIMIT ?,?
。
通过查找资料可得:在使用PaginationInterceptor, MybatisPlusInterceptor
插件做分页操作时,编写mapper.xml
中的SQL
语句时,或者使用@select
注解编写SQL
语句时,语句末尾若使用 ;
结尾,则会导致出现SQL
语法错误(SQLSyntaxErrorException
),原因是在做分页的时候会在编写的SQL
语句后面拼接上limit
语句。
3. 解决问题
既然语句末尾不能加:
,则去掉分号;
即可,如下代码所示:
@Select("select " +
"username,nickname,user_type as userType " +
"from " +
"user " +
"order by " +
"create_time desc"
)
List<UserPageVo> findPageUsers(Page<UserPageVo> page);
重新运行项目即可执行成功,如下图所示:
4. 解决该问题的其他方法
如果你遇到的问题不是我所遇到的问题,可以使用如下方法解决你遇到的这个错误。
4.1 方法1
检查字段类型是否对得上。因为字段类型对应不上,在数据库的类型和实体中的类型不一致。
比如user_id
在数据库中是varchar
类型,但在实体中是Integer
。
4.2 方法2
检查字段名称是否对得上,有可能在java实体
中的注解名称在数据库中不存在。
比如数据库中的字段是user_type
,而注解中的字段是userType
,如下代码所示:
@TableField(value = "userType")
private String userType;
当然,如果java实体
中不指定数据库的字段名称,则默认以属性名称对应数据库的字段名称,往往这种会出现这个错误(UncategorizedSQLException
)。
4.3 方法3
检查数据库的表字段是否有限制。
例如是UNI(唯一)
、非空等限制都会导致出现此问题。
4.4 方法4
检查表字符集是否有问题。
例如表字符集是utf8
,但提交的内容有表情,改成utf8mb4
即可。
备注:如果上述方法都无法解决你的问题,欢迎在评论区留言。