HyperSQL DataBase (HSQLDB)
V předchozím kvízu, Kvíz - Databáze v Javě, jsme si ověřili nabyté zkušenosti z kurzu.
HyperSQL DataBase (HSQLDB) je open source SQL databáze napsaná v Javě. V tomto článku se na HSQLDB podíváme blíže a ukážeme si, jak s databází pracovat pomocí rozhraní JDBC (Java Database Connectivity).
Stažení
HSQLDB je k dispozici volně ke stažení z adresy http://hsqldb.org. V balíku ZIP v adresáři lib naleznete soubor hsqldb.jar, který obsahuje současně:
- databázový engine HSQLDB
- ovladač JDBC
- HSQL Database Manager - nástroj s grafickým uživatelským rozhraním pro správu databází
Spuštění
HSQLDB podporuje různé režimy spuštění a uložení dat. Režim se zvolí na základě URL pro ovladač JDBC při vytváření spojení.
Databázi lze spustit:
- přímo v aplikaci, která k databázi přistupuje (in-process)
- jako samostatnou aplikaci (server mode)
Databáze podporuje různé způsoby uložení dat:
- operační paměť
- soubor
- zdroje na class path (resource)
1a) Spuštění in-process s uložením dat v operační paměti
Zadáme-li URL ve formátu jdbc:hsqldb:mem:NAZEV_DATABAZE, v
operační paměti se při prvním volání metody
DriverManager.getConnection vytvoří nová databáze s názvem
NAZEV_DATABAZE.
V rámci jednoho procesu lze vytvořit více databází s různými názvy. K databázi lze přistupovat z více vláken současně, ale nemohou k ní přistupovat ostatní procesy. Databáze zanikne při jejím zastavení.
Příklad 1: Vytvoření databáze v operační paměti. Databáze se vytvoří během vytváření databázového spojení.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mojedatabaze"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MojeTabulka (id BIGINT, text VARCHAR(100))");
1b) Spuštění in-process s uložením dat v souboru
Zadáme-li URL ve formátu jdbc:hsqldb:file:CESTA_K_SOUBORU,
databáze se načte z požadovaného souboru. Pokud soubor neexistuje, je
automaticky vytvořen včetně případných adresářů.
K databázi lze opět přistupovat z více vláken současně, nikoliv ale z různých procesů současně. Proces, který s databází pracuje, datové soubory zamkne, takže jsou pro ostatní procesy nepřístupné. Po ukončení procesu zůstane databáze zachována. Nejsou-li datové soubory zamčeny, lze je otevřít pomocí nástroje HSQL Database Manager.
Příklad 2: Vytvoření databáze na souborovém systému. Data se uloží do souborů do adresáře databaze. Opakované spuštění ukázkového programu selže s chybou, protože tabulka již bude existovat.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:file:databaze/mojedatabaze"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MojeTabulka (id BIGINT, text VARCHAR(100))"); ...
1c) Spuštění in-process s uložením dat v resource
Zadáme-li URL ve formátu jdbc:hsqldb:res:CESTA_K_ZDROJI,
databáze se načte ze zadaného zdroje na class path. Formát souborů je
shodný jako v případě uložení dat v souboru. Po načtení databáze se
databáze chová obdobně jako v případě uložení dat v operační paměti.
Do databáze lze sice zapisovat, ale změny se nikam neukládají.
2) Server mode
HSQLDB lze spustit samostatně příkazem:
java -cp hsqldb.jar org.hsqldb.server.Server
V tomto případě se vytvoří nová databáze s prázdným názvem a databázovým souborem test Databáze naslouchá na TCP portu 9001.
Pro přístup k databázi je třeba zadat URL ve formátu
jdbc:hsqldb:hsql://HOSTNAME/NAZEV_DATABAZE.
Příklad 3: Vytvoření připojení do samostatně spuštěné databáze s prázdným názvem.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost");
Při spuštění lze zadat více různých databází s různými názvy:
java -cp hsqldb.jar org.hsqldb.server.Server --database.0 file:mojedatabaze --dbname.0 mojedatabaze --database.1 mem: --dbname.1 pametovadatabaze
Příklad 4: Vytvoření připojení do samostatně spuštěné databáze mojedatabaze.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mojedatabaze");
Dobrým zvykem je při spuštění specifikovat velikost paměti pro JVM:
java -Xmx64m -cp hsqldb.jar org.hsqldb.server.Server
Popis dalších parametrů spuštění naleznete v dokumentaci na adrese http://hsqldb.org/doc/2.0/guide.
Zastavení databáze
V případě spuštění databáze in-process dojde k jejímu zastavení automaticky při ukončení procesu.
V případě spuštění databáze v server módu z příkazové řádky zastavíme databázi klávesami CTRL + C.
Databázi lze také zastavit příkazem SHUTDOWN.
HSQL Database Manager
HSQL Database Manager lze spustit z příkazového řádku příkazem:
java -jar hsqldb.jar
Pomocí tohoto nástroje se lze připojit do libovolné databáze, pro kterou je na class path k dispozici ovladač JDBC.
Příklad spuštění s ovladačem JDBC pro MySQL:
java -cp mysql-connector-java-5.1.28-bin.jar;hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
Tabulky
Při vytváření tabulek je třeba dát pozor typ. HSQLDB definuje typy
MEMORY a CACHED. Výchozím typem je
MEMORY. Tabulky typu MEMORY jsou velmi rychlé,
protože veškerá data jsou zkopírována do operační paměti. Pokud ale
paměť dojde, databáze havaruje s chybou OutOfMemoryError.
Příklad 5: Vytvoření tabulky typu MEMORY a její
plnění daty až do pádu databáze.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mojedatabaze"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MojeTabulka (id BIGINT, text VARCHAR(100))"); stmt.close(); PreparedStatement pstmt = connection.prepareStatement("INSERT INTO MojeTabulka(id, text) VALUES (?, ?)"); for (int id = 0; id < Integer.MAX_VALUE; id++) { System.out.println(id); pstmt.setLong(1, id); pstmt.setString(2, "nejaky dlouhy text " + id); pstmt.executeUpdate(); } ...
Tabulka typu CACHED není limitována velikostí přidělené
operační paměti, protože data ukládá do souboru a v operační paměti je
pouze část dat. Tabulku typu CACHED lze vytvořit příkazem
CREATE CACHED TABLE. Výchozí typ tabulek pro celou databázi je
možné změnit příkazem
SET DATABASE DEFAULT TABLE TYPE CACHED.
Tabulka typu CACHED nemá smysl v případě uložení dat v
operační paměti. V takovém případě se příznak CACHED
ignoruje.
Datové typy
Z datových typů podporuje HSQLDB:
- číselné datové typy
TINYINT,SMALLINT,INTEGER,BIGINT,NUMERICaDECIMAL - logický datový typ
BOOLEAN - znakové řetězcové datové typy
CHAR,VARCHARaCLOB - binární řetězcové typy
BINARY,VARBINARYaBLOB - bitový řetězcové typy
BITaBIT VARYING - datové typy pro práci s časem
DATE,TIME,TIMESTAMPaTIMESTAMP WITH TIME ZONE - a další
Automatická inkrementace sloupce
HSQLDB podporuje automatickou inkrementaci sloupce. Sloupec se vytvoří
pomocí klauzule GENERATED BY DEFAULT AS IDENTITY.
Příklad 6: SQL příkaz k vytvoření tabulky s primárním klíčem s automatickou inkrementací.
CREATE TABLE MojeTabulka (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
data VARCHAR(2000))
Příklad 7: Vložení řádku do tabulky s primárním klíčem s automatickou inkrementací.
Pokud do sloupce při INSERTu zadáme NULL nebo nebo hodnotu vynecháme, HSQLDB hodnotu primárního klíče vygeneruje automaticky.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mojedatabaze"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MojeTabulka (id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, data VARCHAR(2000))"); stmt.executeUpdate("INSERT INTO MojeTabulka(id, data) VALUES (NULL, 'svete')"); stmt.executeUpdate("INSERT INTO MojeTabulka(data) VALUES ('ahoj')"); ResultSet rs = stmt.executeQuery("SELECT * FROM MojeTabulka"); while (rs.next()) { System.out.println(rs.getObject(1) + " | " + rs.getObject(2)); }
Transakce
HSQLDB podporuje transakce. Aby transakce v JDBC správně fungovaly, je
třeba pomocí metody Connection.setAutoCommit(boolean) zakázat
auto commit - automatické potvrzení transakce po každé operaci.
Příklad 8: Vložení řádků do tabulky se zapnutými transakcemi.
Nejprve nastavíme auto commit na false. Metoda rollback zruší
transakci, takže nedojde k vložení řádků do tabulku. Potvrzením transakce
metodou commit dojde k vložení řádků do databáze.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mojedatabaze"); connection.setAutoCommit(false); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MojeTabulka (id INTEGER PRIMARY KEY, data VARCHAR(2000))"); stmt.executeUpdate("INSERT INTO MojeTabulka(id, data) VALUES (1, 'svete')"); stmt.executeUpdate("INSERT INTO MojeTabulka(id, data) VALUES (2, 'ahoj')"); connection.rollback(); stmt.executeUpdate("INSERT INTO MojeTabulka(id, data) VALUES (1, 'ahoj')"); stmt.executeUpdate("INSERT INTO MojeTabulka(id, data) VALUES (2, 'svete')"); connection.commit(); ResultSet rs = stmt.executeQuery("SELECT * FROM MojeTabulka"); while (rs.next()) { System.out.println(rs.getObject(1) + " | " + rs.getObject(2)); }
Závěr
HSQLDB patří řadu let mezi oblíbené SQL databáze ve světě Javy. Díky své jednoduchosti a nízkým nárokům ji ocení nejen vývojáři. Čtenářům ITnetwork může tato databáze posloužit jako výborná hračka při studiu JDBC.

