7.1 Csatlakozási medence

Ma megtanuljuk, hogyan kell még professzionálisabban dolgozni az adatbázissal. És most a thread pool-ról vagy angolul connect pool-ról fogunk beszélni .

Az adatbázishoz való csatlakozás eltart egy ideig. Főleg, ha az adatbázis távoli. Ha minden kérésre kapcsolatot létesítünk az adatbázissal, akkor alkalmazásunk válasza hihetetlenül lassú lesz. Nem beszélve az erőforrásokról, amelyeket fel fog fogyasztani.

Az ilyen problémák megoldásaként azt javasolták, hogy az alaphoz való kapcsolatokat valamilyen halmazban tárolják, amelyet szálkészletnek neveznek.

Amikor új kapcsolatot kérünk, a kapcsolatkészlet létrehozza, bezárásakor pedig nem zárja be, hanem elmenti a kapcsolatkészletbe. És ha újra kérünk kapcsolatot a kapcsolatkészletből, akkor a régiek közül egyet ad nekünk, ahelyett, hogy újat hozna létre.

Valójában az alkalmazás egy speciális illesztőprogramon keresztül működik, amely egy normál JDBC-illesztőprogram burkolója, és amely további funkciókkal rendelkezik a készlettel való együttműködéshez. Ez a helyzet a következőképpen ábrázolható:

kapcsolati medence

A programozó manuálisan állíthatja be a kapcsolatkészlet beállításait: az aktív kapcsolatok számát, az időtúllépést stb.

Különösen szélsőséges helyzetekre írhat saját kapcsolati készletet: egy osztályt, amelynek lesz egy listája a kapcsolatokról. Ez felülírja a bezárás funkciót, amely visszaadja a kapcsolatot a listába, és sok más jóság is lesz, például a nyitott kapcsolat időzítője. Ha hosszabb ideig nincs kapcsolat, a kapcsolat megszakad.

7.2* Interfész DataSource és ConnectionPoolDataSource

A szálkészlet általában a DataSource objektummal párhuzamosan működik. Ez az objektum egy távoli adatbázis absztrakciójának tekinthető. A Data Source név szó szerint lefordítható adatforrásnak. Ami egyfajta célzás.

A DataSource objektumok az adatbázishoz való fizikai kapcsolat létrehozására szolgálnak, és a DriverManager alternatívái. Nincs szükség a JDBC illesztőprogram regisztrálására. Csak a megfelelő paramétereket kell beállítania a kapcsolat létrehozásához éshajtsa végre a getConnection() metódust.

Amikor egy DataSource típusú objektumot helyileg (közvetlenül az alkalmazásban) hoz létre, a csatlakozási paraméterek beállítása a JDBC illesztőprogram-szolgáltató által biztosított megfelelő módszerekkel történik. Ezeket a metódusokat nem a DataSource interfész határozza meg, mivel a különböző gyártók DBMS-hez való csatlakozásának paraméterei típusban és számban is eltérhetnek (például nem minden DBMS-hez szükséges az illesztőprogram vagy a hálózati protokoll típusának megadása).

Így az Oracle DBMS-sel végzett munka során a megfelelő készlet használatához és a metódusok lekéréséhez be kell szerezni egy OracleDataSource típusú objektumot, amely a DataSource interfészt megvalósító azonos nevű osztály példánya. Ezért a DataSource típusú objektumok létrehozásának ez a módja kevésbé hordozhatóvá teszi a kódot, és kevésbé függ az illesztőprogram konkrét megvalósításától.

Az alábbi kódpélda a DataSource típusú objektumok helyi használatát illusztrálja.

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 interfész

A DataSource típusú objektumok teljes képessége a JNDI interfész használatával együtt nyilvánul meg. A JNDI egy speciális szolgáltatás (olyan, mint egy címtár) nagy szerveralkalmazásokhoz, amely lehetővé teszi, hogy az egyik szolgáltatás kapcsolatot létesítsen a másikkal.

A név- és címtárszolgáltatás használatával a rendszergazda által korábban létrehozott DataSource típusú objektumok tárolhatók előre meghatározott kapcsolati paraméterekkel. Íme néhány a Sun által kifejlesztett szabványos tulajdonság- (paraméter) név:

Ingatlan neve Java adattípus Célja
adatbázis név Húr Adatbázis név
szerver név Húr Szerver név
felhasználó Húr Felhasználónév (azonosító)
Jelszó Húr Felhasználói jelszó
portNumber int DBMS-kiszolgáló portszáma

A DataSource és a JNDI interfészek kombinációja kulcsszerepet játszik a J2EE komponens technológián alapuló többrétegű vállalati alkalmazások fejlesztésében.

Ha az alkalmazás kódjában a DataSource és a JNDI interfészek kombinációját használja, akkor csak egy DataSource típusú objektumot kell kérnie az elnevezési és címtárszolgáltatástól. Ebben az esetben a kapcsolat részletei és az illesztőprogram egy adott megvalósításától függő programkód rejtve marad az alkalmazás elől a név- és címtárszolgáltatásban tárolt objektumban.

Így a DataSource és JNDI típusú objektumok megosztása két lépésből áll, amelyeket egymástól függetlenül hajtanak végre:

  1. Tárolnia kell a DataSource típusú elnevezett objektumot az elnevezési és címtárszolgáltatásban Context.bind()a javax.naming.
  2. Kérjen egy DataSource típusú objektumot az alkalmazás elnevezési és címtárszolgáltatásától a Context.lookup(). Ezt követően a módszerével DataSource.getConnection()kapcsolatot létesíthet az adatbázissal.

Az alábbiakban egy példa a JNDI felület és egy OracleDataSource típusú objektum együttes használatára.

// 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!!!");

Nem elemezzük a JNDI munkáját. Ez kívül esik a tanfolyam keretein. Csak szeretném, ha tudná, hogy ez a megközelítés nagyon gyakori a nagy alkalmazásokban. Ne essen el, ha a jövőben ilyen kódot lát.

Nem mindegy, hogyan működik. Csak tudnia kell, hogy a JNDI szolgáltatással bármely szolgáltatás proxy objektumát megkaphatja, amely a szolgáltatási címtárban regisztrált. Így kaphatja meg a DataSource objektumot, és használhatja azt az adatbázissal való együttműködéshez.

7.4 Példák a csatlakozási készletre

Térjünk vissza oda, ahonnan indultunk – a kapcsolati medencékhez.

A Java programozók programjaikban nagyon gyakran használnak olyan könyvtárakat, amelyek a kapcsolatkészletek különféle megvalósításait tartalmazzák. Közülük három legnépszerűbb:

  • Apache Commons DBCP
  • C3PO
  • HikariCP

Az Apache projekt volt az első, aki jó kapcsolatkészletet hozott létre, ezt használják a Tomcat webszerveren belül is. Egy példa a vele való munkára:

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(){ }
}

A második nagyon népszerű pool a C3PO . Furcsa nevek, egyetértek. A C3PO név a Star Wars c3po robotjára utal. A CP pedig a Connection Pool rövidítése.

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(){}
}

Ennek dokumentációja megtalálható a hivatalos oldalon .

És végül, korunk legnépszerűbb Connection Poolja a 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(){}
}

Itt van a hivatalos GitHub oldala .

És egy jó cikk a konfigurációról.