文件搜索项目知识介绍

    • 项目背景
    • SQLite介绍
      • SQLite、驱动包下载
      • SQLite使用
      • SQLite和MySQL区别
    • JDBC搭配SQLite
      • JDBC原理-创建连接
      • JDBC原理-关闭连接
      • 添加和发送SQL
      • JDBC-事务开启和提交
    • 打包.exe文件
    • 线程池线程数量问题

项目背景

需求上:因为Windows的文件搜索工具搜索速度十分的慢;让大家苦不堪言;是否能利用以前学习的知识实现这样子的一个功能呢?

项目优点:
1:搜索速度相近于世面众多文件搜索工具;文件大小只需13.4MB
2:灵动搜索;能支持文件名字拼音进行搜索;只需会读即可搜索
3:能自主灵活改动;能随时根据自己和体验人员的需求进行扩展和升级。
4:无广告、无会员、更新的选择权在于用户;不自主占用过多内存

SQLite介绍

SQLite、驱动包下载

在这里插入图片描述

在这里插入图片描述
解压后三个文件:我们只取sqlite3.exe即可
在这里插入图片描述

在这里插入图片描述

SQLite使用

双击打开:它会提升连接到一个临时内存数据库;使用.open FILENAME重新打开一个永久数据库
在这里插入图片描述
我们回到exe文件里:shift+右键空白处
在这里插入图片描述
在这里插入图片描述

SQLite和MySQL区别

1:它不是客户端服务器结构;直接就是一个可执行程序;数据库直接文件的方式表示
2:操作大同小异;但是极个别不一样;SQLite是不需要create database/use /drop database/show databases……
所以我们要删除、显示数据库直接去文件里操作即可
3:SQLite轻量;一个数据库只有1M左右;给别人使用总不可能给别人带个几百MB的MySQL
4:sqlite中并不需要选中表;直接操作即可因为我们增删查改都会带上表名;它会去匹配是哪个表的;这个非常符合我们在用户电脑中我的带上的数据库文件创建表然后就能直接使用。要显示知道数据库有哪些表:.tables (MySQL里的show table不适合用)
5:SQLite插入数据会锁整个表;读和读之间无竞争;写和读、写和写有竞争。MySQL默认隔离级别是可重复读;使用MVCC和锁机制保证的隔离性;读和读之间使用共享锁不会锁竞争;写使用排它锁会发生竞争。插入数据时使用行级锁。
6:SQLite是没有int类型;但是它为了兼容其它数据库;使用支持我们写int;它内部自动进行转换成Integer;但是你要想使用自增主键就必须使用Integer

JDBC搭配SQLite

JDBC原理-创建连接

本质都是通过 Connection 对象才能连接到相应的数据库;获取建立连接有两种方式如下:
1:DriverManager;驱动管理;早期的jdbc版本你是需要显示加载驱动程序Class.forName(“com.mysql.jdbc.Driver”);4.0以后的版本引入了自动驱动程序加载机制后;你直接创建连接即可

Class.forName("com.mysql.jdbc.Driver");//加载驱动程序
DriverManager.getConnection("jdbc:mysql://localhost:3306/test&user=root&password=root&useUnicode=true&characterEncoding=UTF-8");
 //或者
   String url = "jdbc:mysql://localhost:3306/mydatabase";
   String username = "user";
   String password = "password";
   Connection connection = DriverManager.getConnection(url, username, password);

2:DataSoure;可以被视为一个数据源池,其中包含了预先创建的Connection对象,应用程序可以从中获取连接对象并使用。

  ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/liao?characterEncoding=utf8&useSSL=false");
    ((MysqlDataSource)dataSource).setUser("root");
    ((MysqlDataSource)dataSource).setPassword("111111");

两者的区别:
1:相当于一个是直接创建 Connection 对象就需要设置相关连接信息。而另一个是它内部帮你创建好;你通过DataSoure设置相应的连接信息:dataSource.setURL(“jdbc:mysql://127.0.0.1:3306/liao?characterEncoding=utf8&useSSL=false”);。本质都是在设置Connection对象。
2:DataSource是这些Connection对象是它帮你创建好存在那里;你只需要通过dataSource设置相应信息;然后通过这个dataSource对象获取这个连接即可。相当于一个懒汉模式;一个饿汉模式。
3: Connection.close时候;虽然都是断开连接;释放资源;DataSource是把Connection还给这个连接池;就是说我现在用完了;现在你其它人可以复用这个连接了

JDBC原理-关闭连接

使用完成connection、Resultset、statement对象都需要回收

      public static void close(Connection connection, Statement statement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

添加和发送SQL

Statement对象主要是将SQL语句发送到数据库中;通常使用的是PreparedStatement;PreparedStatement是Statemen子类
如何获取这个对象:

//建表特殊一点
connection=数据源对象.getConnection();
statement=connection.createStatement();
//
String sql="insert into file_meta values(null,?,?,?,?,?,?,?)";
preparedStatement=connection.prepareStatement(sql);

这个对象有什么好处:
好处1: 预编译;执行之前,会先将SQL语句预编译,并缓存编译后的执行计划。这样可以提高性能,尤其是需要多次执行相同或类似的SQL语句时。
好处2:支持使用占位符(?)来表示参数,然后通过调用setXXX()方法为占位符设置具体的参数值。更安全(能防SQL注入)、数据和SQL分开更好阅读
好处3:对于重复执行相同的SQL语句(如批量插入),由于预编译的存在,性能通常比Statement更好。就是它会在MySQL这些数据库服务器缓存的执行计划和结果。

如何真正将sql发送:
executeQuery() 方法执行后返回Resultset单个结果集的,通常用于select语句。如何遍历这个结果集:

while (resultSet.next()) {
String name=resultSet.getString("name");
}

executeUpdate()方法返回值是一个整数,指示受影响的行数,通常用于update、insert、delete;create创建表也是用这个提交的;语句

JDBC-事务开启和提交

 connection.setAutoCommit(false);//开启事务;先关闭自动提交的功能
 
  String sql="insert into file_meta values(null,"123")";
 preparedStatement=connection.prepareStatement(sql);
  String sql2="insert into file_meta values(null,"234")";
 preparedStatement=connection.prepareStatement(sql2);

  preparedStatement.addBatch();//在这里累计
  //执行SQL;
  preparedStatement.executeBatch();
  //执行完提交事务;使用commit提交事务
  connection.commit();

使用你得try catch包裹一下;出现异常回滚 connection.rollback(); 最后finally释放资源

打包.exe文件

对于学习来说兴趣是最好的老师;能把一个程序给身边的亲朋好友使用;这无疑能给我们提供很大的学习动力。想要别人能成功的使用你的程序;两种常见手段
第一种:web项目部署云服务器上;别人能通过网络使用你的程序
第二种:把你的程序打包成一个.exe可执行文件给别人使用

需要将依赖的资源一起打包成 JAR 文件,可以使用 Maven 插件来实现。常见的 Maven 插件是 maven-assembly-plugin 和 maven-shade-plugin。使用 maven-assembly-plugin如下:
1:添加配置

   <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2:
在这里插入图片描述
java_everything-1.0-SNAPSHOT.jar:只包含了项目自身的编译输出(类文件)和资源文件。不包含任何依赖项或第三方库,也叫"瘦"JAR。
java_everything-1.0-SNAPSHOT-jar-with-dependencies.jar:这个 JAR 包是使用 maven-assembly-plugin 插件创建的,它将项目及其所有的依赖项一起打包到一个单独的可执行 JAR 文件中,也叫"胖"JAR。

3:打包成.exe文件
需要用exe4j软件:操作步骤如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4:测试效果
先让我们本地Java环境失效看看能否执行
在这里插入图片描述

在这里插入图片描述
jre一定得是在同级下;因为打包时配置的是同级目录下;否则会出现
在这里插入图片描述

在这里插入图片描述

线程池线程数量问题

在这里插入图片描述

这里涉及一个问题:使用线程池添加任务;那么线程池的数量应该多少合适?
解决上述问题,可以采用测试的方法来验证适合的线程池数量,并使用计时方法来测量执行时间。但是会有指令重排序问题;解决这个问题;通过线程之间通信;等添加任务完成再通知它结束计时。但是我怎么知道线程池什么时候执行结束呢?
方法1:

threadPool.getTaskCount() != threadPool.getCompletedTaskCount();//统计已执行的任务和总任务比较。但是不准确;因为任务是一直在变化和添加;所以你需要写轮询的方式去判断。也可能我只想判断当前这个任务的三个线程是否执行完;中途别人又添加任务了;那就不精准了。
                                                               

方法2:

ExecutorService executor=Executors.newFixedThreadPool(10);
FutureTask<Integer> task=new FutureTask(()->{
       //任务
 return -1;
});
executor.submit(task);
int result=task.get();//这个方法就能等待所有任务执行完毕并返回结果

方法3:特殊场景;可以使用计数器的方式;因为给线程池添加任务是内存进行非常快;而真正执行更新数据操作硬盘是相对非常慢。所以我们每向线程池添加一个任务就计数器++;线程池执行完一个任务就计数器–。但是这又有一个问题;使用普通计数器会原子性问题。这里能通过使用原子类解决问题。

简化后代码:

public class FileManager {
 Object object=new Object();
 private AtomicInteger taskCount = new AtomicInteger(0);//计数器

  public void scanAll(File basePath) {
        System.out.println("[FileManager] scanAll 开始!");
        long beg = System.currentTimeMillis();
        scanAllByThreadPool(basePath);
        try {
            synchronized (object){
                object.wait();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("[FileManager] scanAll 结束! 执行时间: " + (end - beg) + " ms");
    }
    
  private static ExecutorService executorService = Executors.newFixedThreadPool(100);
    private void scanAllByThreadPool(File basePath) {
   
        // 计数器自增
        taskCount.getAndIncrement(); // taskCount++

        // 扫描操作, 放到线程池里完成.
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    scan(basePath);//执行任务
                } finally {//写在这里防止中间出问题--失败而永远计数器达不到0
                    taskCount.getAndDecrement(); // taskCount--
                    if (taskCount.get() == 0) {
                        // 如果计数器为 0 ; 通知主线程结束计时了.
                        synchronized (object){
                            object.notify();
                        }

                    }
                }
            }
        });
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/240445.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

编程实战:自己编写HTTP服务器(系列6:调用用户功能)

系列入口&#xff1a;编程实战&#xff1a;自己编写HTTP服务器&#xff08;系列1&#xff1a;概述和应答&#xff09;-CSDN博客 本文讲解如何将原有C代码接入到WEB服务里。 目录 一、概述 二、框架入口 三、执行用户功能 3.1 代码 3.2 入口参数 3.3 系统检查和初始化 3…

消息队列kafka详解:Kafka重要知识点+面试题大全

重要面试知识点 Kafka 消费端确保一个 Partition 在一个消费者组内只能被一个消费者消费。这句话改怎么理解呢&#xff1f; 在同一个消费者组内&#xff0c;一个 Partition 只能被一个消费者消费。 在同一个消费者组内&#xff0c;所有消费者组合起来必定可以消费一个 Topic 下…

【flutter对抗】blutter使用+ACTF习题

最新的能很好反编译flutter程序的项目 1、安装 git clone https://github.com/worawit/blutter --depth1​ 然后我直接将对应的两个压缩包下载下来&#xff08;通过浏览器手动下载&#xff09; 不再通过python的代码来下载&#xff0c;之前一直卡在这个地方。 如果读者可以…

npm安装

node 设置配置之后&#xff0c;要查询时&#xff0c;会从.npmrc中读取路径 .npmrc自己创建的&#xff08;默认情况下.npmrc会创建在C盘中&#xff09; 自己创建的在D:\studay-and-working\node16.14\node_modules\npm中 指定.npmrc文件&#xff0c;因为默认会访问C盘的.npmrc文…

在Windows系统和Linux系统中MongoDB的安装方法

本文主要介绍在Windows系统和Linux系统中MongoDB的安装方法。 目录 Windows系统中安装MongoDBLinux系统中安装MongoDB Windows系统中安装MongoDB 在Windows系统中安装MongoDB&#xff0c;可以分为以下几个步骤&#xff1a; 下载MongoDB安装包 在MongoDB官网上下载Windows系统下…

【Linux学习】深入理解动态库与静态库

目录 十三.动态库与静态库 13.1 认识动静态库 13.2 深入理解动静态库 什么是库? 编译链接过程 动静态库的基本原理 13.3 静态库 静态库的打包: 静态库的使用: 13.4 动态库 动态库的打包: 动态库的使用: 13.5 动态库与静态库怎么选? 十三.动态库与静态库 13.1 认识动静态库 …

Vue 中 v-model 的修饰符

lazy 修饰符&#xff1a;将 v-model 改为失去焦点后更新数据。 number 修饰符&#xff1a;将 v-model 数据转为数字类型。 trim 修饰符&#xff1a;去除 v-model 数据中的首尾空格。 语法格式&#xff1a; // lazy 修饰符 <input v-model.lazy"数据"> // nu…

ArcGIS pro与SuperMap根据属性自动填充颜色步骤

GIS项目经常会接触到控规CAD数据&#xff0c;想要把数据转换成GIS图层并发布&#xff0c;需要进行专题配图。研究了一下ArcGIS pro和SuperMap iDesktop的配图&#xff0c;整理一下用到的一些技术思路。 1、Excel表格根据RGB值添加单元格填充颜色 要实现如上效果图&#xff0c;…

AI创新之美:AIGC探讨2024年春晚吉祥物龙辰辰的AI绘画之独特观点

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《粉丝福利》 《linux深造日志》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言一、龙辰辰事件概述二、为什么龙辰辰会被质疑AI创作&#xff1f;1.1 AI 作画的特点2.2 关于建行的合作宣传图…

如何利用宝塔面板和docker快速部署网站

当你有了一台服务器&#xff0c;就会折腾往这台服务器上部署各种好玩的网站。市面上有许多开源的网站项目&#xff0c;通过docker技术可以快速部署并使用&#xff0c;本文将以部署filebrowser举例介绍网站部署的基本流程。 1. 安装宝塔面板 宝塔面板是一款开源的网站运维工具…

博客内容和多种搜索友好格式在 2024 年的作用

内容和SEO之间一直存在着密切的联系。 今天&#xff0c;我想分享一些关于博客、内容和搜索友好格式的想法和技巧。此外&#xff0c;我将分享有关生成式人工智能如何为这种关系添加新元素的见解。 谷歌最近关于有用和有价值的内容的更新重新引发了关于如何找到内容以及内容排名…

汽车销售技巧培训应该学习哪些内容

汽车销售技巧培训应该学习哪些内容 随着汽车市场的竞争日益激烈&#xff0c;汽车销售技巧培训对于提高销售人员的销售能力和服务水平至关重要。本文将介绍汽车销售技巧培训应该学习哪些内容&#xff0c;并结合案例进行分析。 一、产品知识 作为销售人员&#xff0c;了解所销售…

用户管理第2节课 -- idea 2023.2 创建表

一、懂得 1.1编码格式是防止乱码的&#xff0c;utf-8是完全够的&#xff0c;那几个基本没差别 网址&#xff1a; 【IDEA——连接MySQL数据库&#xff0c;创建库和表】_idea中数据库-CSDN博客 这些是MySQL数据库中的一些术语&#xff0c;可以简单解释如下&#xff1a; 1、col…

【日积月累】Spring中的AOP与IOC相关问题详解

Spring中的AOP与IOC 1.前言2.Spring AOP&#xff08;面向切面编程&#xff09;2.1 AOP的实现过程2.2 AOP代理模式的类型2.2.1JDK的动态代理2.2.2CGLIB的动态代理 2.3AOP应用常见场景2.3.1日志记录 2.4对AOP的理解 3.Spring IOC&#xff08;Inversion of Control&#xff0c;控…

低代码平台解密:探秘MQTT协议的应用之道

本文由葡萄城技术团队发布。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 低代码平台作为当今快速发展的技术之一&#xff0c;为开发人员提供了更高效、更简便的工具和方法&#xff0c;以…

深度解读 Cascades 查询优化器

数据库中查询优化器是数据库的核心组件&#xff0c;其决定着 SQL 查询的性能。Cascades 优化器是 Goetz 在 volcano optimizer generator 的基础上优化之后诞生的一个搜索框架。 本期技术贴将带大家了解 Cascades 查询优化器。首先介绍 SQL 查询优化器&#xff0c;接着分析查询…

【玩转TableAgent数据智能分析】TableAgent全功能详解及多领域数据分析实践(下)数据分析过程及总结展望

6 TableAgent的数据分析过程解析 TableAgent的整个分析过程包括以下步骤&#xff0c;形成一个有机结构&#xff0c;让我们理清其工作原理。 6.1 Data Graph阶段 TableAgent首先绘制数据图&#xff0c;以解决问题。这个图形表示了问题的分解和细化&#xff0c;将大问题分解成…

git强制回滚,远程强制更新,git pull强制更新

注意&#xff1a;这里是强制回滚&#xff0c;回滚后&#xff0c;之后历史的就没有了&#xff0c;慎用。 本地强制回滚 强制回滚到上一个版本 git reset --hard HEAD^强制回滚上上个版本 git reset --hard HEAD^^git log查看版本 git log --prettyonelinegit log --prettyf…

【网络安全】HTTP Slowloris攻击原理解析

文章目录 Slowloris攻击的概念Slowloris攻击原理Slowloris攻击的步骤其他的DDoS攻击类型UDP FloodICMP (Ping) FloodSYN FloodPing of DeathNTP AmplificationHTTP FloodZero-day DDoS 攻击 推荐阅读 Slowloris攻击的概念 Slowloris是在2009年由著名Web安全专家RSnake提出的一…

指定安装nginx版本链接

Index of /packages/centos/7/x86_64/RPMS/ (nginx.org) 找到想要下载的对应版本直接下载 rpm -ivh http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.24.0-1.el7.ngx.x86_64.rpm 查看nginx信息 rpm -qa nginx rpm -qi nginx 命令rpm -ivh是Linux系统中的一种用于…