下面说说看到的工作项目中的代码,是这个样子的,事先查询一次数据库,将查询到的整张表的数据存到内存,以后使用时不再查询数据库,而直接操作内存中的数据,这主要用于数据库中的数据比较稳定,不会轻易改变的情况,比如法律条款,医疗术语,拿到这些数据主要是用于模糊查询,我对相关代码进行了改动,把原来固定的通过某些字段的模糊查询改为可选择通过哪些字段进行模糊查询,下面看一下代码

 

  控制层,服务层没什么可说的,直接看代码

package study.fuzzysearch.controller;

import java.util.List;

import study.fuzzysearch.bean.User;
import study.fuzzysearch.service.UserService; public class UserController {
public List<User> getUserByFuzzySearch(String searchStr, String[] searchFields, boolean startMatch)
{
return new UserService().getUserByFuzzySearch(searchStr, searchFields, startMatch);
}
}
package study.fuzzysearch.service;

import java.util.List;

import study.fuzzysearch.bean.User;
import study.fuzzysearch.dao.UserDao; public class UserService {
public List<User> getUserByFuzzySearch(String searchStr, String[] searchFields, boolean startMatch)
{
return new UserDao().getUserByFuzzySearch(searchStr, searchFields, startMatch);
}
}

  DAO层实现如下

package study.fuzzysearch.dao;

import java.util.List;

import study.fuzzysearch.bean.User;
import study.fuzzysearch.interf.Filter;
import study.fuzzysearch.interf.impl.FuzzyImpl; public class UserDao {
// 模拟从数据库取数据
User[] users = new User[]{
new User("10001", "zihan", "zh"),
new User("zh002", "zuosan", "zs"),
new User("10003", "zisha", "zs"),
new User("10004", "zizhai", "zw"),
new User("10005", "zaohu", "zh"),
new User("10006", "zhanghu", "zh")
};
public List<User> getUserByFuzzySearch(String searchStr, String[] searchFields, boolean startMatch)
{
// 可以初始化一次保存起来,留以后用
FuzzyImpl<User> fuzzy = new FuzzyImpl<User>(users) {
public String getName(User t) {
return t.getUserName();
} public String getPy(User t) {
return t.getPy();
} public String getUserId(User t) {
return t.getUserId();
}
}; final String[] finalSearchFields = searchFields;
return fuzzy.search(searchStr, new Filter<User>() { public String[] searchFields() {
return finalSearchFields;
} // 这里可以定制一些情况,比如张三在黑名单里,不返回张三
public boolean match(User t) {
if(t.getUserId().equals("10006"))
return false; return true;
}
}, startMatch);
}
}

  再看下两个接口

package study.fuzzysearch.interf;

public interface Filter<T> {
public boolean match(T t);
public String[] searchFields();
}

  上面的接口的match可以过滤掉无效的结果,searchFields指定通过哪些字段进行模糊查询

package study.fuzzysearch.interf;

public interface Fuzzy<T> {

    String getName(T t);
String getPy(T t);
String getUserId(T t);
}

  上面的接口指定可以通过名字,拼音码,id进行模糊查询,如果有更多的选择,可以增加方法

  下面看一下最核心的方法FuzzyImpl类

package study.fuzzysearch.interf.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; import study.fuzzysearch.interf.Filter;
import study.fuzzysearch.interf.Fuzzy; public abstract class FuzzyImpl<T> implements Fuzzy<T>{
private T[] datas;
private Map<String, List<T>> nameMap = new HashMap<String, List<T>>();
private Map<String, List<T>> pyMap = new HashMap<String, List<T>>();
private Map<String, List<T>> userIdMap = new HashMap<String, List<T>>();
private Map<String, Map<String, List<T>>> allMap = new HashMap<String, Map<String, List<T>>>(); public FuzzyImpl(T[] datas)
{
this.datas = datas; List<T> temp = null;
if(null != datas && datas.length > 0)
{
for(int i = 0; i < datas.length; i++)
{
temp = nameMap.get(getName(datas[i]));
if(temp == null)
{
temp = new ArrayList<T>();
} temp.add(datas[i]);
nameMap.put(getName(datas[i]), temp); temp = pyMap.get(getPy(datas[i]));
if(temp == null)
{
temp = new ArrayList<T>();
} temp.add(datas[i]);
pyMap.put(getPy(datas[i]), temp); temp = userIdMap.get(getUserId(datas[i]));
if(temp == null)
{
temp = new ArrayList<T>();
} temp.add(datas[i]);
userIdMap.put(getUserId(datas[i]), temp);
} allMap.put("py", pyMap);
allMap.put("userId", userIdMap);
allMap.put("name", nameMap);
}
} public List<T> search(String searchStr, Filter<T> f, boolean startMatch)
{
List<T> result = new ArrayList<T>();
List<T> temp = new ArrayList<T>();
if(null != searchStr && searchStr.length() > 0)
{
String[] searchFields = f.searchFields();
if(null != searchFields && searchFields.length > 0)
{
for(int i = 0; i < searchFields.length; i++)
{
Map<String, List<T>> tempSearchMap = allMap.get(searchFields[i]);
temp.addAll(search(searchStr, tempSearchMap, startMatch));
} Set<T> tempSet = new HashSet<T>(temp);
temp = new ArrayList<T>(tempSet); for(int i = 0; i < temp.size(); i++)
{
if(f.match(temp.get(i)))
{
result.add(temp.get(i));
}
}
}
} return result;
} public List<T> search(String searchStr, Map<String, List<T>> compMap, boolean startMatch)
{
List<T> result = new ArrayList<T>();
Set<String> keys = compMap.keySet();
Iterator<String> keyIte = keys.iterator();
while(keyIte.hasNext())
{
String next = keyIte.next();
if(startMatch)
{
if(next.startsWith(searchStr))
{
result.addAll(compMap.get(next));
}
}
else
{
if(next.contains(searchStr))
{
result.addAll(compMap.get(next));
}
}
} return result;
} public T[] getAllDatas()
{
return datas;
}
}

  构造器中将名字,拼音码,ID分别存在了Map中,而且相同的名字,拼音码,ID存在了一起,这样减小了查询时的次数,search方法根据searchFields从名字,拼音码或者ID的Map中查询结果,并将结果合并去重得到最终结果

  再看一下测试代码

package study.fuzzysearch.test;

import study.fuzzysearch.controller.UserController;

public class Test {
public static void main(String[] args)
{
// getUserByFuzzySearch
UserController controller = new UserController(); System.out.println(controller.getUserByFuzzySearch("zh", new String[]{"name", "userId", "py"}, true));
System.out.println(controller.getUserByFuzzySearch("zh", new String[]{"name", "py"}, false));
}
}

  结果如下

  可以对照着users的内容分析结果

  代码是jdk5.0下的,所以没有用到什么高级特性,其中值得说的地方就是Fuzzy接口中的方法,里面的方法实现是在新建FuzzyImpl对象的时候,因为这时会确定要进行模糊查询的对象是什么,从而得到对象的名字,拼音码,ID,这里算是个技巧了,在对象不同的情况下通过统一的方法获取想要的数据,至于Filter接口,是用来确定查询范围与结果范围的。

  好了,就说到这里吧,有喜欢的评论一下吧。

模糊查询内存查询java实现的更多相关文章

  1. Linux_内存查询

    查询磁盘使用情况: [root@css-management ~]# df -hl 文件系统 容量 已用 可用 已用% 挂载点 Filesystem Size Used Avail Use% Moun ...

  2. Oracle 用Drapper进行like模糊传参查询需要在参数值前后带%符合

    Oracle 用Drapper进行like模糊传参查询需要在参数值前后带%符合   string sqlstr="select * from tblname where name like ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (24) ------ 第五章 加载实体和导航属性之查询内存对象

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-4  查询内存对象 问题 你想使用模型中的实体对象,如果他们已经加载到上下文中, ...

  4. SSH整合时执行hibernate查询报错:java.lang.ClassCastException: com.ch.hibernate.Department_$$_javassist_0 cannot be cast to javassist.util.proxy

    今天在整合ssh三个框架时,有一个功能,是查询所有员工信息,且员工表和部门表是多对一的映射关系,代码能正常运行到查询得到一个List集合,但在页面展示的时候,就报异常了, java.lang.Clas ...

  5. 关系数据库SQL之基本数据查询:子查询、分组查询、模糊查询

    前言 上一篇关系数据库常用SQL语句语法大全主要是关系型数据库大体结构,本文细说一下关系型数据库查询的SQL语法. 语法回顾 SELECT [ALL|DISTINCT] <目标列表达式>[ ...

  6. 10月30日下午 PHP精确查询(模糊查询、模糊+关键字共同查询)

    1.一个条件的模糊查询 <body> <br /> <form action="main.php" method="post"&g ...

  7. 理解SQL Server的查询内存授予(译)

    此文描述查询内存授予(query memory grant)在SQL Server上是如何工作的,适用于SQL 2005 到2008. 查询内存授予(下文缩写为QMG)是用于存储当数据进行排序和连接时 ...

  8. Indri查询命令及Java调用并保存结果

    查询参数 index Indri索引库路径.在参数文件中像/path/to/repository这样指定,在命令行中像-index=/path/to/repository这样指定.该参数可以设置多次来 ...

  9. Oracle,Mysql ,SQL Server 三大数据库带参数的模糊查询, 拼接查询条件问题

    最近项目开发一直在不断切换数据库,有时候一条sql 要同时考虑多种数据库中的兼容问题 , 先总结一条模糊查询拼接查询条件的问题,后续追加总结. 目前使用   mybatis: 1. Oracle 中使 ...

随机推荐

  1. RHEL-server-7.0-Linux-centos安装过程

    虚拟机centos7的安装过程 win10 ()vmware软件的时候,1.先关闭防火墙(杀毒软件),在安装vmware虚拟机.2.试着全装一下 vmware-14版本. 1. 打开VMware Wo ...

  2. centos7 firewall-cmd 理解多区域配置中的 firewalld 防火墙

    原文:https://www.linuxidc.com/Linux/2017-11/148795.htm 现在的新闻里充斥着服务器被攻击和数据失窃事件.对于一个阅读过安全公告博客的人来说,通过访问错误 ...

  3. [UE4]Delay与Retriggerable Delay

    一.Delay 在右上角都有一个表盘的图标,表示不是在当帧内执行,而是需要一定时间才能完成的. 鼠标移上去,会有一段文字注释.根据指定的延迟时间执行一个延后的动作.当计时还没有结束的时候,如果再次被调 ...

  4. vue todolist 1.0

    <template> <div id="app"> <input type="text" v-model='todo' /> ...

  5. Mybatis 系列6-结合源码解析节点配置:objectFactory、databaseIdProvider、plugins、mappers

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  6. Shell IF条件判断解析

    IF条件判断 1.基本语法: if [ command ]; then #符合该条件执行的语句 fi2.扩展语法: if [ command ];then #符合该条件执行的语句 elif [ com ...

  7. 关于-RegExp

    // exec() exec() 查找并返回当前的匹配结果,并以数组的形式返回. // test() test() 方法检索字符串中的指定值.返回值是 true 或 false. // compile ...

  8. 普通数组和json数组的区别

    PHP 数组 什么是数组? 数组是特殊的变量,它可以同时保存一个以上的值. 在 PHP 中创建数组 在 PHP 中, array() 函数用于创建数组 在 PHP 中,有三种数组类型: 索引数组 - ...

  9. 关于python中生成器之Send方法

    #send主要是用于外部与生成器对象的交互def func1(): # 生成器函数 print("ok1") x = 10 # 函数内局部变量x赋值为10 print(x) x = ...

  10. BZOJ2054 疯狂的馒头 并查集

    题意:懒得写了有空再补上 链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2054 离线从后往前做,并查集维护下一个没染色的就可以啦- #incl ...