Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Identity Field Radim Veselý ČVUT v Praze 28. 4. 2013Radim Veselý ČVUT v Praze 28. 4. 2013 Michal Kouřík ČVUT v Praze 13.4.2014.

Podobné prezentace


Prezentace na téma: "Identity Field Radim Veselý ČVUT v Praze 28. 4. 2013Radim Veselý ČVUT v Praze 28. 4. 2013 Michal Kouřík ČVUT v Praze 13.4.2014."— Transkript prezentace:

1 Identity Field Radim Veselý ČVUT v Praze Radim Veselý ČVUT v Praze Michal Kouřík ČVUT v Praze

2 Identity Field– úvod Návrhový vzor patřící do skupiny ORM design patterns Problém  Zapsání dat do databáze – potřebujeme jasně namapovat řádek v databázi na objekt v paměti Jak na to?  Vybrat vhodný klíč a uložit ho jako atribut třídy

3 Výběr klíče Meaningful / meaningless key Simple / compound key Table-unique / database-unique key  Vždy pouze jedno ID pro danou hierarchii tříd (Concrete Table Inheritance) Typ klíče  Simple – stejný typ jako je v databázi  Compound – řešit přes samostatný objekt

4 Implementace – simple key class DomainObject { private long PLACEGOLDER_ID = -1; private long id = PLACEHOLDER_ID; public Boolean isNew() { return id == PLACEHOLDER_ID; }

5 Implementace – compound key class DomainObject { private Key key; protected DomainObject(Key ID) { this.key = ID; } public Key getKey() { return this.key; } public void setKey(Key key) { this.key = key; } class Key { private Object[] fields; public Key(Object[] fields) { this.fields = fields; }

6 Získání hodnoty klíče Předat zodpovědnost databázi  Nejjednodušší, nic neřeším, databáze ID vygeneruje při insertu  Problém – každý databázový stroj může mít implementováno jinak – problém s ORM Auto-generated field  Nejběžnější Sekvence  Nemusí být dostupná na všech DB strojích GUID  Používat s rozvahou – příliš velký, špatně se s ním pracuje  {25892e17-80f6-415f-9c f0223}

7 Implementace – key table Tabulka obsahující další ID v řadě pro každou tabulku CREATE TABLE keys (name varchar primary key, nextID int); INSERT INTO keys VALUES (‘orders’, 1); CREATE TABLE keys (name varchar primary key, nextID int) INSERT INTO keys VALUES ('orders', 1)

8 Příklad z praxe - public abstract class DomainObject implements Serializable { private static final long serialVersionUID = GenerationType.AUTO, generator = = true, nullable = false) private Long id; // getters & setters & hashcode & equals metody }

9 Shrnutí Základní stavební kámen pro veškeré aplikace ukládající do DB Jakou implementaci?  Ve valné většině si vystačíme s jednoduchým klíčem typu long Související vzory  Identity Map  Domain Model  Row Data Gateway

10 Dependent mapping

11 Dependent mapping – úvod Problém  práce s databází spíš než objektový vzor  ukládání kolekcí do databáze  entity kolekce jsou jednoduché z hlediska vztahů (váží se pouze k jedinému objektu)  snažíme se o minimalistické řešení Příklad:  ukládání písniček k albu  vybavení auta (rezerva, žárovky...) Jak na to?  entity kolekce nemají vlastní ID  nemají smysl samy o sobě  při práci s entitami přistupujeme přes vlastníka kolekce

12 Dependent mapping – struktura - příklad Závislý objekt Databáze Vlastník Mapovací třída

13 Dependent mapping – účastníci Vlastník (owner)  třída obsahující kolekci  entity mají ID Závislý (dependent)  třída tvořící entity kolekce  entity nemají ID  přistupuji k nim přes vlastníka  můžou být imutabilní Mapovací třáda (mapper)  obstarává komunikaci s db a spravuje kolekci

14 Dependent mapping – implementace Nahrávání kolekce  většinou probíhá zároveň s vlastníkem  při vyšší ceně nahrávání lazy load ID  entity kolekce neosahují ID, musíme s tím počítat Hierarchie Key  u závislé classy se používá composite Update  vzhledem k tomu, že nemáme ID, tak updatujeme přes delete & insert  při změně entity kolekce měníme vlastníka

15 Dependent mapping – implementace – model, find class Track { private final String title; public Track(String title) { this.title = title; } public String getTitle() { return title; } class Album { private List tracks = new ArrayList(); public void addTrack(Track arg) { tracks.add(arg); } public void removeTrack(Track arg) { tracks.remove(arg); }; public void removeTrack(int i) { tracks.remove(i); } public Track[] getTracks() { return (Track[]) tracks.toArray(new Track[tracks.size()]); } class AlbumMapper { protected String findStatement() { return "SELECT ID, a.title, t.title as trackTitle" + " FROM albums a, tracks t" + " WHERE a.ID = ? AND t.albumID = a.ID" + " ORDER BY t.seq"; }

16 Dependent mapping – implementace - load class AlbumMapper { protected DomainObject doLoad(Long id, ResultSet rs) throws SQLException { String title = rs.getString(2); Album result = new Album(id, title); loadTracks(result, rs); return result; } public void loadTracks(Album arg, ResultSet rs) throws SQLException { arg.addTrack(newTrack(rs)); while (rs.next()) { arg.addTrack(newTrack(rs)); } private Track newTrack(ResultSet rs) throws SQLException { String title = rs.getString(3); Track newTrack = new Track (title); return newTrack; }

17 Dependent mapping – implementace - update public void update(DomainObject arg) { PreparedStatement updateStatement = null; try { updateStatement = DB.prepare("UPDATE albums SET title = ? WHERE id = ?"); updateStatement.setLong(2, arg.getID().longValue()); Album album = (Album) arg; updateStatement.setString(1, album.getTitle()); updateStatement.execute(); updateTracks(album); } catch (SQLException e) { throw new ApplicationException(e); } finally {DB.cleanUp(updateStatement); } public void updateTracks(Album arg) throws SQLException { PreparedStatement deleteTracksStatement = null; try { deleteTracksStatement = DB.prepare("DELETE from tracks WHERE albumID = ?"); deleteTracksStatement.setLong(1, arg.getID().longValue()); deleteTracksStatement.execute(); for (int i = 0; i < arg.getTracks().length; i++) { Track track = arg.getTracks()[i]; insertTrack(track, i + 1, arg); } } finally {DB.cleanUp(deleteTracksStatement); }

18 Dependent mapping – implementace - update public void insertTrack(Track track, int seq, Album album) throws SQLException { PreparedStatement insertTracksStatement = null; try { insertTracksStatement = DB.prepare("INSERT INTO tracks (seq, albumID, title) VALUES (?, ?, ?)"); insertTracksStatement.setInt(1, seq); insertTracksStatement.setLong(2, album.getID().longValue()); insertTracksStatement.setString(3, track.getTitle()); insertTracksStatement.execute(); } finally {DB.cleanUp(insertTracksStatement); }

19 Dependent mapping – shrnutí Plusy  zjednodušení entit  pracujeme na „vyšší vrstvě“ Mínusy  práce s tvorbou mapping class  nepříjemnosti spojené s absencí ID  omezení (pouze jeden vlastník, žádné jiné reference)

20 Dependent mapping – související vzory Identity Field  entity obsahují ID Active record, Row Date Gateway  mapování je prováděno pomocí vlastníka Value Object  entity také nemají ID, porovnáváme podle obsahu  neřeší chování vůči db Unit Of Work  pro úpravu objektů používám pouze metody, které zaštiťují skupinu procesů  neřeší vztahy mezi objekty z pohledu db


Stáhnout ppt "Identity Field Radim Veselý ČVUT v Praze 28. 4. 2013Radim Veselý ČVUT v Praze 28. 4. 2013 Michal Kouřík ČVUT v Praze 13.4.2014."

Podobné prezentace


Reklamy Google