文档章节

关于Spring中jdbc的模糊查询

33号小人物
 33号小人物
发布于 2015/12/28 22:29
字数 745
阅读 1998
收藏 2
点赞 0
评论 0

1、功能需求

    对特定的字段进行模糊查询,并以列表形式返回匹配结果

2、解决思路

    使用NamedParameterJdbcTemplate类中的query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)方法,其中sql是查询语句,paramSource是对应查询语句中的参数列表,rowMapper是每一行记录,对应一个对象。

3、发现问题

    根据以往的经验(其实很少),模糊匹配就是where 字段 like '%匹配值%'。然后跟NamedParameterJdbcTemplate的占位符相结合,通过冒号(:)加参数名的方式来代表,即:

......
sql = "... where column like '%:key%'";
paramSource.addValue(key,value);
......    
JdbcTemplate.query(sql,paramSource,rowMapper);

    匹配的结果是,0(实际上是有满足条件的)。度娘也没有太多办法,只好自己下载spring的源码去debug了。最关键的代码,就是以下这段:

protected PreparedStatementCreator getPreparedStatementCreator(String sql, SqlParameterSource paramSource) {
    ParsedSql parsedSql = getParsedSql(sql);
    String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
    Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null);
    List<SqlParameter> declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource);
    PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters);
    return pscf.newPreparedStatementCreator(params);
}

    getParsedSql是用来识别sql中参数的名字和统计参数的个数,识别的标准有:name和:{name}两种形式;

    substituteNamedParameters是将sql中已识别的参数替换为?占位符,如果参数是一个集合类型的话,会把对象里面的属性遍历出来,并用?代替,变成最后真正使用的sql语句;

    buildValueArray是将输入参数的值转化为Object数组;

    buildSqlParameterList是将输入参数的名字转化为List;

    PreparedStatementCreatorFactory新建一个工厂类;

    最后利用newPreparedStatementCreator的方法生成并返回PreparedStatementCreator的实现类。

    最后找到问题的根源在,getParsedSql-->NamedParameterUtils.parseSqlStatement-->skipCommentsAndQuotes方法中会自动跳过一些字段,下面就是跳过的开始字符和结束字符的匹配规则。

String[] START_SKIP = new String[] {"'", "\"", "--", "/*"};
String[] STOP_SKIP = new String[] {"'", "\"", "\n", "*/"};

    首先,spring是通过识别特殊字符来确定参数的数量的,如“:name”。由于我的:key是放在了单引号'的中间,所以就不能够统计sql中参数的名字和统计参数的个数,因此尽管我的paramSource里面是包含了相应的参数,但程序是不接受的。

4、问题初解决

    解决问题的方法,就是sql中不能够包含单引号',那就这样吧

......
sql = "... where column like :key";
paramSource.addValue(key,"'%"+value+"%'");
......

    上面的方法,居然还是不行。

5、问题终解决

    原来是不需要添加单引号'的

......
sql = "... where column like :key";
paramSource.addValue(key,"%"+value+"%");
......

    后来才发现,jdbc中的参数化查询,本来就是这样子的:

sql = "... where column like %?%";

    5、经验总结

    其实,很多时候会发现问题的根源是个小问题,但是通过查看源码找到问题,并解决问题的过程,感觉自己就像个侦探,抽丝剥茧,层层深入,最后谜底解开。哈哈哈~  就是对自己的鼓励吧!!!

© 著作权归作者所有

共有 人打赏支持
33号小人物
粉丝 1
博文 3
码字总数 2040
作品 0
广州
高级程序员
Spring之jdbc Template实现CRUD操作

Spring为各种持久化技术都提供了简单操作的模板回调。比如jdbc、hibernate、Mybatis以及JPA等。 这里我们就以JDBC为例,看看JDBC template怎么实现CRUD操作。 JdbcTemplate主要提供以下几类方...

Java攻城玩家 ⋅ 05/31 ⋅ 0

【小马哥】Spring Boot系列讲座

这里为大家推荐一个不错的Spring Boot系列讲座,讲师介绍如下: 小马哥,阿里巴巴技术专家,从事十余年Java EE 开发,国内微服务技术讲师。目前主要负责微服务技术推广、架构设计、基础设施、...

杜琪 ⋅ 03/02 ⋅ 0

【小马哥】Spring Cloud系列讲座

这里为大家推荐一个不错的Spring Cloud系列讲座,讲师介绍如下: 小马哥,阿里巴巴技术专家,从事十余年Java EE 开发,国内微服务技术讲师。目前主要负责微服务技术推广、架构设计、基础设施...

杜琪 ⋅ 03/02 ⋅ 0

Elasticsearch入门实践

一. 系统环境 操作系统:CentOS release 6.8 (Final) ES版本:6.1.1 二. 安装 先确认安装了Java运行时环境: 解压ES压缩包: 三. 启动 1. 启动ES单节点 当然,对于在后台以守护进程模式运行的...

哲别0 ⋅ 06/06 ⋅ 0

基于可靠消息方案的分布式事务(二):Java中的事务

前言:在上一篇文章 基于可靠消息方案的分布式事务:Lottor介绍 中介绍了常见的分布式事务的解决方案以及笔者基于可靠消息方案实现的分布式事务组件Lottor的原理,并展示了应用的控制台管理。...

aoho ⋅ 06/01 ⋅ 0

书单丨5本Java后端技术书指引你快速进阶

一名Java开发工程师 不仅要对Java语言及特性有深层次的理解 而且需要掌握与Java相关的 框架、生态及后端开发知识 本文涉及多种后端开发需要掌握的技能 对于帮助提高开发能力非常有帮助 NO.1...

Java高级架构 ⋅ 05/30 ⋅ 0

JAVA程序员面试题整理(较全面)

以下是在面试中可能会遇到的问题,话不多说,往下看 1、面向对象的特征有哪些方面? 2、访问修饰符public,private,protected,以及不写(默认)时的区别? 3、String 是最基本的数据类型吗? ...

编程大侠 ⋅ 04/09 ⋅ 0

【死磕Sharding-jdbc】—–基于ssm

原文作者:阿飞Javaer 原文链接:https://www.jianshu.com/p/602e24845ed3 本篇文章讲解如何在ssm(spring、springmvc、mybatis)结构的程序上集成sharding-jdbc(版本为1.5.4.1)进行分库分...

飞哥-Javaer ⋅ 05/05 ⋅ 0

ThreadLocal趣谈 —— 杨过和他的四个冤家

一个一个上 一日醒来,杨过发现小龙女离家出走,于是外出寻找,不料碰上了金轮法王、李莫愁、裘千尺、公孙止四个冤家。 “哼,四个打我一个,算什么英雄好汉,有本事的,一个一个上!” 按照...

SexyCode ⋅ 06/12 ⋅ 0

Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区 ⋅ 05/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部