搜索
首页Javajava教程什么是光池?

什么是光池?

Jan 07, 2025 pm 04:08 PM

O que é o hikari pool?

什么是光池?

BlueSky 上的一篇帖子中的这个简单问题让我得到了一个我认为非常酷的解释。我来这里是为了完成它。

在具体的上下文中,正在谈论 Hikari 连接池。但是,如果 Hikari 是一个连接池,那么“池”会是什么?

首先,泳池概念

在解释什么是 HikariCP 之前,我们需要先解释一下连接池是什么。为了解释连接池,我们需要解释

我们可以用经济学来类比吗?这是一个与现实世界充满缺陷和不准确的历史经济类比,但是来吧,为了解释而迅速停止你的怀疑!它是独立的。

想象一下您是中世纪时代的领主/女士。你拿着工具来进行农民的工作。并且您希望它们能够工作。那么如何保证这一点呢?如果工具是你的?你需要给农民提供工具,很简单。

所以想象一下这种情况:你的农民需要一把锄头来除草,所以他去那里向你要一把锄头。你会给他锄头并继续生活。但如果他不归还,他的锄头怎么办?总有一天会结束的……

交出锄头的另一种选择是制作锄头。您是这些土地的领主/女士,因此您可以联系铁匠,将金属熔炼成锄头的形状并将其安装到手柄中。但这不是你可以在没有农民坐在候诊室的情况下立即生产的东西。为了实现这个新功能,您需要大量的时间和精力。

现在,如果农民在一天结束时归还锄头,第二天它就可以供其他农民使用。

在这里,您正在控制锄头池是一种设计模式,指示您可以执行以下操作:

  • 向他要一个元素
  • 返回元素

对象中的其他常见内容:

  • 通过在池中注册来按需创建更多对象的能力
  • 能够从中销毁对象(或将其与解除关联)

连接到 JDBC 数据库

那么,让我们离HikariCP更近一些吧。这里我们来谈谈Java中的数据库连接。

在java中,我们要求建立与数据库的连接。有直接连接选项,您需要直接了解要调用哪些类以及一些细节,或者只是享受服务发现选项。

先验地,为了使用服务发现,服务提供者会提供一种方法来注册他所提供的内容,然后“服务发现”会跟踪它以查看谁可以服务该请求。

服务发现案例:pstmt-null-safe

我曾经遇到过需要建立 JDBC 连接来与数据库通信的情况。但是,我的 JDBC 驱动程序不接受使用 null 作为值,只接受直接在查询中使用 null。那么我做了什么?司机顶司机!

总体思路如下。想象一下,我有一个查询,我想将值插入到:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

现在想象一下我正在处理这个值第一次插入到银行中。为此,我需要将其保留为 ID=1、CONTENT=first 和 PARENT=null,因为毕竟没有这样的父记录(毕竟它是第一个)。

自然会做什么:

try (final var pstmt = conn.prepareStatement(
                """
                INSERT INTO some_table (id, content, parent)
                VALUES (?, ?, ?)
                """)) {

    pstmt.setInt(1, 1);
    pstmt.setString(2, "first");
    pstmt.setNull(3, Types.INTGEGER); // java.sql.Types
    pstmt.executeUpdate(); // de fato altere o valor
}

我想继续这样使用它,毕竟这是惯用的使用方式。根据丘比特的说法,“I”来自“惯用语”。拥有惯用代码的想法正是为了“减少不必要的心理负担”。

为了解决这个问题,我的选择是:将prepareStatement留到executeUpdate之前的最后一刻。因此,我存储了要应用的所有空值,当我意识到我实际上需要一个空值时,我运行字符串替换并生成一个新查询,并且这个新查询将实际执行。

在这种情况下,我从:
开始

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

所以,我必须输入这些值:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

-- 1, 'first', NULL

但我实际上无法使用 null,所以我创建了一个键来标识第三位是 null:

-- (value, value, NULL)
INSERT INTO some_table (id, content, parent)
VALUES (?, ?, NULL)
-- 1, 'first'

在这种情况下,我准备这个新字符串并根据要求放置参数。

好吧,也就是说,我如何向我的应用程序表明我需要使用 JDBC 驱动程序?我如何注册?

相关项目是 Pstmt Null Safe。基本上,Java 类加载器有一个神奇之处,即加载 jar 时,它会查找名为 META-INF 的元数据文件夹。对于 JDBC 驱动程序,META-INF/services/java.sql.Driver,我用实现 java.sql.Driver 的类记录了它:br.com.softsite.pstmtnullsafe.jdbc.PstmtNullSafeDriver。

根据 java.sql.Driver 文档,每个驱动程序都应该创建自己的实例并向 DriverManager 注册。我是这样实现的:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

静态块自行加载。我们如何知道哪个连接应该由我的驱动程序管理?该调用是通过 DriverManager#getConnection(String url) 进行的。我们有 URL 来询问驱动程序是否接受连接。约定(这里又是惯用的使用方式)是将其作为 URL 方案的前缀。因为我希望我的驱动程序连接到另一个驱动程序之上,所以我使用了以下方案:

try (final var pstmt = conn.prepareStatement(
                """
                INSERT INTO some_table (id, content, parent)
                VALUES (?, ?, ?)
                """)) {

    pstmt.setInt(1, 1);
    pstmt.setString(2, "first");
    pstmt.setNull(3, Types.INTGEGER); // java.sql.Types
    pstmt.executeUpdate(); // de fato altere o valor
}

因此,为了执行测试,我连接了 SQLite,并使用 Xerial 指示器通过连接 URI 请求内存中连接:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

为了“封装”连接,我的约定表明我不重复 jdbc:,所以:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

-- 1, 'first', NULL

剖析上面的 URI:

-- (value, value, NULL)
INSERT INTO some_table (id, content, parent)
VALUES (?, ?, NULL)
-- 1, 'first'

好的,你如何表明这一点?如果我可以打开连接,Driver#acceptsURL 必须返回 true。我可以这样做:

public static final PstmtNullSafeDriver instance;

static {
    instance = new PstmtNullSafeDriver();
    try {
        DriverManager.registerDriver(instance);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

但是如果我尝试加载不存在的驱动程序,这表明什么?没什么,下次会出问题的。这并不好,理想的情况是从一开始就崩溃。因此,为此,我将尝试从下面加载驱动程序,如果不能,我将返回 false:

jdbc:pstmt-nullsafe:<url de conex sem jdbc:>
\__/ \____________/
 |    |
 |    Nome do meu driver
 Padrão para indicar JDBC
</url>

实际的驱动程序代码还有一些与此处讨论的 HikariCP、DataSource、JDBC 或本文讨论的主题无关的要点。

因此,当请求与 DriverManager 的“空安全”连接时,它首先找到我的驱动程序,然后我的驱动程序递归地尝试检查是否有可能在后台建立连接。确认有一个驱动程序能够处理这个问题,我说是的,这是可能的。

Java中JDBC连接的使用模式

Connection 接口实现了 AutoCloseable 接口。这意味着您获取连接,根据需要使用该连接,然后关闭该连接。对此使用一些间接连接是非常标准的,或者,如果您直接使用连接,请在 try-with-resources:
块中使用它

jdbc:sqlite::memory:

现在,创建连接的过程是一个昂贵的过程。而且服务发现过程并不是完全免费的。因此,理想的情况是保存驱动程序,然后生成连接。让我们一点一点地开发它。

首先,我们需要有一个可以通过驱动程序启动的对象。它可以很容易地是一个全局对象、一个注入的 Spring 组件或类似的东西。我们称之为 JdbcConnector:

jdbc:pstmt-nullsafe:sqlite::memory:

getJdbcConnection() 的一种可能实现是依赖于该函数包含的状态:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

到目前为止一切都很顺利。但是……还记得最初的例子吗?农民在工具池中索要一把锄头?那么……我们要考虑到这一点吗?我们可以将连接返回到,而不是实际关闭连接。为了正确性,我会防止多个同时访问,但我不会担心这里的效率。

我们假设我有一个名为 ConnectionDelegator 的类。它实现了所有 Connection 方法,但它自己不执行任何操作,它仅委托给作为构造函数传递给它的连接。例如,对于 isClosed():
方法

try (final var pstmt = conn.prepareStatement(
                """
                INSERT INTO some_table (id, content, parent)
                VALUES (?, ?, ?)
                """)) {

    pstmt.setInt(1, 1);
    pstmt.setString(2, "first");
    pstmt.setNull(3, Types.INTGEGER); // java.sql.Types
    pstmt.executeUpdate(); // de fato altere o valor
}

其他方法依此类推。它是抽象的,因为一个简单的事实是,当我使用它时,我想强迫自己做一些除了简单委托之外的事情。

好吧,我们走吧。这个想法是,将请求连接,该连接可能存在也可能不存在。如果存在,我将其包装在这个新类中,以便在关闭连接时将其返回到 pool。嗯,所以我要在 close() 方法中做一些事情...好吧,我们先包装一下。让我们将 getConnection() 保留为同步以避免并发问题:

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

好的,如果我的连接中有元素,我会使用它们直到它为空。但它永远不会被填满!那么我们要解决这个问题吗?当它关闭时,我们可以将其返回

INSERT INTO some_table (id, content, parent)
VALUES (?, ?, ?)

-- 1, 'first', NULL

好的,现在当您使用完连接后,它会被发送回
泳池。这不满足 Connection#close() 方法的文档,因为在文档中它提到它释放与此连接相关的所有 JDBC 资源。这意味着我需要保留所有语句、结果集、PreparedStatements 等的记录。我们可以通过在 ConnectionDelegator 上创建一个名为 closeAllInnerResources() 的受保护方法来处理此问题。并在 close() 中调用它:

-- (value, value, NULL)
INSERT INTO some_table (id, content, parent)
VALUES (?, ?, NULL)
-- 1, 'first'

这样我们就可以根据需要向我返回连接,并且能够形成资源池

你知道Java给提供连接的对象起什么名字吗?数据源。您知道 Java 对 DataSource 还说了什么吗?从概念上讲,有一些类型。在这些类型中,最相关的 2 种是:

  • 基本:它不进行池化,它请求连接,它只是创建并返回它
  • 池化:其中存在与银行的连接池

这里我们经历了始终创建连接(基本类型)以及演变为数据源的过程
合并

什么是光CP?

HikariCP 是一个数据源。具体来说,是一个池化数据源。但他有一个特点:他是所有人中速度最快的。为了保证这个速度,在应用程序生命周期中使用的连接中,HikariCP 制定了一个秘密:它已经创建了所有可用的连接。因此,当 getConnection 到达时,HikariCP 只需要检查连接池

如果你想更深入地研究这个主题,你可以查看 Baeldung 上有关该主题的这篇文章,也可以查看 github 上的存储库。

以上是什么是光池?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JVM中的类加载程序子系统如何促进平台独立性?JVM中的类加载程序子系统如何促进平台独立性?Apr 23, 2025 am 12:14 AM

类加载器通过统一的类文件格式、动态加载、双亲委派模型和平台无关的字节码,确保Java程序在不同平台上的一致性和兼容性,实现平台独立性。

Java编译器会产生特定于平台的代码吗?解释。Java编译器会产生特定于平台的代码吗?解释。Apr 23, 2025 am 12:09 AM

Java编译器生成的代码是平台无关的,但最终执行的代码是平台特定的。1.Java源代码编译成平台无关的字节码。2.JVM将字节码转换为特定平台的机器码,确保跨平台运行但性能可能不同。

JVM如何处理不同操作系统的多线程?JVM如何处理不同操作系统的多线程?Apr 23, 2025 am 12:07 AM

多线程在现代编程中重要,因为它能提高程序的响应性和资源利用率,并处理复杂的并发任务。JVM通过线程映射、调度机制和同步锁机制,在不同操作系统上确保多线程的一致性和高效性。

在Java的背景下,'平台独立性”意味着什么?在Java的背景下,'平台独立性”意味着什么?Apr 23, 2025 am 12:05 AM

Java的平台独立性是指编写的代码可以在任何安装了JVM的平台上运行,无需修改。1)Java源代码编译成字节码,2)字节码由JVM解释执行,3)JVM提供内存管理和垃圾回收功能,确保程序在不同操作系统上运行。

Java应用程序仍然可以遇到平台特定的错误或问题吗?Java应用程序仍然可以遇到平台特定的错误或问题吗?Apr 23, 2025 am 12:03 AM

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算如何影响Java平台独立性的重要性?云计算如何影响Java平台独立性的重要性?Apr 22, 2025 pm 07:05 PM

云计算显着提升了Java的平台独立性。 1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。 2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java的平台独立性在广泛采用中扮演着什么角色?Java的平台独立性在广泛采用中扮演着什么角色?Apr 22, 2025 pm 06:53 PM

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技术(例如Docker)如何影响Java平台独立性的重要性?容器化技术(例如Docker)如何影响Java平台独立性的重要性?Apr 22, 2025 pm 06:49 PM

容器化技术如Docker增强而非替代Java的平台独立性。1)确保跨环境的一致性,2)管理依赖性,包括特定JVM版本,3)简化部署过程,使Java应用更具适应性和易管理性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版