关于mysql驱动包的in语句的bug
今天发现一个MySQL驱动包执行in语句的一个bug,也许会有很多人还不知道,那么跟大家分享一下。
驱动包版本:mysql-connector-java-5.1.36.jar
在使用dbutils执行sql语句的时候,遇到这样的sql:
select * from 表名 where 字段名 in (?)
如果你是这样写的,那肯定查询不到你想要的结果,验证此问题只在mysql上存在,如果传进去的是一个字符串,那么你将得到一个这样的一个预编译sql:
select * from 表名 where 字段名 in ('真实值,真实值...');
这样只会查询出在in里面第一个真实值匹配的结果。
下面代码说明
更改前我的代码
List<Long> articleIds = ArticleTag.INSTANCE.findByTagId(tagId);
StringBuilder sb = new StringBuilder();
for (Long id : articleIds) {
sb.append(id + ",");
}
String idString = null;
//去掉末尾的","
if (sb.length() > 1) {
idString = sb.substring(0, sb.length() - 1).toString();
} else {
return new ArrayList<Article>(0);
}
List<Long> ids = getIds("trash = 0 AND status = '" + Article.Status.PUBLISH
+ "' AND id in (?) ORDER BY id DESC",
idString);
上面是执行查询的代码,参数idString是一个字符串,getIds()方法调用底层QueryRunner的query();
查询底层实现看下dbutils的关于QueryRunner的query源码(源码太多,挑重点看一下):
stmt = this.prepareStatement(conn, sql);
this.fillStatement(stmt, params);
rs = this.wrap(stmt.executeQuery());
result = rsh.handle(rs);
在使用fillStatement设置参数的时候,执行下面源码(依然挑重点)
if(!var14) {
var15 = null;
parameterAsBytes = new StringBuilder(x.length() + 2);
parameterAsBytes.append('\'');
parameterAsBytes.append(x);
parameterAsBytes.append('\'');
if(!this.isLoadDataQuery) {
var16 = StringUtils.getBytes(parameterAsBytes.toString(), this.charConverter, this.charEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), this.getExceptionInterceptor());
} else {
var16 = StringUtils.getBytes(parameterAsBytes.toString());
}
我们可以看到底层会将你传递进来的参数加上’’,并没有针对区分,所以SQL语句如上面我们说的in(’真实值,真实值…’)。这就导致了查询数据错误。
网上查询了说传数组进去,仔细想想也不靠谱。后来发现只能将?作为变量拼接进sql才能解决。
更改后代码:
List<Long> articleIds = ArticleTag.INSTANCE.findByTagId(tagId);
StringBuilder sb = new StringBuilder();
StringBuffer params = new StringBuffer();
for (Long id : articleIds) {
sb.append(id + ",");
params.append("?,");
}
String idString = null;
String paramsStr = null;
String[] str = new String[sb.length()];
//去掉末尾的","
if (sb.length() > 1) {
idString = sb.substring(0, sb.length() - 1).toString();
paramsStr = params.substring(0, params.length() - 1).toString();
str = idString.split(",");
} else {
return new ArrayList<Article>(0);
}
List<Long> ids = getIds("trash = 0 AND status = '" + Article.Status.PUBLISH
+ "' AND id in ("+paramsStr+") ORDER BY id DESC",
str);
将?也作为变量根据参数的个数动态拼接到sql里,这样问题就解决了,当然这也只是我的做法,如果大家有更好的做法,希望留言互相讨论,也希望这个bug能够修复。
转载地址:河流博客
关于mysql驱动包的in语句的bug的更多相关文章
- Oozie安装时放置Mysql驱动包的总结(网上最全)
不多说,直接上干货! 对于在oozie里放置Mysql驱动包的总结 根据网上的参考以及我个人经验安装的使用 (1)放一份到$OOZIE_HOME/libext下 (是 mysql-connector- ...
- JDBC-Web项目导入mysql驱动包路径-Eclipse & Myeclipse
初学JAVA,很多都不懂,开始听老师说导入数据库驱动包的时候是: 右键项目 -> Properties -> Java Build Path -> 右侧选项卡选择Libraries ...
- mysql驱动包
mysql驱动包和源码下载地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java 下载 mysql-connector-jav ...
- 使用Maven导入MySQL驱动包遇到的问题
问题描述 今天在使用Maven导入MySQL数据库驱动包依赖后,直接运行项目,出现错误. java.sql.SQLException: No suitable driver found for jdb ...
- pycharm安装mysql驱动包
新的环境配置pycharm的项目时,发现pycharm不能连接到mysql数据库.由于安了java环境但是还没配置相关的库,并且jetbrains家的IDE一般都是java写的,于是猜想可能是java ...
- 各种版本mysql驱动包下载地址
http://central.maven.org/maven2/mysql/mysql-connector-java/
- JSP连接mysql 驱动包
360网盘 https://yunpan.cn/cPxT6CV9Kydyb 访问密码 1df9
- mysql驱动包下载
- 如何实现在Eclipse导入MySQL驱动包
1 右键项目->Properties->Java Build Path->Libraries->Add External JARs...->mysql-connector ...
随机推荐
- 第2次作业:stream案例分析
摘要:本次随笔是对stream软件进行一次案例分析,以个人观点分析stream为什么成功. 一.介绍产品相关信息 1.我选择的商品是stream 2.选择该产品的主要原因准要是因为自己本身喜欢玩这个平 ...
- C语言程序设计(基础)- 第6周作业
一.PTA作业 完成PTA第六周作业中4个题目的思路列在博客中. 1.7-1 高速公路超速处罚 2.7-2 计算油费 3.7-3 比较大小 4.7-4 两个数的简单计算器 (必须使用switch结构实 ...
- 2017-2018-1 Java演绎法 小组会议及交互汇总
第一周会议 今天我们小组开展了第一次团队例会活动.我们小组将<构建之法>分为了六个部分并由六位成员先分别学习并向组长上传学习收获,这次的活动内容便是 交流前两周小组成员学习阅读<构建 ...
- 20162328蔡文琛week06
学号 2016-2017-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 继承是从已有类派生出一个新类的过程. 继承的目的之一之复用已有的软件. 继承呢在子类和父类见建立了is ...
- scrapy crawl 源码修改 爬虫多开
import os from scrapy.commands import ScrapyCommand from scrapy.utils.conf import arglist_to_dict fr ...
- Struts2之Action的实现
对于Struts2框架来说,最重要的莫过于Action类的编写,类比于Servlet,Action类也是通过类的实例对象调用方法来处理请求的,Action类的实例对象是由Struts2的核心Filte ...
- New UWP Community Toolkit - AdaptiveGridView
概述 UWP Community Toolkit 中有一个自适应的 GridView 控件 - AdaptiveGridView,本篇我们结合代码详细讲解 AdaptiveGridView 的实现 ...
- JAVA_SE基础——41.instanceof关键字(运算符)
instanceof 关键字 instanceof关键字的作用:判断一个对象是否属于指定的类别. instanceof关键字的使用前提:判断的对象与指定的类别必须要存在继承或者实现的关系.关于实现以后 ...
- JAVA类的方法调用和变量(全套)
一.类的分类: 1.普通类 2.抽象类(含有抽象方法的类) 3.静态类(不需要实例化,就可以使用的类) 二.方法的分类: 1.私有方法(只有类的内部才可以访问的方法) 2.保护方法(只有类的内部和该该 ...
- Linux安装svn服务图文详解 ;出现No repository found in 'svn***问题
Linux安装svn服务 ** 示例都是用的root权限,可选择用 sudo** 1:检查 安装条件为:Linux(centos)上未安装过svn服务,若安装过或安装失败请自行删除,这里不多介绍.检查 ...