search_everything中几个重要的工具类

2024-03-19 11:50

本文主要是介绍search_everything中几个重要的工具类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、拼音工具类
  • 二、数据库工具类
  • 三、数据库初始化


一、拼音工具类

我们要实现一个拼音搜索的功能,就要把汉字转换成拼音,我们已经导入了汉语拼音处理的jar包,首先需要创建一个拼音工具类,进行一些简单的配置:
在这里插入图片描述
既然我们要实现能进行汉语拼音全拼和拼音缩写的搜索的话,我们就需要实现一个方法,来获取文件名中汉字的全拼和缩写:

/*** @param fileName 传入的文件名* @return {@link String[]}** 该方法的作用是:传入一个文件名,返回一个包含拼音全拼和拼音缩写的字符串数组* 若文件名中包含其它字符(英文,数字,符号等)不做处理*/public static String[] getPinyinByFileName(String fileName){//返回一个字符串数组,数组中有两个元素:拼音全拼,拼音缩写String[] ret = new String[2];//遍历文件名中的每个字符,碰到汉字,将其转换为拼音,非汉字直接拼接StringBuilder allPinyinAppender = new StringBuilder();StringBuilder firstPinyinAppender = new StringBuilder();for (char c : fileName.toCharArray()){try {String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c,FORMAT);if (pinyin == null || pinyin.length == 0){//此时说明该字符不是汉字,对其进行直接拼接allPinyinAppender.append(c);firstPinyinAppender.append(c);}else {//是汉字,取字符串数组中的第一个元素及第一个元素的第一个字符allPinyinAppender.append(pinyin[0]);firstPinyinAppender.append(pinyin[0].charAt(0));}} catch (BadHanyuPinyinOutputFormatCombination e) {//报错的话可能是其它情况,也直接保留allPinyinAppender.append(c);firstPinyinAppender.append(c);}}ret[0] = allPinyinAppender.toString();ret[1] = firstPinyinAppender.toString();return ret;}

此外,当我们把文件信息存储到数据库中时,需要通过判断文件名中是否包含汉字来决定是否保存拼音全拼和拼音首字母缩写,故此时需要一个方法来帮助我们判断文件名中是否包含汉字:
我们知道,字符串在存储时都是转为单个字符进行存储的,而Java中所有的字符都对应唯一的Unicode编码,故我们只要确定汉字的编码范围就可以判断是否包含汉字:

    //Unicode中汉字的编码值范围private static final String CHINESE_PATTERN = "[\\u4E00-\\u9FA5]";/*** @return boolean** 判断文件名中是否包含汉字* 在Java中所有字符都对应不同的Unicode编码值,我们只需要中文编码的起止区间即可*/public static boolean containsChinese(String fileName) {//此处的.*就表示0-N个字符,只要包含中文就能识别出来,相当于一个模糊匹配return fileName.matches(".*" + CHINESE_PATTERN + ".*");}

二、数据库工具类

在选择完文件夹后,会启动文件扫描任务,我们可以将当前选择的文件夹下的所有文件和子文件夹信息保存到SQLite数据库中,在搜索框中进行查询时,直接在数据库中查询,不用再次进行扫描,提升查询效率。

为什么用SQLite数据库?
我们之所以用SQLite嵌入式数据库,是因为我们这个项目本身是比较轻量的,属于一个工具类的项目,如果用MySQL这个数据库的话体积过大,显得比较笨重,故选择了SQLite这样一个轻量级的嵌入式数据库。

要在Java程序中对数据库进行操作,需要进行JDBC:
1.获取数据源,设置账号密码,链接地址
2.获取数据库连接,Statement对象
3.执行Statement的查询或更新方法
4.关闭连接和Statement、ResultSet对象,关闭资源操作。

创建一个数据库的工具类,用来创建数据源,建立连接,关闭连接:
因为该项目会用到多线程,所有我们需要保证,我们的数据源在多线程场景下是唯一的,所有的线程都只能操作这一个数据源,此时需要用到单例模式:

/*** @author Shu* @date 2022/08/22** SQLite数据库的工具类,用来创建数据源,创建数据库的连接* 只提供数据库连接,不提供数据源,数据源封装在类的内部*/
public class DBUtil {//此处volatile关键字相当于内存屏障,当有多个线程操作getDataSource()方法时//t1正在对DATASOURCE进行初始化,但初始化还未完成,//此时t2读取到DATASOURCE != null,获取了尚未初始化完成的DATASOURCE对象//而使用volatile进行修饰,能保证只有当t1初始化操作完全完成时,t2才能获取到对象private volatile static DataSource DATASOURCE;/*** @return {@link DataSource}** 使用double-check单例模式来创建数据源*/private static DataSource getDataSource(){if (DATASOURCE == null){//锁的是DBUtil这个类//保证只有一个线程能进入同步代码块,创建对象.synchronized (DBUtil.class){//进入同步代码块后需要再次确认DATASOURCE是否为空,防止其它线程进入同步代码块后多次创建对象if (DATASOURCE == null){//SQLite没有账号密码,只需要配置日期格式SQLiteConfig config = new SQLiteConfig();config.setDateStringFormat(Util.DATE_PATTERN);DATASOURCE = new SQLiteDataSource();//配置SQLite的URL是SQLiteDataSource类独有的方法,需要向下转型((SQLiteDataSource)DATASOURCE).setUrl(getUrl());}}}return DATASOURCE;}/*** @return {@link String}** 配置SQLite数据库的地址* 对于SQLite而言,它其实就相当于一个文件夹,没有服务端和客户端,只需要配置地址*/public static String getUrl(){//我们创建的数据源会放在当前项目的target目录下String path = "D:\\项目\\search_everything\\target";String url = "jdbc:sqlite://" + path + File.separator + "search_everything.db";return url;}/*** @return {@link Connection}* @throws SQLException** 获取数据库的连接*/public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}
}

注意:以上代码都是适用于单线程下的,当我们要在多线程下执行时,因为SQLite是一个单文件的数据库,在多线程场景下操作SQLite,必须保证多线程使用的是同一个数据库连接,此前我们直接使用数据源的getConnection()方法,但它的内部其实是会创建一个新的连接,在单线程模式下能保证只操作一个连接,但多线程使可能会创建多个不同的连接,此时getConnection()方法需要做一定改动,使数据库连接为单例模式,使每个线程获取的都是同一个连接:

private volatile static Connection CONNECTION;
public static Connection getConnection() throws SQLException {if (CONNECTION == null){synchronized (DBUtil.class){if (CONNECTION == null){CONNECTION = getDataSource().getConnection();}}}return CONNECTION;}

多线程下还需要注意的一点是:此时连接使用完后不能直接关闭了,因为多个线程使用的是同一个连接:

/*** 多线程模式下,每个线程获取的都是同一个连接,此时我们就不能使用完连接之后就直接关闭了*/public static void close(Statement statement) {if (statement != null){try {statement.close();} catch (SQLException e) {System.err.println("statement资源关闭失败");e.printStackTrace();}}}public static void close(Statement statement, ResultSet resultSet){close(statement);if (resultSet != null){try {resultSet.close();} catch (SQLException e) {System.err.println("resultSet资源关闭失败");e.printStackTrace();}}}

三、数据库初始化

既然数据库已经创建了,我们就需要创建一张表来存储我们需要展示的信息:
在这里插入图片描述
在这里插入图片描述

此时我们需要创建一个数据库初始化的类,在界面初始化时创建文件信息数据表

/*** @author Shu* @date 2022/08/23** 界面初始化时初始化我们的数据表*/
public class DBInit {/*** 从resources路径下的init.sql文件中读取sql语句到程序中* @return {@link List}<{@link String}>*/public static List<String> readSQL(){List<String> ret = new ArrayList<>();//拿到init.sql文件的输入流//此处首先考虑的是使用绝对路径读取到sql文件,但若是项目位置改变了的话,就会找不到该文件//于是考虑使用相对路径,但当把项目打成jar包时,编译依然报错//因为编译之后就不存在资源文件夹了,所有资源文件都放在target目录下classes文件夹中//最终解决方案:采用类加载其的方式引入资源文件,这是处理相对路径的通用写法InputStream in = DBInit.class.getClassLoader().getResourceAsStream("init.sql");Scanner sc = new Scanner(in);//此处我们需要自定义分隔符,因为sql语句它是以;作为结尾sc.useDelimiter(";");while (sc.hasNext()){String str = sc.next();if (str.equals(" ") || str.equals("\n")){continue;}ret.add(str);}return ret;}
}

之后再使用JDBC执行我们读取到的sql语句,创建数据表

public static void init(){Connection connection = null;Statement statement = null;try {connection = DBUtil.getConnection();List<String> list = readSQL();statement = connection.createStatement();for (String s : list) {System.out.println("执行sql语句: " + s);statement.executeUpdate(s);}} catch (SQLException e) {System.err.println("数据库初始化失败");e.printStackTrace();}finally {DBUtil.close(connection,statement);}}

执行该方法后,就可以看到我们创建的数据表了:
在这里插入图片描述

这篇关于search_everything中几个重要的工具类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/825901

相关文章

Python使用FFmpeg实现高效音频格式转换工具

《Python使用FFmpeg实现高效音频格式转换工具》在数字音频处理领域,音频格式转换是一项基础但至关重要的功能,本文主要为大家介绍了Python如何使用FFmpeg实现强大功能的图形化音频转换工具... 目录概述功能详解软件效果展示主界面布局转换过程截图完成提示开发步骤详解1. 环境准备2. 项目功能结

Linux系统之stress-ng测压工具的使用

《Linux系统之stress-ng测压工具的使用》:本文主要介绍Linux系统之stress-ng测压工具的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、理论1.stress工具简介与安装2.语法及参数3.具体安装二、实验1.运行8 cpu, 4 fo

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事

Python使用pynput模拟实现键盘自动输入工具

《Python使用pynput模拟实现键盘自动输入工具》在日常办公和软件开发中,我们经常需要处理大量重复的文本输入工作,所以本文就来和大家介绍一款使用Python的PyQt5库结合pynput键盘控制... 目录概述:当自动化遇上可视化功能全景图核心功能矩阵技术栈深度效果展示使用教程四步操作指南核心代码解析

如何基于Python开发一个微信自动化工具

《如何基于Python开发一个微信自动化工具》在当今数字化办公场景中,自动化工具已成为提升工作效率的利器,本文将深入剖析一个基于Python的微信自动化工具开发全过程,有需要的小伙伴可以了解下... 目录概述功能全景1. 核心功能模块2. 特色功能效果展示1. 主界面概览2. 定时任务配置3. 操作日志演示

使用Python和Tkinter实现html标签去除工具

《使用Python和Tkinter实现html标签去除工具》本文介绍用Python和Tkinter开发的HTML标签去除工具,支持去除HTML标签、转义实体并输出纯文本,提供图形界面操作及复制功能,需... 目录html 标签去除工具功能介绍创作过程1. 技术选型2. 核心实现逻辑3. 用户体验增强如何运行

Python使用Turtle实现精确计时工具

《Python使用Turtle实现精确计时工具》这篇文章主要为大家详细介绍了Python如何使用Turtle实现精确计时工具,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录功能特点使用方法程序架构设计代码详解窗口和画笔创建时间和状态显示更新计时器控制逻辑计时器重置功能事件

利用Python实现Excel文件智能合并工具

《利用Python实现Excel文件智能合并工具》有时候,我们需要将多个Excel文件按照特定顺序合并成一个文件,这样可以更方便地进行后续的数据处理和分析,下面我们看看如何使用Python实现Exce... 目录运行结果为什么需要这个工具技术实现工具的核心功能代码解析使用示例工具优化与扩展有时候,我们需要将

Python+PyQt5实现文件夹结构映射工具

《Python+PyQt5实现文件夹结构映射工具》在日常工作中,我们经常需要对文件夹结构进行复制和备份,本文将带来一款基于PyQt5开发的文件夹结构映射工具,感兴趣的小伙伴可以跟随小编一起学习一下... 目录概述功能亮点展示效果软件使用步骤代码解析1. 主窗口设计(FolderCopyApp)2. 拖拽路径

MySQL Workbench工具导出导入数据库方式

《MySQLWorkbench工具导出导入数据库方式》:本文主要介绍MySQLWorkbench工具导出导入数据库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录mysql Workbench工具导出导入数据库第一步 www.chinasem.cn数据库导出第二步