搜索
首页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性能与其他语言May 14, 2025 am 12:16 AM

JVM'SperformanceIsCompetitiveWithOtherRuntimes,operingabalanceOfspeed,安全性和生产性。1)JVMUSESJITCOMPILATIONFORDYNAMICOPTIMIZAIZATIONS.2)c提供NativePernativePerformanceButlanceButlactsjvm'ssafetyFeatures.3)

Java平台独立性:使用示例Java平台独立性:使用示例May 14, 2025 am 12:14 AM

JavaachievesPlatFormIndependencEthroughTheJavavIrtualMachine(JVM),允许CodeTorunonAnyPlatFormWithAjvm.1)codeisscompiledIntobytecode,notmachine-specificodificcode.2)bytecodeisisteredbytheybytheybytheybythejvm,enablingcross-platerssectectectectectross-eenablingcrossectectectectectection.2)

JVM架构:深入研究Java虚拟机JVM架构:深入研究Java虚拟机May 14, 2025 am 12:12 AM

TheJVMisanabstractcomputingmachinecrucialforrunningJavaprogramsduetoitsplatform-independentarchitecture.Itincludes:1)ClassLoaderforloadingclasses,2)RuntimeDataAreafordatastorage,3)ExecutionEnginewithInterpreter,JITCompiler,andGarbageCollectorforbytec

JVM:JVM与操作系统有关吗?JVM:JVM与操作系统有关吗?May 14, 2025 am 12:11 AM

JVMhasacloserelationshipwiththeOSasittranslatesJavabytecodeintomachine-specificinstructions,managesmemory,andhandlesgarbagecollection.ThisrelationshipallowsJavatorunonvariousOSenvironments,butitalsopresentschallengeslikedifferentJVMbehaviorsandOS-spe

Java:写一次,在任何地方跑步(WORA) - 深入了解平台独立性Java:写一次,在任何地方跑步(WORA) - 深入了解平台独立性May 14, 2025 am 12:05 AM

Java实现“一次编写,到处运行”通过编译成字节码并在Java虚拟机(JVM)上运行。1)编写Java代码并编译成字节码。2)字节码在任何安装了JVM的平台上运行。3)使用Java原生接口(JNI)处理平台特定功能。尽管存在挑战,如JVM一致性和平台特定库的使用,但WORA大大提高了开发效率和部署灵活性。

Java平台独立性:与不同的操作系统的兼容性Java平台独立性:与不同的操作系统的兼容性May 13, 2025 am 12:11 AM

JavaachievesPlatFormIndependencethroughTheJavavIrtualMachine(JVM),允许Codetorunondifferentoperatingsystemsswithoutmodification.thejvmcompilesjavacodeintoplatform-interploplatform-interpectentbybyteentbytybyteentbybytecode,whatittheninternterninterpretsandectectececutesoneonthepecificos,atrafficteyos,Afferctinginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginging

什么功能使Java仍然强大什么功能使Java仍然强大May 13, 2025 am 12:05 AM

JavaispoperfulduetoitsplatFormitiondence,对象与偏见,RichstandardLibrary,PerformanceCapabilities和StrongsecurityFeatures.1)Platform-dimplighandependectionceallowsenceallowsenceallowsenceallowsencationSapplicationStornanyDevicesupportingJava.2)

顶级Java功能:开发人员的综合指南顶级Java功能:开发人员的综合指南May 13, 2025 am 12:04 AM

Java的顶级功能包括:1)面向对象编程,支持多态性,提升代码的灵活性和可维护性;2)异常处理机制,通过try-catch-finally块提高代码的鲁棒性;3)垃圾回收,简化内存管理;4)泛型,增强类型安全性;5)ambda表达式和函数式编程,使代码更简洁和表达性强;6)丰富的标准库,提供优化过的数据结构和算法。

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

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

热门文章

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具