6. diel - Databázový wrapper v Jave - Tvorba triedy Query
V minulom dieli, Programovanie databázového Wrappera v Jave - Príprava, sme začali s tvorbou databázového wrappera, ktorý nám zjednoduší prácu s databázou.
Dnešný tutoriál bude hlavne o programovaní. Ešte než začneme
programovať samotnú triedu Database
, tak si pripravíme triedu
Query
, ktorá bude znázorňovať samotný SQL dotaz.
Trieda Query
V balíčku DB
máme z minulosti pripravené prázdne triedy
Database
a Query
. V triede Query
budeme
teraz pomocou metód postupne zostavovať SQL dotazy. Celá štruktúra nášho
projektu vyzerá takto:
Metódy na vyhľadávanie a mazanie
V triede Query
si vytvoríme metódu delete()
a
metódu where()
, ktorú budeme používať veľmi často:
public class Query { private StringBuilder query; /** * * @param table (Db table) * @return SQL query DELETE */ public Query delete(String table) { query = new StringBuilder(); query.append("DELETE FROM "); query.append(table); return this; } /** * Adds condition for SQL query * @param requirement condition * @return SQL query WHERE */ public Query where(String requirement) { query.append(" WHERE "); query.append(requirement); return this; } /** * * @param table (Db table) * @return SQL query FROM */ public Query from(String table) { query.append(" FROM "); query.append(table); return this; } }
Vďaka triede StringBuilder
môžeme ľahšie poskladať naše
SQL dotazy a uložiť ich do inštančnej premennej query
. Metóda
append()
k nej jednoducho pridá časť textu, znak, alebo
premennú. Premenná môže byť akéhokoľvek dátového typu
(Object
, String
, char
,
boolean
, double
, int
, float
,
atď.).
Inštanciu triedy StringBuilder
môžeme potom premeniť na
textový reťazec pomocou metódy toString()
.
Dôležitá pre nás je metóda where()
, pretože tú využijeme
najčastejšie.
Metódy update()
a
set()
Podobne pridáme aj metódy update()
a set()
:
public class Query { // ... /** * @param table (Db table) * @return SQL query UPDATE */ public Query update(String table) { query = new StringBuilder(); query.append("UPDATE "); query.append(table); query.append(" SET "); return this; } /** * Fills Db columns into the query * * @param columns (array of Db columns) */ public Query set(String[] columns) { int count = columns.length; if (count == 0) { throw new IllegalArgumentException("Invalid argument count"); } for (String column : columns) { query.append(column); query.append(" = "); query.append("?"); query.append(","); } query.deleteCharAt(query.lastIndexOf(",")); return this; } }
Tak a teraz si povieme prečo máme na konci každej metódy
return this;
Je to jednoduché. Každá metóda v triede
Query
je dátového typu Query
. To znamená, že
vracia inštanciu danej triedy. Má to tú výhodu, že
môžeme zefektívniť kód. A namiesto tohto kódu:
query.update(table); query.set(columns); query.where(requirement);
Môžeme efektívne napísať toto:
query.update(table).set(columns).where(requirement);
Takému zápisu sa hovorí plynulé rozhranie (Fluent Interface). Pomáha nám to vytvárať aplikačné rozhranie, ktoré je veľmi čitateľné a pochopiteľné. Plynulé rozhranie vytvoril Martin Fowler a je to technika objektovo orientovaného programovania, kde ako sme si už vyššie ukázali, reťazíme po sebe idúce volania metód toho istého objektu.
Ďalej stojí za povšimnutie, že v metóde set()
testujeme,
či neposielame prázdny parameter. V prípade, že pošleme neplatný
parameter, tak sa vyvolá výnimka IllegalArgumentException
.
Nakoniec len spomeniem, že metóda deleteCharAt()
nám odoberie
poslednú nežiaducu čiarku, ale vnútornú logiku metód si aj s príkladmi
preberieme v inej časti tohto tutoriálu.
Metódy insert()
a
values()
Pridajme metódy insert()
a values()
:
public class Query { // ... /** * @param table (Db table) * @return SQL query INSERT */ public Query insert(String table) { query = new StringBuilder(); query.append("INSERT INTO "); query.append(table); return this; } /** * @param params (array of VALUES) * @return VALUES for INSERT */ public Query values(Object[] params) { query.append(" VALUES("); int count = params.length; if (count == 0) { throw new IllegalArgumentException("Invalid parametr count"); } for (int i = 0; i < count; i++) { query.append("?,"); } query.deleteCharAt(query.lastIndexOf(",")); query.append(");"); return this; } }
V metóde insert()
nie je nič nové. Metóda
values()
berie ako parameter pole objektov a za každý prvok
dosadí do SQL dotazu ?
. Nakoniec sa odstráni posledná čiarka a
vráti inštancia triedy Query
. Ak bude počet parametrov rovný
nule, vyvolá sa výnimka IllegalArgumentException
.
Metóda select()
Do triedy doplníme aj metódu select()
s týmto kódom:
public class Query { // ... /** * @param columns (array of Db columns) * @return SQL query SELECT */ public Query select(Object[] columns) { query = new StringBuilder(); query.append("SELECT "); if (columns != null) { for (Object column : columns) { query.append(column); query.append(","); } query.deleteCharAt(query.lastIndexOf(",")); } else { query.append("*"); } return this; } }
Metóda select()
berie ako parameter pole objektov, ktoré
reprezentujú jednotlivé stĺpce. Ak dáme metóde select()
ako
parameter hodnotu null
, dosadí do SQL dotazu znak *
,
ktorý vracia všetky stĺpce z databázovej tabuľky.
Metóda getQuery()
Nakoniec doplníme metódu, ktorá nám vráti daný SQL dotaz:
public class Query { // ... /** * * @return complete sql query */ public String getQuery() { return query.toString(); } }
V metóde getQuery()
sme zavolali metódu
toString()
na inštanciu query
a vrátili predtým
zostavenú dotaz ako textový reťazec. Pokračovať budeme nabudúce
V ďalšom dieli, Programovanie databázového Wrappera v Jave - Trieda Database, si triedu Query
otestujeme a
vytvoríme si triedu Database
.