Náš model aplikace je již dost rozsáhlý na to,
abychom nad jeho třídami mohli začít provádět
dotazování. Dnes si tedy ukážeme, jaké nám Caché
nabízí možnosti práce s dotazy na data, vracející
sady záznamů.
Jedním z častých dotazů v účetních aplikacích je
přehled zůstatků na účtech syntetické evidence, nebo
přehled pohybů na účtech – deník. Ukážeme si též, jak
lze v Caché tvořit uložené procedury a jak s nimi z
Javy pracovat (i když je to z pohledu objektového
programování samozřejmě krok zpátky, protože s Caché
umí Java spolupracovat objektově, ale někdy se
relační způsob může hodit.)
Samozřejmě, že dotazovat se na data v Caché můžeme
pomocí SQL i dynamicky, ale v takovém případě musí
server, pokud nemá již vygenerovaný runtime kód
našeho SQL dotazu nakešován, nejdříve příslušný kód
sestavit, což jej může zdržovat. Proto je vhodné,
alespoň u často používaných dotazů, tyto nadefinovat
jako součást definice třídy, a tedy se stanou částí
API aplikace.
Ukážeme si, jak sestavit sadu záznamů se zůstatky
na účtech syntetické evidence.
V Caché Studiu otevřeme třídu ucto.demo.Syntetika k editování. Pomocí
průvodce přidáním dotazu (menu Class -> Add ->
New Query) nadefinujeme seznam vstupních parametrů
dotazu (v našem případě žádné nebudou) a poté
vybereme, zda náš dotaz bude tvořen SQL příkazem nebo
kódem v některém ze skriptovacích jazyků Caché;
zvolíme SQL, sestavu nazveme OsnovaReport.
Definice dotazu bude vypadat takto:
Query OsnovaReport() As %SQLQuery(CONTAINID = 1)
{
SELECT %ID,cisloUctu,nazev,typ,aktualniZustatek as zustatek FROM ucto_demo.Syntetika
ORDER BY cisloUctu
}
Vidíte, že je to klasický SQL dotaz. Jediné co Vás
může zarazit, je parameter CONTAINID=1, ten říká, že
dotaz vrací identifikátor objektu (jako %ID) a pro
náš příklad není důležitý. Tento parametr je používán
jinými technologiemi. ID se však hodí pro následné
otevírání instancí objektů.
Po zkompilování třídy a vytvoření aktualizované
verze Java proxy třídy se dotaz stane součástí Java
projekce. Caché dotazy jsou vystaveny jako statické
metody vracející třídu CacheQuery
.
Následující řádky ukazují jednoduchý kód volající
výše definovaný dotaz:
String url="jdbc:Cache://localhost:56773/" + namespace;
dbconnection = CacheDatabase.getDatabase (url, username, password);
System.out.println( "Spojeno." );
CacheQuery qry = Syntetika.query_OsnovaReport(dbconnection);
rs = qry.execute();
// hlavicka
String h = "";
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
if (i>1) h += ": ";
h += rs.getMetaData().getColumnName(i);
}
System.out.println(h);
while (rs.next()) {
/* vypiseme vsechny sloupce kazdeho nalezeneho radku */
String s = "";
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
if (s.length() > 0) {
s += ": ";
}
s += rs.getString( i );
}
System.out.println( s );
}
/* Close the ResultSet object */
rs.close();
V předminulém díle našeho seriálu jsme používali
metodu _open
k otevírání instancí
Caché tříd. Tato metoda ovšem předpokládá, že známe
identifkátor instance. My jsme před chvíli viděli,
jak si identifikátory instancí objektů vrátit; pomocí
dotazu. Ovšem existuje i pohodlnější způsob než
samostatné volání dotazu a následné použití vráceného
ID pro použití v metodě _open
, a to
metoda OpenByQuery
, která kombinuje
oba kroky – nalezení ID a otevření objektu.
Ukázka otevření instance syntetického účtu s číslem
221:
Iterator it = Syntetika.openByQuery(dbconnection,"cisloUctu = ?",
new String[] {"221"});
// vime (cisloUctu je unikatni), ze pokud najdeme nejaka data, tak nanejvys jeden zaznam
if (it.hasNext()) {
Syntetika syn = (Syntetika)it.next();
System.out.println(syn.getcisloUctu() + " : " + syn.getnazev() + " : zustatek: " + syn.getaktualniZustatek());
}
Možná si ještě vybavíte, ze na počátku tohoto
seriálu, v jednom z dílů věnovaných technologii
Jalapeno, jsme tuto metodu používali také.
V tomto případě se sice SQL dotaz generuje
dynamicky, ale jelikož se jedná o prostý select z
jedné tabulky, režie na jeho sestavení je minimální.
Když už jsme u dotazování: vzhledem k tomu, že
Caché plně podporuje SQL, je možno použít standardní
SQL dotazy prostřednictvím JDBC rozhraní. Na tom není
nic objevného, takže si to ukazovat nebudeme. Ale
ukážeme si, jak lze v Caché označit metodu nebo dotaz
jako uloženou proceduru SQL pro volání (nejen) z Javy
nikoliv prostřednictvím objektové vazby, ale
prostřednictvím JDBC.
Udělat z vloženého dotazu nebo statické metody
třídy Caché uloženou proceduru, je velice jednoduché.
Stačí přidat k deklaraci metody či dotazu klíčové
slovo SQLProc a případně volitelný název uložené
procedury. (Stále pracujeme s definicí Caché třídy
ucto.demo.Syntetika
)
Query Osnova() As %SQLQuery(CONTAINID = 1) [ SqlName = spOsnova, SqlProc ]
{
SELECT %ID,cisloUctu,nazev,typ,{FN CONCAT(aktualniZustatek,' Kč')} as zustatek FROM ucto_demo.Syntetika
ORDER BY cisloUctu
}
Uloženou proceduru pak spustíme jednoduše:
String url="jdbc:Cache://localhost:56773/" + namespace;
Class.forName ("com.intersys.jdbc.CacheDriver");
dbconnection = DriverManager.getConnection(url,username,password);
CallableStatement cs = dbconnection.prepareCall("{call ucto_demo.spOsnova()}");
ResultSet rs = cs.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
Příště se pustíme do projekcí Caché tříd do
Enterprise Java Beans.