Adatbázis-programozás

A Java nyelv hálózati lehetőségei miatt ideálisan megfelel kliens-szerver architektúrájú adatbáziskezelő programok létrehozására. Ezért felmerült az igény, hogy a Java programok kommunikálni tudjanak a legkülönfélébb adatbázisokkal is. Ezen kommunikáció lehetőségét a JDBC biztosítja.

Egyszerű (DISTINCT) felhasználói SQL típus

Ezen SQL adattípus tulajdonképp egy egyszerű SQL alaptípus megfelelően paraméterezett változata. Példák:
CREATE TYPE RÖVIDNÉV AS CHAR(20);
CREATE TYPE PÉNZ AS NUMERIC(10,2);

Struktúrált (STRUCT) felhasználói SQL típus

Ezen SQL adattípus más SQL típusokból összetevődő struktúrát ír le. Példák:
CREATE TYPE LAKHELY 
     (
             AJTÓ VARCHAR(20),
             HÁZSZÁM NUMERIC(6),
             UTCA VARCHAR(100), 
             VÁROS VARCHAR(50),
             IRÁNYÍTÓSZÁM CHAR(8),
             TULAJDONOS REF(SZEMÉLY)
     );
CREATE TYPE TELJESNÉV
     (
             VEZETÉKNÉV VARCHAR(50),
             KERESZTNÉV VARCHAR(50)
     );
CREATE TYPE SZEMÉLY 
     (
             NÉV TELJESNÉV,
             CÍM REF(LAKHELY),
             TELEFON VARCHAR(20),
             FOTÓ BLOB
     );

Felhasználói SQL adattípusok Java megfeleltetése

A leírtak szemléltetésére tekintsük az előző két példában definiált felhasználói SQL típusok Java reprezentációit. A Dolgozó osztály egyben példa arra is, hogy hogyan lehet a reprezentáló osztályokkal az SQL öröklődési hierarhiát követni. Ehhez az SQL típust a következőképp definiáltuk:
CREATE TYPE SZEMÉLY AS OBJECT (...);
CREATE TYPE DOLGOZÓ AS OBJECT EXTENDS SZEMÉLY (BÉR PÉNZ);
Már csak a típusmegfeleltetés megadása maradt hátra:
Connection con=...
try {
    java.util.Map map = con.getTypeMap();
    map.put("RÖVIDNÉV", Class.forName("Rövidnév"));
    map.put("PÉNZ", Class.forName("Pénz"));
    map.put("LAKHELY", Class.forName("Lakhely"));
    map.put("TELJESNÉV", Class.forName("Teljesnév"));
    map.put("SZEMÉLY", Class.forName("Személy"));
    map.put("DOLGOZÓ", Class.forName("Dolgozó"));
} catch (ClassNotFoundException ex) {}

Eredményfeldolgozás

A következő kódrészlet biztosítja egy végrehajtott SQL utasítás összes visszaadott eredménykomponensének feldolgozását:
    Connection con = DriverManager.getConnection(url, "uid", "password");
                                                //adatbáziskapcsolat létrehozása
    Statement stmt = con.createStatement();       //utasításobjektum létrehozása

    stmt.execute(SQL_utasítás);                      //SQL utasítás végrehajtása
    int rowCount;
    while (true)  {
      rowCount = stmt.getUpdateCount();
      if (rowCount >= 0) {                                   //volt sormódosítás
        System.out.println("Megváltozott sorok száma = " + rowCount);
        stmt.getMoreResults();        //következő eredménykomponens feldolgozása
        continue;
      }
      ResultSet rs = stmt.getResultSet();                   //eredménytábla volt
      if (rs != null) {                             //eredménytábla feldolgozása
         ...
         stmt.getMoreResults();       //következő eredménykomponens feldolgozása
         continue;
      }
      break;                                      //nincs több eredménykomponens
    }

Példa kötegelt végrehajtásra

int[] updateCounts;
Connection con=...
try {
    con.setAutoCommit(false);

    Statement stmt = con.createStatement();
    stmt.addBatch("CREATE TABLE NEVEK OF TELJESNÉV");
    stmt.addBatch("INSERT INTO NEVEK VALUES ('Gábor', 'Dénes')");
    stmt.addBatch("INSERT INTO NEVEK VALUES ('Máté', 'Barbara')");
    stmt.addBatch("INSERT INTO NEVEK VALUES ('Csilla', 'Péter')");
    stmt.addBatch("DELETE FROM NEVEK");
    updateCounts = stmt.executeBatch(); // {0, 1, 1, 1, 3}

    PreparedStatement pstmt = con.prepareStatement(
                  "INSERT INTO NEVEK VALUES (?, ?)");

    pstmt.setString(1, "Névtelen");
    for (int i=1; i<=10; i++) {
        pstmt.setString(2, "Felhasználó"+i );
        pstmt.addBatch();
    }
    updateCounts = pstmt.executeBatch(); // {1,1,1,1,1,1,1,1,1,1}

    stmt.addBatch("SELECT * FROM NEVEK");     // itt még nem, de
    updateCounts = stmt.executeBatch(); // itt Exception!!!!
    
} catch (BatchUpdateException bue) {
        System.err.println("BatchUpdateException: " + bue.getMessage());
        System.err.println("SQLState:  " + bue.getSQLState());
        System.err.println("ErrorCode:  " + bue.getErrorCode());
        System.err.println("Sikeres végrehajtások sormódosítási számai:");
        updateCounts = bue.getUpdateCounts();
        for (int i=1; i<=updateCounts.length; i++) {
             System.err.println("\t" + i + ".: " + updateCounts[i]);
        }
} catch (SQLException e) {
        System.err.println("SQLException: " + e.getMessage());
        System.err.println("SQLState:  " + e.getSQLState());
        System.err.println("ErrorCode:  " + e.getErrorCode());
}

Példa

A következő példa egy általános JDBC adatbázis-elérési felületet nyújt. Használható mind alkalmazásként, mind appletként, persze ilyenkor figyelembe kell venni az ismertetett megkötéseket.