Kurs Hibernate – część 1

Zapraszam na szybki kurs Hibernate. Wspólnie stworzymy cztery proste aplikacje bazodanowe w języku Java wykorzystujące mapowanie obiektowo-relacyjne (Object-Relational Mapping, ORM) za pomocą frameworku Hibernate. W pierwszej części kursu Hibernate mapowanie obiektów języka Java na tabele w bazie danych.

Dla niecierpliwych: Jeśli chcesz szybko uruchomić opisywaną w tej części kursu Hibernate aplikację bazodanową, pobierz plik .zip wskazany na końcu tego tekstu, a następnie zajrzyj do mojego artykułu o importowaniu istniejącego projektu z plikiem budowania Apache Ant do Eclipse.

Mapowanie obiektowo-relacyjne w Hibernate

Pierwszą część kursu Hibernate zaczniemy od prostej klasy języka Java opisującej autorów książek. Klasę nazwiemy Autor i zapiszemy oczywiście w pliku Autor.java. Będzie się ona składać z trzech pól: id zawierającego unikalny identyfikator autora, imie zawierającego imię autora oraz nazwisko zawierającego nazwisko autora. Oprócz pól klasa będzie zawierać konstruktor bezparametrowy oraz gettery i settery do wszystkich pól. Dokładny kod całej klasy przedstawiam poniżej.

package pl.iprogramujesz.bazydanych.hibernate;

public class Autor {
	private Long id;
	private String imie;
	private String nazwisko;

	public Autor() {
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getImie() {
		return imie;
	}

	public void setImie(String imie) {
		this.imie = imie;
	}

	public String getNazwisko() {
		return nazwisko;
	}

	public void setNazwisko(String nazwisko) {
		this.nazwisko = nazwisko;
	}
}

Obiekty klasy Autor będziemy przechowywać w bazie danych. Do tego celu utworzymy tabelę AUTOR o strukturze odpowiadającej zawartości klasy Autor, tzn. o kolumnach ID, IMIE i NAZWISKO. Ponieważ w tym kursie Hibernate nie chcę wnikać w strukturę samej bazy danych, nie będziemy samodzielnie tworzyć tej tabeli, a pozwolimy Hibernate utworzyć ją automatycznie przy pierwszym uruchomieniu aplikacji.

Poinformujemy Hibernate o zależnościach między klasą Autor a tabelą AUTOR określając mapowanie obiektowo-relacyjne między klasą Autor a tabelą AUTOR. Określa się je zwykle w pliku .hbm.xml o nazwie odpowiadającej nazwie mapowanej klasy. Utworzymy więc plik Autor.hbm.xml o zawartości przedstawionej poniżej.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="pl.iprogramujesz.bazydanych.hibernate">

	<class name="Autor" table="AUTOR">

		<id name="id" column="ID">
			<generator class="native"/>
		</id>

		<property name="imie" column="IMIE"/>

		<property name="nazwisko" column="NAZWISKO"/>

	</class>

</hibernate-mapping>

Mapowania obiektowo-relacyjne Hibernate określa się elementem <hibernate-mapping>. Parametr package definiuje nazwę pakietu języka Java, w którym znajdują się mapowane klasy. Zagnieżdżone elementy <class> określają mapowania poszczególnych klas. Parametr name zawiera nazwę klasy, a parametr table nazwę odpowiadającej jej tabeli w bazie danych. Wewnątrz elementu <class> określa się mapowania poszczególnych pól klasy na poszczególne kolumny tabeli. Element <id> określa klucz główny. Parametr name definiuje nazwę pola klasy zawierającego unikalny identyfikator obiektu, a parametr column nazwę odpowiadającej mu kolumny tabeli zawierającej klucz główny. Element <generator class=”native”/> wskazuje Hibernate sposób generowania wartości tego pola dla nowo tworzonych obiektów. Element <property> określa mapowanie pola klasy, wskazanego w parametrze name, na kolumnę tabeli, wskazaną w parametrze column.

Utworzony plik Autor.hbm.xml wystarcza frameworkowi Hibernate do poprawnego pobierania obiektów klasy Autor z tabeli AUTOR w bazie danych i poprawnego ich zapisywania do bazy danych. Określa on mapowanie obiektowo-relacyjne między obiektami klasy Autor a wierszami tabeli AUTOR.

Konfiguracja Hibernate

Oprócz określenia mapowania obiektowo-relacyjnego między klasą Autor a tabelą AUTOR, musimy jeszcze skonfigurować całość frameworku Hibernate. W tym kursie Hibernate zrobimy to w najprostszy sposób, określając konfigurację Hibernate w pliku hibernate.cfg.xml, którego zawartość przedstawiam poniżej.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

	<session-factory>

		<property name="connection.driver_class">org.postgresql.Driver</property>
		<property name="connection.url">jdbc:postgresql://localhost:5432/postgres</property>
		<property name="connection.username">postgres</property>
		<property name="connection.password">iProgramujesz.pl</property>

		<property name="connection.pool_size">1</property>

		<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

		<property name="current_session_context_class">thread</property>

		<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

		<property name="show_sql">false</property>

		<property name="hbm2ddl.auto">update</property>

		<mapping resource="pl/iprogramujesz/bazydanych/hibernate/Autor.hbm.xml"/>

	</session-factory>

</hibernate-configuration>

Konfigurację Hibernate określa się elementem <hibernate-configuration>. Zagnieżdżony element <session-factory> określa parametry nawiązywanych sesji Hibernate do operacji bazodanowych. Pierwsze cztery wiersze określają parametry połączenia z serwerem baz danych (nazwę sterownika JDBC, adres serwera baz danych, nazwę użytkownika i hasło). Ostatni wiersz, zawierający element <mapping >, określa lokalizację pliku z mapowaniem obiektowo-relacyjnym używanym przez Hibernate w naszej aplikacji.

Szkielet aplikacji bazodanowej z Hibernate

Pozostała do napisania główna część aplikacji bazodanowej uruchamiająca framework Hibernate i wykonująca operacje na obiektach klasy Autor. W tym kursie Hibernate utworzymy klasę pomocniczą HibernateUtil, która zainicjalizuje framework Hibernate i będzie udostępniać sesje Hibernate do operacji bazodanowych. Dokładny kod całej klasy przedstawiam poniżej.

package pl.iprogramujesz.bazydanych.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		try {
			Configuration configuration = new Configuration();
			configuration.configure();

			StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
			standardServiceRegistryBuilder.applySettings(configuration.getProperties());
			ServiceRegistry serviceRegistry = standardServiceRegistryBuilder.build();

			return configuration.buildSessionFactory(serviceRegistry);
		}
		catch(Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}

Pozostaje napisać główną część aplikacji – klasę KursHibernate01 z metodą statyczną main uruchamiającą całość aplikacji z tej części kursu Hibernate. Metoda ta otwiera sesję Hibernate do operacji bazodanowych, tworzy obiekt klasy Autor, zapisuje go w bazie danych, pobiera listę wszystkich autorów z bazy danych i wyświetla ją, po czym zamyka sesję Hibernate. Dokładny kod całej klasy przedstawiam poniżej.

package pl.iprogramujesz.bazydanych.hibernate;

import java.util.List;
import org.hibernate.Session;

public class KursHibernate01 {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Autor autor = new Autor();
		autor.setImie("Henryk");
		autor.setNazwisko("Sienkiewicz");
		session.save(autor);

		List<Autor> autorzy = session.createQuery("from Autor").list();
		for(Autor a : autorzy) {
			System.out.println(a.getId() + "\t" + a.getImie() + "\t" + a.getNazwisko());
		}

		session.getTransaction().commit();

		HibernateUtil.getSessionFactory().close();
	}
}

Uruchomienie aplikacji bazodanowej z Hibernate

Aplikacja opisana w tej części kursu Hibernate składa się z plików opisanych we wcześniejszych sekcjach: Autor.java, Autor.hbm.xml, hibernate.cfg.xml, HibernateUtil.java, KursHibernate01.java.

Jako podsumowanie tej części kursu Hibernate, przygotowałem plik .zip zawierający całość aplikacji bazodanowej z Hibernate z mapowaniem obiektów. Jeśli nie wiesz jak szybko uruchomić pobraną aplikację przeczytaj mój artykuł o importowaniu istniejącego projektu z plikiem budowania Apache Ant do Eclipse.