Hibernate
Hibernate je framework napsaný v jazyce Java, který umožňuje tzv. objektově relační mapování (ORM). Usnadňuje řešení otázky zachování dat objektů i po ukončení běhu aplikace. Je jednou z implementací Java Persistence API (JPA).
Vývojář | Red Hat |
---|---|
Aktuální verze | 5.6.5 (26. ledna 2022) |
Operační systém | multiplatformní |
Platforma | Java Virtual Machine |
Vyvíjeno v | Java |
Typ softwaru | objektově relační mapování |
Licence | GNU Lesser General Public License |
Web | www.hibernate.org |
Některá data mohou pocházet z datové položky. |
Historie
Projekt vytvořil Gavin King, který později spolu s Hibernate přešel pod křídla firmy JBoss. Ta byla v roce 2006 převzata firmou Red Hat, která nadále pokračuje ve vývoji frameworku Hibernate. Gavin King spolu s JBoss také přešel do RedHatu.
Co dělá Hibernate
Hibernate poskytuje způsob, pomocí něhož je možné zachovat stav objektů mezi dvěma spuštěnými aplikacemi. Říkáme tedy, že udržuje data persistentní. Dosahuje toho pomocí ORM, což znamená, že mapuje Javovské objekty na entity v relační databázi. K tomu používá tzv. mapovací soubory, ve kterých je popsáno, jakým způsobem se mají data z objektu transformovat do databáze a naopak a jakým způsobem se z databázových tabulek mají vytvořit objekty. Druhý způsob jak mapovat objekty je použít anotace místo mapovacích souborů. V Hibernate se tedy pracuje s běžnými business objekty, přičemž mohou být sloupce tabulky spojeny přímo s atributy objektu, nebo mohou být připojeny skrze metody get/set a metody hashCode() a equals(). Nutno podotknout, že nelze použít EJB (viz Java Bean), ale pouze klasické objekty – tzv. POJO (Plain Old Java Object). Poté, co jsou objekty uložené v databázi se na ně lze dotazovat jazykem HQL (Hibernate Query Language), který je odvozen z SQL a je mu tedy velice podobný.
Mapování
a) mapovací soubory
Jedná se soubory ve formátu XML s příponou „.hbm.xml“ (tedy např. Zajezd.hbm.xml), kdy pro jednu třídu máme jeden soubor, obvykle umístěný ve stejném balíčku jako samotná třída. Ve struktuře mapovacího souboru se používají např. tagy <property> nebo <set>. Prvním se popisuje normální datový atribut třídy. Tagem <set> se také popisuje atribut, ale tentokrát má speciální význam, protože udržuje odkazy na související objekty. (Např. objekt „Zajezd“ by měl atribut typu Set jménem „cestujici“, který by obsahoval odkazy na objekty jednotlivých cestujících)
<hibernate-mapping package="model">
<class name="Zajezd" table="ZAJEZD">
<id name="id" column="ZAJEZD_ID" type="long">
<generator class="native"></generator>
</id>
<property name="nazevZajezdu" column="NAZEV" not-null="true" unique="true"></property>
<property name="atribut1" column="ATRIBUT1"></property>
<property name="atribut2" column="ATRIBUT2"></property>
<set name="cestujici"><!-- název atributu ve třídě Zajezd -->
<key column="ZAJEZD_ID"></key><!-- název sloupce v tabulce OSOBA, který je cizím klíčem k tabulce ZAJEZD -->
<one-to-many class="Osoba" />
</set>
</class>
</hibernate-mapping>
b) anotace
Anotace lze použít dvěma způsoby – buďto u atributů nebo u jejich getterů. Následují výpisy, které ukazují použití obojího.
Použití anotací u atributů:
@Entity(access = AccessType.FIELD)
@Table (name="ZAJEZD")
public class Zajezd {
@Id (generate = GeneratorType.AUTO)
private Long id;
@Column (length=100, nullable=false, unique=true)
private String nazev;
@Column (length=100)
private String atribut1;
@Column (length=30)
private String atribut2;
private Set<Osoba> cestujici;
}
Použití anotací u metod:
@Entity(access = AccessType.PROPERTY)
@Table (name="ZAJEZD")
public class Zajezd {
private Long id,
private String nazev;
private String atribut1;
private String atribut2;
private Set<Osoba> cestujici;
@Id (generate = GeneratorType.AUTO)
public int getId() {
return id;
}
@Column (length=100)
public String getNazev() {
return nazev;
}
@Column (length=100)
public String getAtribut1() {
return atribut1;
}
@Column (length=30)
public String getAtribut2() {
return atribut2;
}
public void setNazev(String nazev) {
this.nazev = nazev;
}
...
}
Konfigurační soubor pro Hibernate
Hibernate potřebuje pro správnou funkci několik nastavení, jako je JDBC driver, adresa databáze (connection string), generátor SQL dotazů (dialect) nebo cesty k mapovacím souborům. Tento konfigurační soubor se běžně pojmenovává „hibernate.cfg.xml“.
<hibernate-configuration>
<session-factory>
<!-- JDBC driver -->
<property name="hibernate.connection.driver_class">
org.gjt.mm.mysql.Driver
</property>
<!-- generátor SQL dotazů (dialect) -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect
</property>
<!-- connection string -->
<property name="hibernate.connection.url">
jdbc:mysql://server/databaze
</property>
<!-- přihlašovací údaje k databázi -->
<property name="hibernate.connection.username">uzivatel</property>
<property name="hibernate.connection.password">heslo</property>
<!-- automaticky vytvořit prázdné tabulky v databázi -->
<!-- (odstraní stávající, takže nevhodné pro produkční užití) -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- cesty k mapovacím souborům -->
<mapping resource="model/Zajezd.hbm.xml"/>
<mapping resource="model/Osoba.hbm.xml" />
</session-factory>
</hibernate-configuration>
HQL – Hibernate Query Language
Preferovaný způsob práce s objekty je HQL (oproti SQL). Syntaxe je SQL velice podobná, ale HQL je, na rozdíl od SQL, objektově orientované, takže rozumí věcem jako dědičnost, polymorfismus, apod. Dotaz „from java.lang.Object o“ by tedy vrátil úplně všechny persistentní objekty. Nejjednodušší dotaz vypadá takto: „from Zajezd“ – vrátí všechny instance třídy Zajezd.
Pokud se v dotazu chceme odvolávat na „Zajezd“, je potřeba mu přiřadit alias: „from Zajezd as zajezd“ – je zvykem pojmenovávat aliasy stejným slovem jako název třídy, ale podle konvence, kterou pojmenováváme atributy. Použili bychom toho následujícím způsobem: „from Zajezd as zajezd where zajezd.nazev = nazev“
HQL podporuje klasické konstrukce, na které jsme zvyklí z SQL, jako jsou: INNER a OUTER JOIN, klauzule WHERE nebo WITH, agregační výrazy jako AVG() nebo COUNT(), subdotazy, atd. Další zajímavostí je QBE – Query by Example. Jedná se o způsob dotazování, kdy vytvoříme nový objekt s vlastnostmi, které hledáme a tento objekt poté předáme do HQL a ten nám vrátí objekty se stejnými vlastnostmi.
Zajezd z = new Zajezd();
z.setCestujici(cestujici);
z.setNazev(„Nazev Zajezdu“);
List vysledek = session.createCriteria(Zajezd.class)
.add( Example.create(z) )
.list();
V předchozím příkladu byla použita konstrukce „Criteria“. QBE je ve skutečnosti pouze jedním z více druhů kritérií, které můžeme pro dotazy zavádět. V obecnější rovině vypadají kritéria následovně:
Criteria crit = sess.createCriteria(Zajezd.class);
crit.setMaxResults(50);
List zajezdy = crit.list();
nebo:
List zajezdy = sess.createCriteria(Zajezd.class)
.add( Restrictions.like("nazev", "Kostarika%") )
.add( Restrictions.or(
Restrictions.eq( "atribut1", hledanaHodnota ),
Restrictions.isNull("atribut2")
) )
.list();
Výhody používání Hibernate
Hibernate, framework pro perzistentní vrstvu, usnadňuje programátorovi práci tím, že nemusí transformovat objekty do relací ručně, ale přenechá to perzistentní vrstvě. Zároveň jsou tím odstíněna specifika jednotlivých databází – programátor používá API Hibernate.
Odkazy
Související články
Externí odkazy
- Obrázky, zvuky či videa k tématu Hibernate na Wikimedia Commons
- (anglicky) Oficiální stránky Hibernate
- (anglicky) Interview s tvůrcem Hibernate - Gavinem Kingem[nedostupný zdroj]
Další podobné frameworky
- (anglicky) Java Persistence API - JPA
- (anglicky) CocoBase
- (anglicky) OpenJPA
- (anglicky) Spring Framework