HyperSQL DataBase (HSQLDB)
V predchádzajúcom kvíze, Kvíz - Databáza v Jave, sme si overili nadobudnuté skúsenosti z kurzu.
HyperSQL DataBase (HSQLDB) je open source SQL databázy napísaná v Jave. V tomto článku sa na HSQLDB pozrieme bližšie a ukážeme si, ako s databázou pracovať pomocou rozhrania JDBC (Java Database Connectivity).
Stiahnutie
HSQLDB je k dispozícii voľne k stiahnutiu z adresy http://hsqldb.org. V balíku ZIP v adresári lib nájdete súbor hsqldb.jar, ktorý obsahuje súčasne:
- databázový engine HSQLDB
- ovládač JDBC
- HSQL Database Manager - nástroj s grafickým užívateľským rozhraním pre správu databáz
Spustenie
HSQLDB podporuje rôzne režimy spustenia a uloženie dát. Režim sa zvolí na základe URL pre ovládač JDBC pri vytváraní spojenia.
Databázu je možné spustiť:
- priamo v aplikácii, ktorá k databáze pristupuje (in-process)
- ako samostatnú aplikáciu (server mode)
Databáza podporuje rôzne spôsoby uloženie dát:
- operačná pamäť
- súbor
- zdroje na class path (resource)
1a) Spustenie in-process s uložením dát v operačnej pamäti
Ak zadáme URL vo formáte jdbc:hsqldb:mem:DATABASE_NAME
, v
operačnej pamäti sa pri prvom volanie metódy
DriverManager.getConnection
vytvorí nová databáza s názvom
DATABASE_NAME.
V rámci jedného procesu možno vytvoriť viac databáz s rôznymi názvami. K databáze je možné pristupovať z viacerých vlákien súčasne, ale nemôžu k nej pristupovať ostatné procesy. Databáza zanikne pri jej zastavení.
Príklad 1: Vytvorenie databázy v operačnej pamäti. Databáza sa vytvorí počas vytvárania databázového spojenia.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydatabase"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MyTable (id BIGINT, text VARCHAR(100))");
1b) Spustenie in-process s uložením dát v súbore
Ak zadáme URL vo formáte jdbc:hsqldb:file:FILE_PATH
, databázy
sa načíta z požadovaného súboru. Ak súbor neexistuje, je automaticky
vytvorený vrátane prípadných adresárov.
K databáze možno opäť pristupovať z viacerých vlákien súčasne, nie ale z rôznych procesov súčasne. Proces, ktorý s databázou pracuje, dátové súbory zamkne, takže sú pre ostatných procesy neprístupné. Po ukončení procesu zostane databázy zachovaná. Ak nie sú dátové súbory zamknuté, je možné ich otvoriť pomocou nástroja HSQL Database Manager.
Príklad 2: Vytvorenie databázy na súborovom systéme. Dáta sa uložia do súborov do adresára databazy. Opakované spustenie ukážkového programu zlyhá s chybou, pretože tabuľka už bude existovať.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:file:database/mydatabase"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MyTable (id BIGINT, text VARCHAR(100))"); ...
1c) Spustenie in-process s uložením dát v resource
Ak zadáme URL vo formáte jdbc:hsqldb:res:PATH_TO_SOURCE
,
databázy sa načíta zo zadaného zdroja na class path. Formát súborov je
zhodný ako v prípade uloženia dát v súbore. Po načítaní databázy sa
databáza chová obdobne ako v prípade uloženia dát v operačnej pamäti. Do
databázy možno síce zapisovať, ale zmeny sa nikam neukladajú.
2) Server mode
HSQLDB možné spustiť samostatne príkazom:
java -cp hsqldb.jar org.hsqldb.server.Server
V tomto prípade sa vytvorí nová databáza s prázdnym názvom a databázovým súborom test Databáza počúva na TCP porte 9001.
Pre prístup k databáze je potrebné zadať URL vo formáte
jdbc:hsqldb:hsql://HOSTNAME/DATABASE_NAME
.
Príklad 3: Vytvorenie pripojenie do samostatne spustené databázy s prázdnym názvom.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost");
Pri spustení možné zadať viac rôznych databáz s rôznymi názvami:
java -cp hsqldb.jar org.hsqldb.server.Server --database.0 file:mydatabase --dbname.0 mydatabase --database.1 mem: --dbname.1 memorydatabase
Príklad 4: Vytvorenie pripojenie do samostatne spustené databázy mydatabase.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mydatabase");
Dobrým zvykom je pri spustení špecifikovať veľkosť pamäte pre JVM:
java -Xmx64m -cp hsqldb.jar org.hsqldb.server.Server
Popis ďalších parametrov spustení nájdete v dokumentácii na adrese http://hsqldb.org/doc/2.0/guide.
Zastavenie databázy
V prípade spustenia databázy in-process dôjde k jej zastaveniu automaticky pri ukončení procesu.
V prípade spustenia databázy v server móde z príkazového riadku zastavíme databáze klávesmi CTRL + C.
Databázu možno tiež zastaviť príkazom SHUTDOWN
.
HSQL Database Manager
HSQL Database Manager je možné spustiť z príkazového riadka príkazom:
java -jar hsqldb.jar
Pomocou tohto nástroja sa dá pripojiť do ľubovoľnej databázy, pre ktorú je na class path k dispozícii ovládač JDBC.
Príklad spustenie s ovládačom JDBC pre MySQL:
java -cp mysql-connector-java-5.1.28-bin.jar;hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
Tabuľky
Pri vytváraní tabuliek je potrebné dať pozor typ. HSQLDB definuje typy
MEMORY
a CACHED
. Východiskovým typom je
MEMORY
. Tabuľky typu MEMORY
sú veľmi rýchle,
pretože všetky dáta sú skopírované do operačnej pamäte. Pokiaľ ale
pamäť dôjde, databázy havaruje s chybou OutOfMemoryError
.
Príklad 5: Vytvorenie tabuľky typu MEMORY
a jej
plnenie dátami až do pádu databázy.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mydatabase"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MyTable (id BIGINT, text VARCHAR(100))"); stmt.close(); PreparedStatement pstmt = connection.prepareStatement("INSERT INTO MyTable(id, text) VALUES (?, ?)"); for (int id = 0; id < Integer.MAX_VALUE; id++) { System.out.println(id); pstmt.setLong(1, id); pstmt.setString(2, "some long text " + id); pstmt.executeUpdate(); } ...
Tabuľka typu CACHED
nie je limitovaná veľkosťou pridelenej
operačnej pamäte, pretože dáta ukladá do súboru a v operačnej pamäti je
len časť dát. Tabuľku typu CACHED
možno vytvoriť príkazom
CREATE CACHED TABLE
. Predvolený typ tabuliek pre celú databázu
je možné zmeniť príkazom
SET DATABASE DEFAULT TABLE TYPE CACHED
.
Tabuľka typu CACHED
nemá zmysel v prípade uloženia dát v
operačnej pamäti. V takom prípade sa príznak CACHED
ignoruje.
Dátové typy
Z dátových typov podporuje HSQLDB:
- číselné dátové typy
TINYINT
,SMALLINT
,INTEGER
,BIGINT
,NUMERIC
aDECIMAL
- logický dátový typ
BOOLEAN
- znakovej reťazcové dátové typy
CHAR
,VARCHAR
aCLOB
- binárne reťazcové typy
BINARY
,VARBINARY
aBLOB
- bitový reťazcové typy
BIT
aBIT VARYING
- dátové typy pre prácu s časom
DATE
,TIME
,TIMESTAMP
aTIMESTAMP WITH TIME ZONE
- a ďalšie
Automatická inkrementácia stĺpce
HSQLDB podporuje automatickú inkrementácia stĺpca. Stĺpec sa vytvorí
pomocou klauzuly GENERATED BY DEFAULT AS IDENTITY
.
Príklad 6: SQL príkaz na vytvorenie tabuľky s primárnym kľúčom s automatickou inkrementácia.
CREATE TABLE MyTable (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
data VARCHAR(2000))
Príklad 7: Vloženie riadku do tabuľky s primárnym kľúčom s automatickou inkrementácia.
Pokiaľ do stĺpca pri INSERTu zadáme NULL alebo alebo hodnotu vynecháme, HSQLDB hodnotu primárneho kľúča vygeneruje automaticky.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydatabase"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MyTable (id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, data VARCHAR(2000))"); stmt.executeUpdate("INSERT INTO MyTable(id, data) VALUES (NULL, 'world')"); stmt.executeUpdate("INSERT INTO MyTable(data) VALUES ('hello')"); ResultSet rs = stmt.executeQuery("SELECT * FROM MyTable"); while (rs.next()) { System.out.println(rs.getObject(1) + " | " + rs.getObject(2)); }
Transakcie
HSQLDB podporuje transakcie. Aby transakcie v JDBC správne fungovali, treba
pomocou metódy Connection.setAutoCommit(boolean)
zakázať auto
commit - automatické potvrdenie transakcie po každej operácii.
Príklad 8: Vloženie riadkov do tabuľky so zapnutými transakciami.
Najprv nastavíme auto commit na false
. Metóda rollback zruší
transakciu, takže nedôjde k vloženiu riadkov do tabuľku. Potvrdením
transakcie metódou commit dôjde k vloženiu riadkov do databázy.
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydatabase"); connection.setAutoCommit(false); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE MyTable (id INTEGER PRIMARY KEY, data VARCHAR(2000))"); stmt.executeUpdate("INSERT INTO MyTable(id, data) VALUES (1, 'world')"); stmt.executeUpdate("INSERT INTO MyTable(id, data) VALUES (2, 'hello')"); connection.rollback(); stmt.executeUpdate("INSERT INTO MyTable(id, data) VALUES (1, 'hello')"); stmt.executeUpdate("INSERT INTO MyTable(id, data) VALUES (2, 'world')"); connection.commit(); ResultSet rs = stmt.executeQuery("SELECT * FROM MyTable"); while (rs.next()) { System.out.println(rs.getObject(1) + " | " + rs.getObject(2)); }
Záver
HSQLDB patrí niekoľko rokov medzi obľúbené SQL databázy vo svete Javy. Vďaka svojej jednoduchosti a nízkym nárokom ju ocenia nielen vývojári. Čitateľom ITnetwork môže táto databáza poslúžiť ako výborná hračka pri štúdiu JDBC.