7.1 Tilslutningspulje

I dag skal vi lære at arbejde med databasen endnu mere professionelt. Og nu skal vi tale om trådpuljen eller forbindelsespuljen på engelsk.

Det tager noget tid at oprette forbindelse til databasen. Især hvis databasen er fjerntliggende. Hvis vi opretter forbindelse til databasen for hver anmodning, vil svaret fra vores applikation være utroligt langsomt i hastighed. For ikke at nævne de ressourcer, det vil forbruge.

Som en løsning på sådanne problemer blev det foreslået at gemme forbindelser til basen i et sæt, som kaldes trådpuljen.

Når vi anmoder om en ny forbindelse, opretter forbindelsespuljen den, og når den lukkes, lukker den den ikke, men gemmer den i forbindelsespuljen. Og hvis vi anmoder om en forbindelse fra forbindelsespuljen igen, vil det give os en af ​​de gamle i stedet for at oprette en ny.

Faktisk fungerer applikationen gennem en speciel driver, som er en indpakning til en almindelig JDBC-driver, og som har yderligere funktionalitet til at arbejde med poolen. Denne situation kan repræsenteres som følger:

tilslutningspool

Programmøren kan indstille indstillingerne for forbindelsespuljen manuelt: antallet af aktive forbindelser, timeout osv.

I særligt ekstreme situationer kan du skrive din egen forbindelsespulje: en klasse, der vil have en liste over forbindelser. Det vil tilsidesætte lukkefunktionen, som vil returnere forbindelsen tilbage til listen, og der vil være mange andre godbidder som den åbne forbindelsestimer. Når der ikke er forbindelse i længere tid, lukkes forbindelsen.

7.2* Interface DataSource og ConnectionPoolDataSource

Trådpuljen fungerer normalt sammen med DataSource-objektet. Dette objekt kan opfattes som en abstraktion af en fjerndatabase. Selve navnet Datakilde kan bogstaveligt oversættes som Datakilde. Hvilket er en slags antydning.

DataSource-objekter bruges til at opnå en fysisk forbindelse til en database og er et alternativ til DriverManager. Det er ikke nødvendigt at registrere JDBC-driveren. Du behøver kun at indstille de relevante parametre for at etablere en forbindelse ogudfør getConnection() metoden.

Når du opretter et objekt af typen DataSource lokalt (direkte i applikationen), indstilles forbindelsesparametrene ved hjælp af de relevante metoder leveret af JDBC-driverudbyderen. Disse metoder er ikke defineret af DataSource-grænsefladen, da parametrene for at oprette forbindelse til DBMS fra forskellige leverandører kan variere både i type og antal (f.eks. kræver ikke alle DBMS, at typen af ​​driver eller netværksprotokol angives).

Når du arbejder med Oracle DBMS, for at bruge det tilsvarende sæt og få-metoder, er det således nødvendigt at opnå et objekt af typen OracleDataSource, som er en forekomst af klassen af ​​samme navn, der implementerer DataSource-grænsefladen. Derfor gør denne måde at oprette objekter af typen DataSource din kode på mindre bærbar og mindre afhængig af den specifikke implementering af driveren.

Det følgende er et kodeeksempel, der illustrerer den lokale brug af objekter af typen DataSource.

import java.sql.*;
import javax.sql.*;
import oracle.jdbc.driver.*;
import oracle.jdbc.pool.*;

public class DataSource {
    public static void main(String[] args) {
    	try {
        	OracleDataSource ods = new OracleDataSource();

        	ods.setUser("root");
        	ods.setPassword("secret");
        	ods.setDriverType("thin");
        	ods.setDatabaseName("test");
        	ods.setServerName("localhost");
        	ods.setPortNumber(1521);

        	Connection connection = ods.getConnection();
        	System.out.println("Connection successful!!!");

    	} catch (SQLException se) {
        	se.printStackTrace();
    	}
    	System.out.println("Goodbye!");
	}
}

7.3* JNDI-grænseflade

De fulde muligheder for objekter af typen DataSource manifesteres i kombination med brugen af ​​JNDI-grænsefladen. JNDI er en speciel tjeneste (noget som en mappe) til store serverapplikationer, der gør det muligt for en tjeneste at etablere forbindelse med en anden.

Ved at bruge navnet og bibliotekstjenesten kan du gemme objekter af typen DataSource, som tidligere er oprettet af systemadministratoren med foruddefinerede forbindelsesparametre. Følgende er nogle af standardegenskabsnavnene (parameternavne) udviklet af Sun:

Ejendomsnavn Java datatype Formål
databasenavn Snor Database navn
server navn Snor Server navn
bruger Snor Brugernavn (ID)
adgangskode Snor Brugeradgangskode
portnummer int DBMS server portnummer

Kombinationen af ​​DataSource- og JNDI-grænseflader spiller en nøglerolle i udviklingen af ​​multi-tier virksomhedsapplikationer baseret på J2EE-komponentteknologi.

Hvis du bruger en kombination af DataSource- og JNDI-grænsefladerne i din applikationskode, behøver du kun at anmode om et objekt af typen DataSource fra navngivnings- og katalogtjenesten. I dette tilfælde er detaljerne om forbindelsen og programkoden afhængig af en bestemt implementering af driveren skjult fra applikationen i objektet, der er gemt i navnet og bibliotekstjenesten.

Således involverer deling af objekter af typen DataSource og JNDI to trin, der udføres uafhængigt af hinanden:

  1. Du skal gemme det navngivne objekt af typen DataSource i navngivnings- og katalogtjenesten ved hjælp Context.bind()af javax.naming.
  2. Anmod om et objekt af typen DataSource fra navngivnings- og bibliotekstjenesten i applikationen ved hjælp af Context.lookup(). Derefter kan du bruge dens metode DataSource.getConnection()til at få en forbindelse til databasen.

Det følgende er et eksempel på at bruge JNDI-grænsefladen og et objekt af typen OracleDataSource sammen.

// Create a key JNDI object
Hashtable env = new Hashtable();
env.put (Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put (Context.PROVIDER_URL, "file:JNDI");
Context ctx = new InitialContext(env);

// Get the DataSource object by its name
DataSource ods = (DataSource) ctx.lookup("myDatabase");

// Get the Connection from the DataSource object
Connection connection = ods.getConnection();
System.out.println("Connection successful!!!");

Vi vil ikke analysere JNDI's arbejde. Dette er uden for dette kursuss rammer. Jeg vil bare have dig til at vide, at denne tilgang er meget almindelig i store applikationer. Gå ikke tabt, hvis du ser kode som denne i fremtiden.

Det er lige meget, hvordan det fungerer. Du skal bare vide, at med en JNDI-tjeneste kan du få proxy-objektet for enhver tjeneste, der er registreret i tjenestekataloget. Sådan får du DataSource-objektet og bruger det til at arbejde med databasen.

7.4 Eksempler på forbindelsespool

Lad os vende tilbage til, hvor vi startede - forbindelsespuljer.

Java-programmører i deres programmer bruger meget ofte biblioteker, der indeholder forskellige implementeringer af forbindelsespuljer. Blandt dem er der tre mest populære:

  • Apache Commons DBCP
  • C3PO
  • HikariCP

Apache-projektet var det første til at skabe en god forbindelsespulje, den bruges også inde på Tomcat-webserveren. Et eksempel på at arbejde med det:

public class DBCPDataSource {

    private static BasicDataSource ds = new BasicDataSource();
    static {
    	ds.setUrl("jdbc:h2:mem:test");
    	ds.setUsername("user");
    	ds.setPassword("password");
    	ds.setMinIdle(5);
    	ds.setMaxIdle(10);
    	ds.setMaxOpenPreparedStatements(100);
    }

    public static Connection getConnection() throws SQLException {
    	return ds.getConnection();
    }

    private DBCPDataSource(){ }
}

Den anden meget populære pool er C3PO . Mærkelige navne, jeg er enig. Navnet C3PO er en reference til c3po-robotten fra Star Wars. Og også CP er en forkortelse for Connection Pool.

public class C3p0DataSource {

    private static ComboPooledDataSource cpds = new ComboPooledDataSource();
    static {
    	try {
        	cpds.setDriverClass("org.h2.Driver");
        	cpds.setJdbcUrl("jdbc:h2:mem:test");
        	cpds.setUser("user");
        	cpds.setPassword("password");
    	} catch (PropertyVetoException e) {
            // handle the exception
    	}
    }

    public static Connection getConnection() throws SQLException {
    	return cpds.getConnection();
    }

    private C3p0DataSource(){}
}

Dokumentation for det kan findes på den officielle side .

Og endelig er den mest populære forbindelsespool i vores tid HikariCP :

public class HikariCPDataSource {

    private static HikariConfig config = new HikariConfig();
    private static HikariDataSource ds;

    static {
    	config.setJdbcUrl("jdbc:h2:mem:test");
    	config.setUsername("user");
    	config.setPassword("password");
    	config.addDataSourceProperty("cachePrepStmts", "true");
    	config.addDataSourceProperty("prepStmtCacheSize", "250");
    	config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    	ds = new HikariDataSource(config);
    }

    public static Connection getConnection() throws SQLException {
    	return ds.getConnection();
    }

    private HikariCPDataSource(){}
}

Her er hans officielle GitHub- side .

Og en god artikel om konfiguration.