Hibernate

advertisement
Hibernate
Każda poważniejsza aplikacja wymaga przechowywania danych w jakiejś bazie danych. Można
realizować to na wiele sposobów. Można obsługę bazy danych pisać samodzielnie, do zera, albo
skorzystać z gotowych frameworków – bo po co wynajdywać koło od nowa? Jednym z takich
frameworków jest Hibernate.
Wstęp
Hibernate jest frameworkiem, który pozwala realizować w prosty i szybki sposób obsługę
przechowywania danych w bazie danych, niezależnie od systemu baz danych. Hibernate będzie
więc warstwą pośredniczącą pomiędzy systemem baz danych, a aplikacją, będzie tak zwaną
warstwą dostępu do danych (ang. persistance layer). Przede wszystkim dostarcza on translację, czy
też mapowanie obiektów ze świata Javy, na relacyjne bazy danych. Strukturę mapowania
definiujemy przy użyciu kodu XML, w odpowiednich plikach. Ważną zaletą projektu Hibernate jest
fakt, iż pozwala on zwiększyć wydajność warstwy dostępu do danych dzięki minimalizacji liczby
zapytań (poprzez buforowanie). Rysunek 1 przedstawia odpowiednie warstwy aplikacji – jak
widzimy, Hibernate jest pośrednikiem między aplikacją, a bazą danych.
Ilustracja 1: Warstwy aplikacji
Hibernate jest projektem open source, a jego liderem i inicjatorem jest Gavin King.
Projekt został podzielony na kilka podprojektów takich, jak:
•
Hibernate Core - centralna część wszystkich projektów – pozostałe są jej rozszerzeniami;
•
Hibernate Annotations – pozwala na stosowanie adnotacji (zamiast dokumentów XML) do
mapowania obiektów;
•
Hibernate EntityManager – dzięki temu rozszerzeniu można stosować technikę mapowania
w zgodzie ze standardem Java Persistence Manager;
•
Hibernate Shards – ułatwia sterowanie Hibernate Core w przypadku wielu baz danych;
•
Hibernate Validator – dzięki temu rozszerzeniu otrzymujemy możliwość walidacji, czy też
ograniczeń, które nałożymy na żądane pola;
•
Hibernate Search – pełnotekstowe wyszukiwanie w oparciu o bibliotekę Lucene;
•
Hibernate Tools – zestaw narzędzi, które ułatwiają pracę z frameworkiem (wtyczka do
Eclipse, zadania dla Anta);
•
NHibernate – Hibernate dla platformy .NET.
Hibernate posiada także dużą społeczność, zatem nietrudno uzyskać jakieś wsparcie w przypadku
problemów.
Rozpoczynamy pracę
Na potrzeby artykułu, założymy, że korzystamy ze środowiska programistycznego NetBeans
(wersja 6.8). Do budowania aplikacji wykorzystujemy także Mavena.
Klikając prawym przyciskiem myszki na sekcję Librarier w drzewie projektu, z menu
kontekstowego wybieramy opcję Add Dependencies. Pojawia się okno, w którym można wyszukać
zależności (rys. 2). Wpisujemy Hibernate i czekamy, aż Maven znajdzie w swoim repozytorium
odpowiednie dane.
Ilustracja 2: Dodajemy Hibernate do projektu
Spowoduje to automatyczną edycję pliku pom.xml przez NetBeansa.
Kolejnym krokiem będzie utworzenie pliku konfiguracyjnego.hibernate.cfg.xml. Również to można
zrobić automatycznie z wykorzystaniem NetBeansa, wybierając opcję dodania nowego pliku do
projektu. Plik należy umieścić w katalogu src/main/resources. Jego treść przedstawiono na listingu
1.
Listing 1. Treść pliku hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="hibernate.connection.url">jdbc:mysql://db4free.net:3306/helloworld</proper
ty>
<property name="hibernate.connection.username">helloworld</property>
<property name="hibernate.connection.password">helloworldpass</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/helloworld/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Kluczowymi informacjami, które tutaj podajemy, to dane dostępu do bazy danych (znaczniki:
<property name=”hibernate.connection.url”/>, <property
name=”hibernate.connection.username”/>, <property
name=”hibernate.connection.password”/>), informacje o typie bazy danych, oraz pliki z
zdefiniowanym mapowaniem (znaczniki <mapping resource=”...”/>).
Następnie tworzymy właśnie pliki z definicjami mapowanie, w naszym przypadku jest to
User.hbm.xml. Jego zawartość przedstawiono na listingu 2. Tworzymy także odpowiadający mu pilk
z definicją klasy opisującą mapowane obiekty (listing 3).
Listing 2. Zawartość pliku User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping3.0.dtd">
<hibernate-mapping package="com.helloworld">
<class name="User" table="Users">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="login"/>
<property name="password"/>
<property name="email"/>
</class>
</hibernate-mapping>
Listing 3. Zawartość pliku User.java
//@Entity
public class User implements Serializable {
private Long
id;
private String
login;
private String
password;
private String
email;
public User() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Pozostaje jeszcze utworzyć plik HibernateUtil.java, który pozwoli nam przeprowadzać operacje na
bazie danych – listing 4. Również ten plik może zostać wygenerowany automatycznie przez
NetBeansa poprzez wybranie opcji dodania nowego pliku do projektu.
Listing 4. Plik HibernateUtil.java
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
return new
Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
private static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void saveEntity(Object entity) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
session.save(entity);
transaction.commit();
}
public static List getEntities(Class criteria) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
List result = session.createCriteria(criteria).list();
transaction.commit();
return result;
}
}
Przede wszystkim widzimy, że jest to singleton, który obiekt sessionFactory tworzy tylko raz.
Parametryzujemy jego tworzenie poprzez podanie nazwy pliku konfiguracyjnego, który
utworzyliśmy wcześniej. Poza tym, interesują nas właściwie dwie funkcje: saveEntity oraz
getEntities. Pisząc kod HibarnateUtil.saveEntity(new User()), mamy już zapewniony zapis obiektu
do bazy danych. Wcześniej należy oczywiście obiekt ten wypełnić odpowiednimi danymi.
Podobnie rzecz ma się z pobieraniem obiektów z bazy danych przy pomocy funkcji getEntities.
Tutaj otrzymamy na wyjściu listę. Jedynym kryterium, które podajemy, jest typ (klasa) obiektu,
czyli w kontekście bazy danych – tabela.
Zaznaczmy tutaj, że nie jest konieczne przygotowanie tabeli w bazie danych – Hibernate utworzy ją
w razie potrzeby automatycznie.
Podsumowanie
Przygotowanie komunikacji między aplikacją a bazą danych jest niezwykle proste z użyciem
frameworka Hibernate w roli warstwy pośredniczącej. Jego wsparcie dla licznych typów baz
danych nie ogranicza nas tylko do jednego systemu, a duża społeczność dostarczy ogromne
wsparcie. Zachęcam do pogłębienia wiedzy z zakresu tego projektu. Pamiętajmy, że decydując się
na Hibernate nie jesteśmy zmuszeni do korzystania z Javy – można używać również platformy
.NET.
Download