HyperSQL DataBase (HSQLDB)
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
,NUMERIC
aDECIMAL
- logický datový typ
BOOLEAN
- znakové řetězcové datové typy
CHAR
,VARCHAR
aCLOB
- binární řetězcové typy
BINARY
,VARBINARY
aBLOB
- bitový řetězcové typy
BIT
aBIT VARYING
- datové typy pro práci s časem
DATE
,TIME
,TIMESTAMP
aTIMESTAMP 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.