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

 

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

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. awk 改名

    awk 改名 echo ""|awk 'END{for(i=2;i<=100;i++){system("mv securitycode\ \("i&quo ...

  2. Jmeter(二十四)Jmeter-Question之“加密请求参数”

    日常接口测试碰到参数加密的情况不在少数,当然与之相对的也有解密.直接记录实例: 排除各家用的不一样的加密方式,用的最多的还是MD5加密(16,32).Jmeter3.2版本已经有解决方案 1.${__ ...

  3. T-SQL 带参数存储过程

    创建带参数的存储过程 use StudentManager go if exists(select * from sysobjects where name='usp_ScoreQuery4') dr ...

  4. 第10章 网络安全(4)_网络层安全IPSec

    5. 网络层安全IPSec 5.1 IPSec协议 (1)前面使用Outlook进行数字签名和数字加密是应用层实现的安全.安全套接字实现的安全是在应用层和传输层之间插入了一层来实现数据通信安全.而IP ...

  5. nodejs中mysql用法

    nodejs也算是一篇脚本了我们来看nodejs如何使用mysql数据库了有了它们两组合感觉还是非常的不错哦,下面一起来看nodejs中使用mysql数据库的示例,希望能够帮助到各位. <scr ...

  6. django前篇

    http协议 HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本 ...

  7. Java - 23 Java 抽象类

    Java 抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不 ...

  8. is和==的区别

    is 比较的是内存地址 == 比较的是内容 当两个变量指向同一个对象的时候. is是True, ==也是True

  9. gentoo samba 密码错误

    参考 Samba Share Password Refused https://social.technet.microsoft.com/Forums/windows/en-US/8249ad4c-6 ...

  10. idea 控制台行数限制

    在本地进行测试时,会出现报错太多idea控制台被限制打印出来的日志被清楚的现象: idea改变控制台打印log限制的方法: 1. 点击 File ->Settings ->editor - ...