模糊查询内存查询java实现

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

 

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

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接口,是用来确定查询范围与结果范围的。

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

原文地址:https://www.cnblogs.com/liunianfeiyu/p/10125720.html

时间: 2024-11-08 13:39:31

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

Linux_内存查询

查询磁盘使用情况: [[email protected] ~]# df -hl 文件系统 容量 已用 可用 已用% 挂载点 Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_cssmanagement-lv_root 24G 8.0G 15G 37% / tmpfs 3.9G 112K 3.9G 1% /dev/shm /dev/sda1 485M 37M 423M 8% /boot /dev/sdb1 99G 9.8G 84G

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

此文描述查询内存授予(query memory grant)在SQL Server上是如何工作的,适用于SQL 2005 到2008. 查询内存授予(下文缩写为QMG)是用于存储当数据进行排序和连接时的临时中间数据行.查询在实际执行前需要先请求保留内存,所以会存在一个授予的动作. 这样的好处是提高查询的可靠性和避免单个查询占用所有的内存. SQL Server在收到查询时,会执行3个被定义好的步骤来返回用户所请求的结果集. 1.生成编译计划.它包括各种逻辑指令,如怎么联接数据行. 2.生成执行计

查询内存溢出

首先我们来看一个带排序的查询,点击工具栏的显示包含实际的执行计划. 1 SELECT * FROM AdventureWorks2008R2.Person.Person WHERE FirstName LIKE 'w%' ORDER BY 1 从执行计划里可以看出,SELECT运算符包含了内存授予(Memory Grant)信息(一般情况下不会出现,这里是因为我们的语句包含排序操作).内存授予是KB为单位,是当执行计划中的一些运算符(像Sort/Hash等运算符)的执行,需要使用内存来完成——因

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

http://www.jianshu.com/p/eeb6a898d4ec 前言 上一篇关系数据库常用SQL语句语法大全主要是关系型数据库大体结构,本文细说一下关系型数据库查询的SQL语法. SQL数据查询 语法回顾 SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>]- FROM <表名或视图名>[,<表名或视图名>]- [WHERE <条件表达式>] [GROUP BY <列名> [HAVING &l

简易DVD查询系统(Java半学年成果)

值此2018年最后一天,决定上传一下我上个星期做好的DVD查询系统(java): 虽然自己觉得应该会有更简单的方法,但苦于知识的薄弱,暂时只能用这样较为繁琐复杂的方式来实现: 如果以后有新的方法,我会在此文下附上: 以下是我自己做好并在Eclipse上运行试验好的源代码,如有不足还望谅解. 这是DVD任务管理器的主界面: 1 package day20181224; 2 3 import java.text.ParseException; 4 import java.util.Scanner;

数据库 day60,61 Oracle入门,单行函数,多表查询,子查询,事物处理,约束,rownum分页,视图,序列,索引

1.    oracle介绍 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一.比如SilverStream就是基于数据库的一种中间件.ORACLE数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能:作为一个关系数据库,它是一个完备关系的产品:作为分布式数据库它实现了分布式处理功能.但它的所有知识,只要在一种机型上学习

Oracle基本语法&amp;&amp;函数&amp;&amp;子查询&amp;&amp;分页查询&amp;&amp;排序&amp;&amp;集合操作&amp;&amp;高级分组函数

一.  数据库 手工---文件管理---数据库 DB:Database 数据库. DBMS:管理数据库的软件.(oracle) 主流关系数据库: 1.      Oracle 2.      DB2 3.      SQL Server 基本没人使 4.      MySQL  基本没人用,免费 Linux 开源,可以发现漏洞补上 Windows服务器会有补丁,数据易泄漏 eclipse 日食 数据表(Table): 表的行(Row):记录 表的列(Column):字段 二.  关系型数据库 一

Hibernate学习---第十节:Hibernate之QBC、样例查询&amp;离线查询

一.QBC (Query By Criteria) 主要有Criteria,Criterion,Oder,Restrictions类组成 1.java 代码如下: /** * 查询所有 */ @Test public void testQuery(){ // 获取 Criteria 对象 Criteria criteria = session.createCriteria(Person.class); List<Person> list = criteria.list(); for(Perso

Hibernate5-投影查询,分组查询,Query的List和Iterate

1.创建项目,项目名称hibernatedemo9,目录结构如图所示 2.在项目中创建lib目录存储jar文件,目录结构如图所示 3.在src目录中创建实体Bean Forum,包名(com.mycompany.demo.bean),如图所示 4.实体Bean Forum的内容如下 package com.mycompany.demo.bean; public class Forum { private int fid; private String name; private int issh