Prosinec 13th, 2007DAO pattern + generika pro EJB3
Když jsem se dostal do fáze většího poznávání J2EE, došlo mi, že
vrstvení logiky je nedílnou součástí úspěchu při návrhu.
Jistě by nebylo moudré nechat „dolování dat“ rozházené po aplikační
logice tak, jak ho zrovna potřebuji. Zde nastupuje DAO (Data Access Object),
což je návrhový vzor sloužící ke komunikaci mezi persistentní vrstvou a
zbytkem světa.
Asi nejvíce mě zaujala možnost, kde DAO vrstvu definuji pomocí generiky a abstraktní třídy. Více než tisíc slov je lepší přímá ukázka kódu.
První věcí je interface, který obsahuje všechny důležité metody, které je třeba pro DAO jednotlivých entit třeba vystavit:public T find(ID id);
public List<t> findAll();
public T create(T entity);
public T save(T entity);
public void remove(T entity);
}
public interface ZamestnanecDAOLocal extends GenericDAO<zamestnanec, String> {
}
public class ZamestnanecDAOBean implements ZamestnanecDAOLocal {
@PersistenceContext(unitName = „myDB“)
private EntityManager em;
//… implementace metod
}
Velkou nevýhodou je ovšem fakt, že pokaždé musím implementovat metody, které jsou potřeba ke splnění požadavku z GenericDAO.
Zde nastupuje abstraktní třída, která za nás vyřeší onu potřebnou implementaci.private Class<t> entityBeanType;
private EntityManager em;
public AbstractDAO() {
// vytvari, ziskava typ entity pro dane DAO
this.entityBeanType = (Class<t>) ((ParameterizedType)
getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
public Class<t> getEntityBeanType() {
return entityBeanType;
}
@PersistenceContext(unitName = „default“)
public void setEntityManager(EntityManager em) {
this.em = em;
}
protected EntityManager getEntityManager() {
if (em == null) {
throw new IllegalStateException(„…“);
}
return em;
}
public T find(ID id) {
T entity;
entity = getEntityManager().find(getEntityBeanType(), id);
return entity;
}
// … implementace zbylych metod
}
public class ZamestnanecDAOBean extends AbstractDAO<zamestnanec, String> implements ZamestnanecDAOLocal {
}
Takto definovaná beana je schopna podědit abstraktní třídu a například anotovaný setter pro entitymanager převzít na svá bedra. Podle specifikace je totiž možné EJB beany nechat dědit mezi sebou, s vyjímkou, že dependency injections a další služby jsou poté managovány potomkem, v našem případě „ZamestnanecDAOBean“.
Aby samotné DAO nebylo tak chudé, přidal jsem si několik dalších možností. Některé jsou již specifikovány na danou implementace ORM frameworku. Osobně jsem díky tomu přešel na Hibernate Session a Criteria API. Tady jsou některé další metody:/
* <p>Vraci vsechny zaznamy z dane tabulky, ktera prislusi entite.
* Navic umoznuje definovat razeni podle <i>Hibernate Criteria API: Order</i></p>
* <p>Zpusob pouziti: {@code findAll(Order.asc(„jmeno“), Order.desc(„prijmeni“))}</p>
@param orderBy definice razeni zaznamu
* @return vsechny zaznamy, pokud zadne neexistuji, vraci null
/
public List<t> findAll(Order… orderBy);
/
<p>Vraci vsechny zaznamy z dane tabulky, ktera prislusi entite.
* Navic umoznuje definovat omezeny vyber dat, pouzivane napr. pro strankovani.</p>
* <p>Zpusob pouziti: {@code findAll(0, 20); } Prvni radek je roven 0</p>
@param first prvni radek, od ktereho se vybiraji zaznamy
* @param offset maximalni pocet vybiranych zaznamu
* @return vsechny zaznamy dle definovanych omezenich
/
public List<t> findAll(int first, int offset);
/
<p>Vraci vsechny zaznamy z dane tabulky, ktera prislusi entite.
* Navic umoznuje definovat omezeny vyber dat, pouzivane napr. pro strankovani
* a definovat razeni podle <i>Hibernate Criteria API: Order</i></p>
* <p>Zpusob pouziti: {@code findAll(0, 20, Order.asc(„jmeno“)); } Prvni radek je roven 0</p>
@param first prvni radek, od ktereho se vybiraji zaznamy
* @param offset maximalni pocet vybiranych zaznamu
* @param orderBy definice razeni zaznamu
@return vsechny zaznamy dle definovanych omezenich
/
public List<t> findAll(int first, int offset, Order… orderBy);
/
<p>Dohledava zaznamy na zaklade Hibernate Example.</p>
* <p>Spousti: {@code findByExample(exampleInstance, false, false, false, excludeProperty)}</p>
* <p> Zpusob pouziti: <a href=„http://www.hibernate.org/hib_docs/reference/en/html/querycriteria.html“>15.6. Example queries</a>
@param exampleInstance s naplnenymi vlastnostmi pro vyber
* @param excludeProperty pradavajici vlastnosti pro vyber pres example
* @return dohledane zaznamy
/
public List<t> findByExample(T exampleInstance, String… excludeProperty);
/**
<p>Ziskava pocet vsech radku z tabulky prislusici dane entite</p>
@return pocet vsech radku
*/
public int countAll();
Prosinec 13th, 2007 at 17.07
Drive jsem neco podobneho pouzival pro vsechny DAO objekty, ale to vede k castemu poruseni DRY (don`t repeat yourself). Pokud ma entita mit pouze CRUD operace, tak je lepsi udelat tovranu, ktera pro danou entitu vrati zakladni DAO pouze s CRUD operacemi. Neco podobneho ma myslim JBoss Seam a rikaji tomu EntityHome.
GenericDao dao = GenericDaoFactory.get(MyEntity.class);
MyEntity entity = dao.find(id);
Prosinec 14th, 2007 at 10.51
Asi to z toho kontextu uplne nevypadlo, ale dalsim krokem jsou implementace specialnich metod vztahujici se k dane entite. Pr:
public interface ZamestnanecDAOLocal extends GenericDAO<Zamestnanec, String> {
public List<Zamestnanec> findByTyp(int typ);
public List<Zamestnanec> findByStredisko(String cisloStrediska);
…
}
V kazdem pripade pro ciste CRUD operace souhlasim s tim DAO Factory.
Jinak Seam skutecne neco takoveho ma, zajimave je, ze se jedna v podstate jen o nadefinovani metadat k dane entite a Seam sam vygeneruje CRUD aplikaci. Existuje i moznost s Hibernate Search.
Me osobne to ovsem prislo prilis velke vazani se na Seam. Mam navic jeste vzdaleneho klienta na stejnou business logiku, cimz je pro me vrstveni docela dulezite.
Leden 5th, 2008 at 0.39
zde je DAO vrstva tvorena EJB? zajimave, ja vzdy pouzival POJO a AbstractFactory pattern
Leden 5th, 2008 at 12.30
to kooudy: Presnejsi popis tohoto vzoru muzes naleznout na strankach hibernate.
http://www.hibernate.org/328.html
Pro pouziti na EJB, pod nazvem: „Writing DAOs as managed EJB 3.0 components“
Září 8th, 2010 at 20.01
< blockquote >< a href=„http://cheaptabletsonline.com/“>CheapTabletsOnline.Com. Canadian Health&Care.Best quality drugs.Special Internet Prices.No prescription online pharmacy. High quality drugs. Order drugs online< /a >…
Buy:Acomplia.SleepWell.Lipothin.Wellbutrin SR.Zocor.Aricept.Cozaar.Prozac.Ventolin.Advair.Benicar.Lasix.Nymphomax.Female Pink Viagra.Zetia.Female Cialis.Seroquel.Amoxicillin.Lipitor.Buspar…