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办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

sqlite3 命令行工具使用指南

《sqlite3命令行工具使用指南》本文系统介绍sqlite3CLI的启动、数据库操作、元数据查询、数据导入导出及输出格式化命令,涵盖文件管理、备份恢复、性能统计等实用功能,并说明命令分类、SQL语... 目录一、启动与退出二、数据库与文件操作三、元数据查询四、数据操作与导入导出五、查询输出格式化六、实用功

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

SQLite3命令行工具最佳实践指南

《SQLite3命令行工具最佳实践指南》SQLite3是轻量级嵌入式数据库,无需服务器支持,具备ACID事务与跨平台特性,适用于小型项目和学习,sqlite3.exe作为命令行工具,支持SQL执行、数... 目录1. SQLite3简介和特点2. sqlite3.exe使用概述2.1 sqlite3.exe

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1