> Java > java지도 시간 > 히카리풀이란?

히카리풀이란?

Mary-Kate Olsen
풀어 주다: 2025-01-07 16:08:41
원래의
953명이 탐색했습니다.

O que é o hikari pool?

히카리풀이란?

BlueSky에 게시된 이 간단한 질문은 제가 정말 멋지다고 생각했던 설명으로 이어졌습니다. 마무리하러 왔습니다.

구체적인 맥락에서 히카리 커넥션 풀(Hikari Connection Pool)이 거론되고 있었습니다. 그런데 히카리가 Connection Pool이라면 "Pool"은 무엇일까요?

가장 먼저, 수영장 컨셉

HikariCP가 무엇인지 설명하기 전에 커넥션 풀이 무엇인지 먼저 설명해야 합니다. 그리고 커넥션 풀을 설명하려면 을 설명해야 합니다.

이를 경제적 비유로 들어볼까요? 현실 세계와의 결점과 부정확함으로 가득 찬 역사적 경제 비유입니다. 하지만 설명을 위해서라면 빨리 불신을 멈춰주세요! 독립형입니다.

당신이 중세 시대의 영주/부인이라고 상상해 보세요. 당신은 농민의 일을 수행하기 위한 도구를 쥐고 있습니다. 그리고 당신은 그들이 일하기를 원합니다. 그러면 이것을 어떻게 보장합니까? 도구가 당신의 것이라면? 간단하게 농민들에게 도구를 전달해야 합니다.

상황을 상상해 보세요. 농부가 땅에 잡초를 뽑기 위해 괭이가 필요해서 그곳에 가서 당신에게 괭이를 요청합니다. 당신은 그에게 괭이를 주고 살아갈 것입니다. 하지만 만약 그가 그것을 돌려주지 않는다면, 그의 재고의 여자들은 어떻게 될까요? 언젠가는 끝나겠죠...

호미를 넘겨주는 대신 호미를 만들어 주는 것도 있습니다. 당신은 그 땅의 영주/부인이므로 대장장이에게 접근하여 금속을 괭이 모양으로 녹여 손잡이에 맞출 수 있습니다. 그러나 이것은 농민이 대기실에 앉아 있지 않고서는 바로 생산할 수 있는 것이 아니다. 이 새로운 기능을 만들려면 엄청난 시간과 에너지가 필요합니다.

이제 농민이 하루를 마치고 괭이를 반납하면 다음날 다른 농민이 사용할 수 있게 됩니다.

여기서 당신은 을 관리하고 있습니다. 은 다음 작업을 수행할 수 있음을 나타내는 디자인 패턴입니다.

  • 그에게 요소를 요청하세요
  • 요소를 반환

객체 에 포함된 기타 일반적인 항목:

  • 에 등록하여 요청 시 더 많은 개체를 생성할 수 있는 기능
  • 에서 개체를 삭제하는 기능(또는 해당 에서 개체 연결 해제)

JDBC 데이터베이스에 연결

그럼, 히카리CP에 좀 더 가까이 다가가 보겠습니다. 여기서는 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
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

이런 식으로 계속 사용하고 싶은데, 결국은 관용적인 사용법이거든요. 그리고 CUPID에 따르면 I는 "관용적"에서 유래합니다. 관용적인 코드를 갖는다는 취지는 ​​바로 "불필요한 정신적 부담을 줄인다"는 것이다.

이 문제를 해결하기 위해 내 선택은: prepareStatement를 ExecuteUpdate 전 마지막 순간까지 그대로 두는 것이었습니다. 그래서 적용할 Null을 모두 저장하고 실제로 Null이 필요하다는 것을 알게 되면 문자열 대체를 실행하고 새 쿼리를 생성하면 이 새 쿼리가 실제로 실행됩니다.

이 경우에는 다음으로 시작합니다.

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:, so:
를 반복하지 않음을 나타냅니다.

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ão sem jdbc:>
\__/ \____________/
 |    |
 |    Nome do meu driver
 Padrão para indicar JDBC
로그인 후 복사

실제 드라이버 코드에는 HikariCP, DataSource, JDBC 또는 이 게시물에서 다루는 주제에 대한 논의와 관련이 없는 몇 가지 추가 사항이 있습니다.

따라서 DriverManager에 "null safe" 연결을 요청할 때 먼저 내 드라이버를 찾고 내 드라이버는 내부적으로 연결 가능성이 있는지 재귀적으로 확인하려고 시도합니다. 이를 처리할 수 있는 드라이버가 있는 것을 확인하면 가능하다고 대답합니다.

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 리소스를 해제한다고 언급하기 때문입니다. 이는 모든 명령문, 결과 집합, 준비된 명령문 등의 기록을 유지해야 함을 의미합니다. closeAllInnerResources()라는 ConnectionDelegator에 보호된 메서드를 생성하여 이를 처리할 수 있습니다. 그리고 close()로 호출하세요.

-- (value, value, NULL)
INSERT INTO some_table (id, content, parent)
VALUES (?, ?, NULL)
-- 1, 'first'
로그인 후 복사
로그인 후 복사
로그인 후 복사

그리고 이를 통해 필요할 때 나에게 연결을 반환하고 리소스 을 형성할 수 있는 기능을 갖게 되었습니다.

Java가 연결을 제공하는 객체에 어떤 이름을 붙이는지 아시나요? 데이터소스. 그리고 Java가 DataSource에 관해 또 뭐라고 말하는지 아시나요? 개념적으로 말하면 몇 가지 유형이 있습니다. 이러한 유형 중 가장 관련성이 높은 두 가지 유형은 다음과 같습니다.

  • 기본: 풀링을 수행하지 않고 연결을 요청하고 연결만 생성하고 반환합니다
  • 풀링: 은행과의 연결이 풀링됩니다

그리고 여기서는 항상 연결(기본 유형)을 생성하고 DataSource로 진화하는 과정을 거칩니다.
풀링.

히카리CP란 무엇인가요?

HikariCP는 데이터 소스입니다. 특히 풀링된 데이터 소스입니다. 그러나 그에게는 한 가지 특징이 있습니다. 그는 가장 빠른 사람입니다. 이 속도를 보장하기 위해 애플리케이션 수명 주기 동안 사용할 연결 에서 HikariCP는 비밀을 만듭니다. 즉, 사용 가능한 모든 연결을 이미 생성한다는 것입니다. 따라서 getConnection이 도착하면 HikariCP는 연결 풀

만 확인하면 됩니다.

이 주제에 대해 더 자세히 알아보고 싶다면 해당 주제에 대한 Baeldung의 기사를 확인하고 Github의 저장소도 확인하세요.

위 내용은 히카리풀이란?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿