Přeskočit na hlavní obsah

Anotace nahrazující SQL a OQL dotazy (důvody)

V minulém příspěvku jsem psal o tom, jakým způsobem nadefinovat základní DAO vrstvu. Zvolil jsem způsob, který se stal zavislý na Hibernate Session. Tento "vendor" nabízí i jednu z věcí, kterou jsem si pomalu oblíbil, a tím jsou Criteria API.

Psaní základních SQL dotazů jsem nahrazil OQL dotazy. OQL je v podstatě velice podobný SQL s tím rozdílem, že daný dotaz se provádí nad entitami reprezentující data v DB. Díky tomu odpadá nutnost psát ruzné JOIN konstrukce, specifikovat vrácené sloupce a hlavně získávám nezávislost na použitém databázovém systému. Převod z MySQL na Oracle či MSSQL je triviální záležitost spočívající v přepsání pár řádku v persistence.xml či v přepsání JDBC zdroje v aplikačním serveru.

Ale zpět. I když je OQL velice elegantní způsob psaní, stále obsahuje velké omezení, které spočívá v tvorbě dynamických dotazů. Pokud aplikace přistupuje k datům tak, že je získává na základě uživatelského filtru, musím dotaz poskládat z daného Stringu, což je dost otravující záležitost.
K tomuto účelu se velice hodí Criteria API. Nebudu zde popisovat funkci Criteria API, k tomuto účelu slouží referenční příručka. U Criteria API se mi velice zalíbila možnost filtrovat data přes danou entitu. K tomuto účelu zde existuje objekt "Example". Při použití tohoto přístupu mohu velice snadno získat data filtrovaná podle daných sloupců (atributů) v tabulce (entitě).

Jenže....

Pokud si například řeknu: "Chci vybrat všechny záznamy s podmínkou WHERE datum BETWEEN od AND do", dostanu se opět do slepé uličky a musím přistoupit zpět k čistému Criteria API nebo dokonce k OQL.

Toto byl první důvod, proč jsem přistoupil k implementaci vlastního způsobu, který je řízen pomocí anotací. Ještě než přejdu k samotnému způsobu, musím zmínit druhou pozitivní věc.

Pokud začnu tvořit DAO vrstvu, začne se mi každý DAO objekt hemžit metodami jako: findByDatumPrijeti, findByXXX.... Jistě není nic špatného na implementaci daných metod, až na to, že metody obsahují parametry, které již jasně říkají, jaká data mají být výsledkem (návratovou hodnotou).
Uvedu malý příklad (pro pozdější srovnání):

public List findForExample(String zakaznik, Date datumOd, Date datumDo) {

// implementace Criteria API, OQL ci suroveho SQL

}


Jak je z ukázky patrné, metoda vybíra zakázky, které spadají jistému zákazníkovi a jejich datum je v rozmezi datumOd-datumDo.

K odstranění psaní samotných dotazů použiji následující kroky:

  • vytvořím objekt pro filtraci

  • daný objekt anotuji příslušnými "metadaty"

  • zruším metodu findForExample a v DAO vytvořím obecnou metodu: findByCriteria(Object filtr)



Jediné, co mi zůstane je objekt pro filtrování. Sám se svými metadaty je schopen řici, co vlastně chci. Následující ukázka je ekvivalentní předchozímu způsobu:

@Criteria(entity = Zakazky.class)
public class ZakazkyForExampleFiltr {

@Criterion(property="zakaznik.id")
private String zakaznik;

@Criterion(property = "datumPrijeti")
@Between(idf = "dp", property = BetweenDAO.MIN)
private Date datumPrijetiOd;


@Criterion(property = "datumPrijeti")
@Between(idf = "dp", property = BetweenDAO.MAX)
private Date datumPrijetiDo;

// settry, gettry
}

// pouziti
ZakazkyForExampleFiltr filtr = new ZakazkyForExampleFiltr();
// naplneni filtru
List result = dao.findByCriteria(filtr);


Pro lidi nesnášející anotace, bude tento způsob jistě nepoužitelný, pro lidi snažící se o co největší usnadnění a zpřehlednění své práce, naopak přínosem. Věřím, že každý si již ten svůj zpusob nalezl a nehodlá ho měnit, na druhou stranu při pohledu na takovýto kod si pokládám jednu otázku: "Není přece jen efektivnější popsat kod metadaty a nechat zbytek na daném frameworku?".

Jelikož se mi článek rozrostl, rozhodl jsem se ho rozdělit do dvou částí. V první části jsem popsal důvody a uvedl malou ukázku. V druhé části uvedu možnosti a nabídnu danou funkčnost ke stažení. Tedy ten základní "motor", který lze jednoduše "přilepit" do své DAO vrstvy. Navíc uvedu další plány a položím otázky, na které si zatím nedokážu odpovědět.

Komentáře

  1. František Jandoš3. ledna 2008 22:15

    Criteria API je pěkné, je třeba však mít napaměti, že je určeno výhradně pro dynamické dotazy, tedy ty, kde bychom normalně lepily při každém volání jiné SQL. Tato věc má tu nevýhodu, že databáze si pak nedrží zkompilované query a musí je kompilovat pokaždé znovu, což ji nemusí udělat uplně dobře. Proto bych jen doplnil pro ORM nováčky, že HQL ci OQL by se stejně měli naučit ;-)

    OdpovědětVymazat
  2. Urcite souhlas. Na jednoduche dotazy je vzdy lepsi pouzit OQL.
    Asi nejefektivnejsi je u JPA "NamedQuery", coz je dotaz, ktery se anotuje k dane entite. EntityManager pri svem "nacteni" udela prepared statement techto dotazu. Volani takoveho dotazu je jeste rychlejsi.

    OdpovědětVymazat
  3. František Jandoš6. ledna 2008 1:35

    Tak mi to nedalo a provedl jsem test. U Hibernate jsou jak na HQL, Criteria a Named Query (HQL) použity PreparedStatementy, tedy databáze si zkompilované query může držet (pokud se samozřejmě nemění kriteria (ne parametry)). Čímž si sypu popel na hlavu, že jsem v předchozím komentaři neměl pravdu :-/ Rychlosti HQL a Criteria byly srovnatelné na triviálním dotazu přes jednu entitu. Named Query byly nejrychlejší, jak píšeš, ale kvůli tomu, že si Hibernate pamatuje zkompilované HQL.

    OdpovědětVymazat
  4. Statementy si nemusi drzet jen databaze, ale treba i connection pool. Viz. napr. hojne pouzivany c3p0 pool,

    Slava

    OdpovědětVymazat

Okomentovat

Populární příspěvky z tohoto blogu

Jak si v IT vydělat hodně peněz?

Na začátek by bylo dobré, abych objasnil samotný titulek, který může na někoho působit jako červený hadr. Článek nebude o obecných pravidlech, ale bude vyprávět můj vlastní příběh, na kterém vám zkusím ukázat, jak se dá docílit úspěchu, či alespoň správně nastartovat svojí vlastní kariéru v IT.

I když se z názvu článku dá dedukovat, že se vše bude točit kolem peněz, není tomu tak. Alespoň ze dvou třetin určitě ne. Ale to už předbíhám, pojďme to raději vzít hezky popořadě...

Kdybychom měli mluvit o roce 2017 jako o přelomové době, nejspíše to nebude pravda. I když pro někoho to může být rok plný úspěchů a štěstí v podobě narození zdravých dětí, svatby či první velké lásky, tak z pohledu lidstva se jedná o rok, který jen kopíruje předešlé a v oblasti technologií nás posouvá stejným tempem jako rok předtím.

Jsem naprosto přesvědčen o tom, že i když se současná doba tak nenazývá, tak prožíváme dobu, která jednou bude označena za revoluční, a to zejména díky vynálezu internetu, který je st…

Jak by se firmy neměly chovat k programátorům?

Každý, kdo pracuje v IT oboru, se jistě již setkal s různými „geniálními nápady“, od kterých si firma slibovala zlepšení produktivity či snížení nákladů. Ať už je to zavedení agilních principů, striktní kontrola práce či zavedení nové a skvělé metodiky, o které si „šéf“ přečetl včera na internetu. Jsou z toho skutečně tak nadšení i samotní vývojáři? A bude nový nápad fungovat?
K napsání tohoto článku mě navedly různé programátorské diskuze, kde si lidé stěžovali na firmu, kde pracují. Příklady, které zde uvedu, jsou z reálné praxe. Ať už jsem je zažil jako řadový programátor, či jako šéf týmu.
I když je poptávka po programátorech tak vysoká, že Vás headhunteři nahánějí i ve chvílích, kdy o to opravdu nestojíte, tak i přes to je mnoho lidí, kteří se bojí opustit svoje současné zaměstnání.
Čeho se nejčastěji bojíme? Je to samozřejmě nejistota, kterou si často omlouváme větami jako: „Tady mám své pohodlí, co když to jinde mít nebudu?“ nebo „I když mě to v práci štve a nebaví, tak mě ale…

Jak jsem technologicky postavil startup

Tento příběh pojednává o technologiích, nástrojích a vůbec o všem, co jsem potřeboval k tomu, abych byl schopen, postavit startup na zelené louce.

Každý správný příběh začíná stejně: "Jednou jsem...."

Kapitola první: Nápad
Jednou jsem se setkal s člověkem, který měl nápad na produkt, který se v průmyslu zatím nevyskytuje. I přes prvotní skepsi, kdy jsem si říkal: "Tohle už přeci dávno v průmyslu existuje, ne?", jsem došel ke zjištění, že nikoli.

Tím jsem se dostal ke svému prvnímu poučení. Průmysl je technologicky dost zabržděný. Osobně se domnívám, že těch důvodů, proč tomu tak je, je několik. Za prvé je to fakt, že většina lidí, kteří se pohybují v tomto odvětví jsou často konzervativní a za správné považují pouze léty osvědčené věci. Druhým důvodem je to, že jakákoli změna znamená riziko. Ať už z pohledu finanční ztráty tak i z pohledu stability výroby. No a třetím a nejzásadnějším důvodem je to, že ač zde máme spousty technologických vymožeností, narážíme na to,…