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.