novinka Javy 5 umožňují k Java kódu přidávat dodatečné informace (podobně jako JavaDoc) za předchůdce anotací je možné považovat XDoclet, který k podobné funkcionalitě používal právě JavaDoc komentáře
Anotace vs XDoclet
anotace jsou silnější anotace mohou být použity při kompilaci, ale mohou být také používány za běhu programu (pomocí reflexe)
Příklad použití anotací
@Greet(text="Hello everyone") public class Main { public static void main(String[] args) { System.out.println(new Main().getClass().getAnnotation(Greet.class).text()); }
}
Anotace z Java API
@Deprecated
kompilátor vypíše varování
@Override
programátor by neměl takto označený element používat
označená metoda má předefinovat metodu předka pokud to nedělá (chyba programátora) kompilace skončí chybou
@SupressWarning
pro daný element se nemá generovat specifický warning
Ukázka
class A { @Override public boolean equals(A a) { ... } @Deprecated public void deprecatedMethod() { ... } }
Kompilátor: „method does not override or implement a method from a supertype“ Kompilátor: „The method deprecatedMethod() from the type A is deprecated.“
ORM
Způsob transformace mezi objektovým a relačním modelem může být definován: 1.Pomocí externího souboru (obvykle ve formátu XML) 2.Pomocí speciálních JavaDoc komentářů (v době, kdy nebyly anotace, viz XDoclet) 3.Pomocí anotací
Hibernate 2.x
používá mapovací XML soubory - lze je generovat automaticky (např. z existující databáze) - může jich být velký počet použití Xdocletu
při buildu vyžaduje jeden krok navíc (spuštění preprocesoru)
Hibernate 3
použití anotací
zápis mapování přímo ve zdrojovém kódu => při refactoringu si aplikace snáze zachová aktuálnost OR mapování jsou součástí byte kódu a čtou se za běhu pomocí reflexe => není potřeba žádný externí XML soubor podpora nástroji např. IntelliJ IDEA, Eclipse (doplňování kódu, označení syntaxe)
získání Hibernate session factory: sessionFactory = new AnnotationConfiguration().buildSessionFactory();
Použití anotací v Hibernate
Deklarace perzistentních tříd v souboru hibernate.cfg.xml: <session-factory> <mapping class="PlaneType"/> <mapping class="ModelPlane"/>
Persistentní třídy
POJO = Plain Old Java Object Třídy s privátními datovými atributy a příslušnými veřejnými get/set metodami Anotace upravují persistentní mapování na tabulky v databázi
Příklad persistentní třídy @Entity public class ModelPlane { private Long id; @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
@Entity – Udává, že třída je persistentní @Id – označuje unikátní atribut
Nepersistentní atributy
Anotace @Transient Udává, že daný atribut se nebude ukládat, ani načítat z databáze Všechny ostatní atributy budou automaticky brány jako persistentní Zjednodušení oproti mapování přes XML
Generování primárních klíčů
@Id @GeneratedValue(strategy=GenerationType.AUTO) public Long getId() { return id; }
Specifikace tabulky a sloupců
Anotace třídy: @Table(name="TABLE") Udává jméno tabulky, do které se entita ukládá a ze které se načítá
Anotace metody: @Column(name="COLUMN")
Přidává se ke get metodě daného atributu
Příklad @Entity @Table(name="T_MODEL_PLANE") public class ModelPlane { private Long id; private String name; @Id @Column(name="PLANE_ID") public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Column(name="PLANE_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } }
Mapování sloupců
Je možné specifikovat v anotacích mnoho vlastností spojených s daným sloupcem v databázi @Column(name="PLANE_ID", length=80, nullable=true) Příklad upřesňuje maximální délku záznamu na 80 znaků a povolenou nullovou hodnotu
Jedna z nejdůležitějších a nejkomplexnějších vlastností persistentního mapování Mapování vztahů mezi tabulkami Anotace tabulkových vztahů se udávají ke get metodám @JoinColumn(name="COLUMN") – název sloupce, přes který se joinují tabulky
Druhy vztahů
@OneToOne @ManyToOne @OneToMany @ManyToMany
Many-to-one aneb n:1
Jeden z nejčastějších vztahů mezi tabulkami je many-to-one @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} ) CascadeType udává chování Hibernate při kaskádových operacích, neboli při mazání záznamů provázaných cizími klíči
Příklad mapování vztahů @Entity() public class Flight implements Serializable { private Company company; @ManyToOne( cascade = CascadeType.PERSIST, CascadeType.MERGE} ) @JoinColumn(name="COMP_ID") public Company getCompany() { return company; } ... }
Named query
Slouží k uložení speciálních dotazů Možno provádět dotazy podle názvu přímo z kódu @NamedQueries @NamedQuery
Příklad named query @NamedQueries( { @NamedQuery( name="planeType.findById", query="select p from PlaneType p left join fetch p.modelPlanes where id=:id" ), @NamedQuery( name="planeType.findAll", query="select p from PlaneType p" ), @NamedQuery( name="planeType.delete", query="delete from PlaneType where id=:id" ) } )
Odkazy
Více informací na: http://www.hibernate.org/hib_docs/annotations/reference/en /html_single/ http://www.onjava.com/pub/a/onjava/2007/02/08/anintroduction-to-hibernate-3-annotations.html