任务驱动才能明确方向。我举一个例子。

情景分析

题目

现在我们要执行查询操作,例如我要查询商品的供应商信息。供应商的信息包括公司名称,负责人名字,联系电话,公司地址等。

我也许会输入电话号码的前几位查询,也许会输入公司名称的某个字查询,也许会输出负责人的姓氏查询……

我希望查出来的结果,是按照Id升序排序好了的。

要求

1.我要根据公司名称查询,只要公司名称包含“广东”、“深圳”的都可以被查询出来

2.我要根据负责人名字查询,只要负责人名字包含“周”、“吴”、“郑”、“王”的都可以被查询出来

3.我要根据电话号码查询,只要电话号码包含“139”,“136”,“137”的都可以被查询出来

相关代码

下面MyBatis的配置方式是Spring整合MyBatis的,详情请参阅下面这篇文章

【Spring】【MyBatis】Spring整合MyBatis01 - 萌狼蓝天 - 博客园 (https://www.cnblogs.com/mllt/p/SpringAndMybatis01.html)

Mapper.java

    /**
* 查询供应商信息
* @param way 查询方式。1:根据供应商公司名称模糊查询 2:根据供应商负责人名字模糊查询 3:根据电话模糊查询
* @param npcs 查询的关键字
* @return List<SmbmsProvider>
*/
public List<SmbmsProvider> getProviderByNCP(@Param("way") int way, @Param("npcs") List<String> npcs);

SmbmsProvider是供应商对象。

Impl.java

package cc.mllt.impl;

import cc.mllt.mapper.ProviderMapper;
import cc.mllt.pojo.SmbmsProvider;
import org.mybatis.spring.SqlSessionTemplate; import java.util.List;
//实现类
public class ProviderImpl implements ProviderMapper {
private SqlSessionTemplate sqlSessionTemplate;
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate){
this.sqlSessionTemplate=sqlSessionTemplate;
}
@Override
public List<SmbmsProvider> getProviderByNCP(int way, List<String> npcs) {
ProviderMapper providerMapper = sqlSessionTemplate.getMapper(ProviderMapper.class);
return providerMapper.getProviderByNCP(way,npcs);
}
}

mapper.xml

<!--    public List<SmbmsProvider> getProviderByNCP(@Param("way") int way, @Param("npc") List<String> npcs);-->
<select id="getProviderByNCP" resultType="SmbmsProvider">
select * from smbms_provider
<choose>
<when test="way==1">
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proName like concat('%',#{npc},'%')
</if>
</foreach>
</when>
<when test="way==2">
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proContact like concat('%',#{npc},'%')
</if>
</foreach>
</when>
<when test="way==3">
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proPhone like concat('%',#{npc},'%')
</if>
</foreach>
</when>
<otherwise>
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proName like concat('%',#{npc},'%')
</if>
</foreach>
</otherwise>
</choose>
order by `id`
</select>

经过测试,当List类型参数包含Null时,不会对结果造成影响,因此我上面没有进行null的判断,如果你有需求,可以加上

经过测试,当List类型参数包含""(也就是空)的时候,会导致将所有数据都查询出来了,因此要判断内容不为空

了解MyBatis foreach标签相关信息请查阅:MyBatis foreach标签 (biancheng.net)

test.java

    ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
ProviderMapper providerMapper = context.getBean("providerMapperBean",ProviderMapper.class);
@Test
public void getProviderByNCPTest(){
List<String> list1 = new ArrayList<>();
//下面两个是我们要查询的
list1.add("北京");
list1.add("深圳");
//下面这些是用来测试的
list1.add(null);
list1.add("");
//下面这句话是分页插件的使用,未使用分页插件则忽略这句话
Page<Object> page = PageHelper.startPage(1,3);
//执行查询操作
List<SmbmsProvider> result1 = providerMapper.getProviderByNCP(1,list1);
//方式1查询结果合集,通过分页插件整理了的
PageInfo<SmbmsProvider> pageInfo1 = new PageInfo<>(result1,3);//三页
//输出相关分页的信息
System.out.println(page);
System.out.println(pageInfo1);
//从分页信息中取出查询到的数据
result1=pageInfo1.getList();
//格式化输出
System.out.println("--------------------根据公司名称查询--------------------");
for(SmbmsProvider smbmsProvider:result1){
System.out.println(smbmsProvider.getId()+"\t"+smbmsProvider.getProCode()+"\t"+smbmsProvider.getProName()+"\t"+ smbmsProvider.getProContact()+"\t"+smbmsProvider.getProPhone());
}
}

【输出结果如下】

思路分析

1.最开始,参数没有使用List,引起的问题

    /**
* 查询供应商信息
* @param way 查询方式。1:根据供应商公司名称模糊查询 2:根据供应商负责人名字模糊查询 3:根据电话模糊查询
* @param npc 查询的关键字
* @return List<SmbmsProvider>
*/
public List<SmbmsProvider> getProviderByNCP(@Param("way") int way, @Param("npc") String npc);

这种方式有一个问题,我查询“北京”,“深圳”需要分为两次查询,后面手动将查询结果合并在一起,然后又要去考虑id升序排序问题……

正如你所见,很麻烦。尤其是排序问题。因为得到的结果是List,排序要根据List里面的SmbmsProvider对象里面的id排序。

如果能一起将多个关键字一起查询,将得到的结果,一个Order By 就解决了,所以,我们要去考虑使用的参数应该是个List,然后里面包含我们想要查询的多个关键字。

那么传入一个List,又怎么在Mapper.xml中取出想要的东西呢,就发现了后面的 MyBatis foreach

2.Mybatis的foreach

了解MyBatis foreach标签相关信息请查阅:MyBatis foreach标签 (biancheng.net)

3. npc != ''

注意标题上的是两个单引号,而不是一个双引号

为什么我特意用一个 if做判断?

这里应对的是List中存在

1:如果整个列表都空的(也就是一个空列表)

List<String> list1 = new ArrayList<>();
list1.add(null);
list1.add("");

我们没有在When中进行判断,列表是否为空,所以它会继续执行下去

到达foreach的时候,开始遍历,如果为空,则后续无语句,若不为空,则继续添加if块中的语句

测试当空List传入时,结果如下

4.其他

分页插件在这篇文章并没有得到充分的应用。

【MyBatis】多关键字的模糊查询的更多相关文章

  1. MyBatis Plus之like模糊查询中包含有特殊字符(_、\、%)

    传统的解决思路:自定义一个拦截器,当有模糊查询时,模糊查询的关键字中包含有上述特殊字符时,在该特殊字符前添加\进行转义处理. 新的解决思路:将like 替换为 MySQL内置函数locate函数 参考 ...

  2. 【Mybatis】【3】mybatis Example Criteria like 模糊查询

    正文: 在Java中使用Mybatis自动生成的方法,like需要自己写通配符 public List<TableA> query(String name) { Example examp ...

  3. Mybatis使用MySQL进行模糊查询时输入中文检索不到结果

    Mybatis使用MySQL进行模糊查询时输入中文检索时,需要在jdbcURL后增加参数   ?useUnicode=true&characterEncoding=UTF-8

  4. mybatis框架入门程序:演示通过mybatis实现数据库的模糊查询操作

    1. mybatis的基本准备操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2. 根据用户名查询用户信息: (1)映射文件 ...

  5. mybatis Example Criteria like 模糊查询

    用Mybatis代码生成工具会产生很多个XXXExample类,这些类的作用是什么? 查阅了很多资料,在这里总结归纳一下 简介XXXExample类用于构造复杂的筛选条件 它包含一个名为Criteri ...

  6. MyBatis动态SQL与模糊查询

    sqlxml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC & ...

  7. mybatis中根据日期模糊查询

    首先设置起始日期startDate和结束日期endDate,数据库中日期字段为achive_time,表名为dos_dossier<select id="getDossiers&quo ...

  8. mybatis 动态Sql的模糊查询

    where teacher.tname like concat(concat(#{tName}),'%') 2:distinct的使用 下面先来看看例子: table    id name    1 ...

  9. Mybatis中的like模糊查询四种方式

    1.  参数中直接加入%% param.setUsername("%CD%"); param.setPassword("%11%"); <select i ...

随机推荐

  1. Kerberos与各大组件的集成

    1. 概述 Kerberos可以与CDH集成,CDH里面可以管理与hdfs.yarn.hbase.yarn.kafka等相关组件的kerberos凭证.但当我们不使用CDH的时候,也需要了解hdfs. ...

  2. js获取元素本身相关值

    Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置. getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集 ...

  3. 简述 Memcached 内存管理机制原理?

    早期的 Memcached 内存管理方式是通过 malloc 的分配的内存,使用完后通过 free 来回收内存,这种方式容易产生内存碎片,并降低操作系统对内存的管理效 率.加重操作系统内存管理器的负担 ...

  4. java-jdbc-all

    jdbc相关解析 JDBC(Java DataBase Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语 ...

  5. 在多线程环境下,SimpleDateFormat 是线程安全的吗?

    不是,非常不幸,DateFormat 的所有实现,包括 SimpleDateFormat 都不是 线程安全的,因此你不应该在多线程序中使用,除非是在对外线程安全的环境中 使用,如 将 SimpleDa ...

  6. 客户端回调 Watcher?

    客户端 SendThread 线程接收事件通知,交由 EventThread 线程回调 Watcher. 客户端的 Watcher 机制同样是一次性的,一旦被触发后,该 Watcher 就失效了.

  7. java后台解决上传图片翻转90的问题,有demo,经过测试可用

    1.需要加入 依赖 metadata-extractor.jar 依赖如下 <dependencies> <!-- Extracts Exif, IPTC, XMP, ICC and ...

  8. Java中final的使用

    原文链接https://www.cnblogs.com/dolphin0520/p/10651845.html 作者Matrix海 子 本文为笔记 0. 概述 final和static一样都是修饰词, ...

  9. (stm32f103学习总结)—DS18B20

    一. DS18B20简介 DS18B20数字温度传感器接线方便,封装后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式.主要根据应用场合的不同而改变其外观.封装后的DS18B20可用于电缆 ...

  10. 算法 | 串匹配算法之KMP算法及其优化

    主串 s:A B D A B C A B C 子串 t:  A B C A B 问题:在主串 s 中是否存在一段 t 的子串呢? 形如上述问题,就是串匹配类问题.[串匹配--百度百科] 串匹配问题是一 ...