SpringMVC + Mybatis bug调试 SQL正确,查数据库却返回NULL
时间:2022-05-04
本文章向大家介绍SpringMVC + Mybatis bug调试 SQL正确,查数据库却返回NULL,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
今天碰到个bug,有点意思
背景是SpringMVC + Mybatis的一个项目,mapper文件里写了一条sql 大概相当于 select a from tableA where b = "123" 这样的级别
然后不管传进去的是什么 数据库里有没有 都会返回null
第一反应是sql语句写错了,比如把1和小写L弄混了之类的,传给sql的参数里有奇怪的空格等等
于是打开debug log 拿到传给sql的preparedStatement 和对应的参数
复制到console里自己查了一下,可以执行,返回结果也正确,说明不是sql的问题
既然不是sql的问题,那只好调试一下代码了
既然preparedStatement sql能够被打印出来,所以就不从业务逻辑加断点了,直接定位到PreparedStatement类 找到execute方法,上个断点开始单步
单步的时候发现了奇怪的现象,ide提示说源代码和class文件对应行不一致,单步调试时代码在不同行之间乱跳,并且对我正在监视的变量报了一个类中不存在该变量的错
所以怀疑是引用冲突了
接下来确认一下是不是引用了奇怪的类 ,用下面这个方法去定位一下PreparedStatement的位置
public static String where(final Class cls) {
if (cls == null)throw new IllegalArgumentException("null input: cls");
URL result = null;
final String clsAsResource = cls.getName().replace('.', '/').concat(".class");
final ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
final CodeSource cs = pd.getCodeSource();
if (cs != null) result = cs.getLocation();
if (result != null) {
if ("file".equals(result.getProtocol())) {
try {
if (result.toExternalForm().endsWith(".jar") ||
result.toExternalForm().endsWith(".zip"))
result = new URL("jar:".concat(result.toExternalForm())
.concat("!/").concat(clsAsResource));
else if (new File(result.getFile()).isDirectory())
result = new URL(result, clsAsResource);
}
catch (MalformedURLException ignore) {}
}
}
}
if (result == null) {
final ClassLoader clsLoader = cls.getClassLoader();
result = clsLoader != null ?
clsLoader.getResource(clsAsResource) :
ClassLoader.getSystemResource(clsAsResource);
}
return result.toString();
}
在IDEA里 单步时按alt+F8 用where方法去查一下类,发现jvm没有加载我认为的msql-java-connector-5.1.63 而是加载了一个内部类库里的java-connector,定位进去看了一下 确实是写的有问题,原因找到了。
最后到maven依赖里,打开依赖树,找到了加载这个自定义connector的pom条目,配置了<exclusions> ,然后重启项目,解决。
- WordPress后台首页显示RSS错误的解决办法
- ASM 翻译系列第十九弹:ASM Internal ASM Continuing Operations Directory
- ASM 翻译系列第二十五弹:ASM 高级知识 When will my rebalance complete
- ASM 翻译系列第二十六弹:ASM 高级知识 Where is my data
- LVS+Keepalived负载均衡主备&双主架构全攻略
- ASM 翻译系列第二十八弹:ASM INTERNAL Partnership and Status Table
- ASM 翻译系列第二十九弹:ASM INTERNAL Free Space Table
- MySql常用30种SQL查询语句优化方法
- RxJS速成
- 会HTML/CSS就可以轻松创建网站
- 区块链银行应用探索(Hyperledger fabric)
- mysql之基本语法
- mysql之索引的工作机制
- Mysql之锁与事务
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- HaseMap的循环姿势你真的懂了吗?
- 历经14天自定义3个注解解决项目的3个Swagger难题
- VUE开发–获取DOM对象和组件对象(十九)
- RASP攻防 —— RASP安全应用与局限性浅析
- JavaScript 交换值的奇思妙想
- Docker体验(一)
- (二)Hadoop集群配置安装
- 压缩视频
- (四)Java读写文件,合并成新的文件
- 【小白学金融】—— 用 STATA 计算 CAR 值
- 3行核心CSS代码的rate评分组件,秀到你怀疑人生
- 用 Rust 和 N-API 开发高性能 NodeJS 扩展
- 教你 Linux 免密登录配置
- Linux阅码场 - Linux内核月报(2020年08月)
- 事务的本质和死锁的原理