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

 

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

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. centos6.9安装oracle11g

    感谢强哥的文档 源文档链接 https://www.qstack.com.cn/archives/68.html #------------------------------------------ ...

  2. MySQL学习----各种字符的长度总结

    数字型 类型 大小 范围(有符号) 范围(无符号) 用途 TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 768,32 767) (0, ...

  3. 0000 - Spring Cloud 概述

    1.概述 Spring Cloud是一系列框架的有序集合,它利用Spring Boot的开发便利性简化了分布式系统的开发,比如服务发现.服务网关.服务路由.链路追踪等.Spring Cloud并不重复 ...

  4. mac一些设置

    Mac自带了的JDK6,安装在目录:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/下. JDK8则需要自己到Oracle官网下载安装对应的版本. ...

  5. Python利用脚本2.x到3自动转换

    本文介绍一下在windows 10 环境下如何使用这个工具: 1)首先要先安装好python3,可到官网下载https://www.python.org/ 2)使用Windows 命令提示符(cmd) ...

  6. vue2.0自定义指令

    前面一片文章说了vue2.0过滤器,其实自定义指令跟过滤器非常相似,单就定义方式而言,其与过滤器完全一致,分为局部指令,和全局指令.不过就是filter改为directive的区别. 过滤器一般用于对 ...

  7. 数据库设计和ER模型-------之数据库系统生存期(第二章)

    数据库设计 概念:开发人员利用开发环境表达用户要求.设计构造最优的数据模型,然后据此建立数据库以及其应用系统,这个过程称为数据库设计 数据库生存期 1968年首次提出“软件工程”的概念 概念:我们把数 ...

  8. [Unity基础]镜头管理类

    一个游戏中可能会有各种类型的镜头,例如有时候是第一人称,有时是第三人称,有时又会给个特写等等,因此可以定义一个镜头类型枚举,在不同的场合进行切换,管理起来很方便. CameraManager.cs u ...

  9. getent passwd 不能访问到 ldap 的用户

    getent passwd  不能访问到 ldap 的用户,搞了一整个下午! 依然没搞定, 一开始是不知道nslcd 需要启动,另外getent passwd 域, 无有用结果, 换个方式搜索 get ...

  10. ADO.net 增删改查

    ADO.net 一.定义:编程开发语言与数据库连接的一门语言技术 二.链接: 在vs中操作数据库需在开头进行链接 链接内容:using System.Data.SqlClient 三.引用数据库: 四 ...