Hibernate Anleitung und Beispiele



1. Einleitung

Diese Seite ist eine kleine Einführung zum objektrelationale Mapping von Datenbanken mit dem Open Source Tool Hibernate. Als Beispiel dient eine Zitate Datenbank auf Basis von MySQL. Andere Datenbanken sind auch durch leichtes anpassen der Konfiguration möglich.

2. Datenbank

Als Grundlage des Beispiels soll diese Zitate Datenbank mit folgender Struktur dienen.

Datenbank

Es gibt eine 1:n Beziehung. Ein Autor kann mehrere Zitate haben.

3. Mapping

Möglichkeiten des Mappings:

Nr. Mapping von nach mit Klasse oder Tool Beispiel Bemerkung
1 XML DDL net.sf.hibernate.tool.
hbm2ddl.SchemaExport
tw-zitat-schema-export.bat Erzeugt aus der XML Mapping Datei das Schema für die Datenbank.
2 DDL XML Middlegen - Aus vorhandener Datenbank wird mit Middlegen die Hibernate Mapping XML Datei erzeugt.
3 XML Java net.sf.hibernate.tool.
hbm2java.CodeGenerator
tw-zitat-generate-java.bat Generiert Java Code (Beans) aus XML Hibernate Mapping Dateien.
4 Java XML net.sf.hibernate.tool.
class2hbm.MapGenerator
tw-zitat-mapping.bat Aus Java Klassen werden die Hibernate XML Dateien generiert.
5 Java XML XDoclet - Aus Java Klassen die mit XDoclet Tags versehen sind,werden die Hibernate XML Dateien generiert.

DDL = Datenbank Schema
XML = Hibernate Mapping
Java = Java Beans

Es gibt verschiedenen Ansätze für die Vorgehensweise. Der Middle-out-Ansatz beginnt mit dem erstellen der Hibernate XML Datei. Dann wird mit dem hbm2ddl Tool das Datenbank Schema erzeugt. Anschließend werden die Java Beans mit hbm2java generiert.
Der Bottom-up-Ansatz geht von einer bestehenden Datenbank aus. Bei dem Top-down-Ansatz wird mit dem schreiben der Java Beans begonnen.

3.1 Mapping XML nach DDL

Kommen wir zum ersten Beispiel. Wir erstellen die Hibernate Mapping XML Datei per Hand. Und generieren dann über hbm2ddl das Datenbank Schema. Für jede Tabelle wird je eine XML Datei erstellt. Für unser Beispiel könnten sie so aussehen:

Die XML Datei für die Autoren:

<?xml version="1.0"?

Die XML Datei für die Zitate:

<?xml version="1.0"?

Aus beiden obigen mapping Dateien wird eine tw-zitat-mapping.xml erzeugt. Aus dieser Mapping Datei wird dann das Datenbankschema erzeugt. Es kann ein solches Script verwendet werden. Die Pfade müssen entsprechen angepasst werden.

rem tw-zitat-schema-export.bat

set BASIS=E:\Java\lokal\TWZitat
set LIB=%BASIS%\lib
set BIN=%BASIS%\bin
set INPUT_DATEI=tw-zitat-mapping.xml
set OUTPUT_SCHEMA_DATEI=tw-zitat-schema.ddl

set DB_TREIBER=C:\mysql\mm.mysql.jdbc-1.2c\mysql_comp.jar

set CP=%LIB%;
%BIN%;
%DB_TREIBER%;
%CLASSPATH%;
%LIB%\hibernate2.jar;
%LIB%\commons-logging-1.0.4.jar;
%LIB%\commons-lang-1.0.1.jar;
%LIB%\cglib-2.0-rc2.jar;
%LIB%\dom4j-1.4.jar;
%LIB%\odmg-3.0.jar;
%LIB%\xml-apis.jar;
%LIB%\xerces-2.4.0.jar;
%LIB%\xalan-2.4.0.jar;
%LIB%\jdom.jar;
%LIB%\commons-collections-2.1.1.jar;
%LIB%\hibernate-tools.jar

rem --text Option schreibt keine Datenbank

java -cp %CP% net.sf.hibernate.tool.hbm2ddl.SchemaExport
--text
--format
--delimiter=;
--properties=%BASIS%/hibernate.properties
--output=%OUTPUT_SCHEMA_DATEI% %INPUT_DATEI%

Für die Ausführung werden die obigen jar Dateien benötigt. Sie sind alle bei Hibernate dabei. Die hibernate-tools.jar ist im hibernate-extensions-2.1.3 Package enthalten das gesondert geladen werden muss.

Nach dem fehlerfreien Ausführen erhält man das Datenbank Schema, welches in die DB geschrieben werden kann. Wird die --text Option nicht angegeben, wird versucht gleich in die Datenbank zu schreiben. Für unser Beispiel sieht das erzeugte Schema (tw-zitat-schema.ddl) so aus:

alter table ZITATE drop foreign key FK9DC0094D84751B00;
drop table if exists ZITATE;
drop table if exists AUTOREN;
create table ZITATE (
   ZITATE_ID integer not null auto_increment,
   AUTOR_NR integer not null,
   ZITAT varchar(255) not null,
   KATEGORIE integer,
   primary key (ZITATE_ID)
);
create table AUTOREN (
   AUTOREN_ID integer not null auto_increment,
   NAME varchar(255) not null,
   GEBDATUM date,
   BERUF varchar(255),
   BEMERKUNG varchar(255),
   VORNAME varchar(255),
   TODESDATUM date,
   primary key (AUTOREN_ID)
);
alter table ZITATE add index FK9DC0094D84751B00 (AUTOR_NR),
add constraint FK9DC0094D84751B00
foreign key (AUTOR_NR) references AUTOREN (AUTOREN_ID);

Nach dem Import dieses Schemas in die Datenbank ist die gewünschte Zitat Datenbank vorhanden.

3.2 Mapping DDL nach XML

//todo

3.3 Mapping XML nach Java

Aus den oben erstellten Hibernate Mapping Datei tw-zitat-mapping.xml die für die Autoren und die Zitate die beschreibungen enthält wird nun Java Code generiert. Die tw-zitat-generate-java.bat ruft den hbm2java CodeGenerator auf.

rem tw-zitat-generate-java.bat
set BASIS=E:\Java\lokal\TWZitat
set LIB=%BASIS%\lib
set BIN=%BASIS%\bin
set INPUT_DATEI=tw-zitat-mapping.xml
set OUTPUT_SCHEMA_DATEI=tw-zitat-schema.ddl

set CP=%LIB%;
%BIN%;
%DB_TREIBER%;
%CLASSPATH%;
%LIB%\hibernate2.jar;
%LIB%\commons-logging-1.0.4.jar;
%LIB%\commons-lang-1.0.1.jar;
%LIB%\cglib-2.0-rc2.jar;
%LIB%\dom4j-1.4.jar;
%LIB%\odmg-3.0.jar;
%LIB%\xml-apis.jar;
%LIB%\xerces-2.4.0.jar;
%LIB%\xalan-2.4.0.jar;
%LIB%\jdom.jar;
%LIB%\commons-collections-2.1.1.jar;
%LIB%\hibernate-tools.jar

java -cp %CP% net.sf.hibernate.tool.hbm2java.CodeGenerator %INPUT_DATEI%

Das Ergebnis sind zwei Java Beans. Eine für den Autor:

   1:package de.wenzlaff.twzitat.mapping;
   2:
   3:import java.io.Serializable;
   4:import java.util.Date;
   5:import java.util.Set;
   6:import org.apache.commons.lang.builder.ToStringBuilder;
   7:
   8:
   9:/** @author Hibernate CodeGenerator */
  10:public class Autor implements Serializable {
  11:
  12:    /** identifier field */
  13:    private Integer id;
  14:
  15:    /** persistent field */
  16:    private String name;
  17:
  18:    /** nullable persistent field */
  19:    private Date gebDatum;
  20:
  21:    /** nullable persistent field */
  22:    private String beruf;
  23:
  24:    /** nullable persistent field */
  25:    private String bemerkung;
  26:
  27:    /** nullable persistent field */
  28:    private String vorname;
  29:
  30:    /** nullable persistent field */
  31:    private Date todesDatum;
  32:
  33:    /** persistent field */
  34:    private Set zitate;
  35:
  36:    /** full constructor */
  37:    public Autor(String name, Date gebDatum, String beruf, String bemerkung, String vorname, Date todesDatum, Set zitate) {
  38:        this.name = name;
  39:        this.gebDatum = gebDatum;
  40:        this.beruf = beruf;
  41:        this.bemerkung = bemerkung;
  42:        this.vorname = vorname;
  43:        this.todesDatum = todesDatum;
  44:        this.zitate = zitate;
  45:    }
  46:
  47:    /** default constructor */
  48:    public Autor() {
  49:    }
  50:
  51:    /** minimal constructor */
  52:    public Autor(String name, Set zitate) {
  53:        this.name = name;
  54:        this.zitate = zitate;
  55:    }
  56:
  57:    public Integer getId() {
  58:        return this.id;
  59:    }
  60:
  61:    public void setId(Integer id) {
  62:        this.id = id;
  63:    }
  64:
  65:    public String getName() {
  66:        return this.name;
  67:    }
  68:
  69:    public void setName(String name) {
  70:        this.name = name;
  71:    }
  72:
  73:    public Date getGebDatum() {
  74:        return this.gebDatum;
  75:    }
  76:
  77:    public void setGebDatum(Date gebDatum) {
  78:        this.gebDatum = gebDatum;
  79:    }
  80:
  81:    public String getBeruf() {
  82:        return this.beruf;
  83:    }
  84:
  85:    public void setBeruf(String beruf) {
  86:        this.beruf = beruf;
  87:    }
  88:
  89:    public String getBemerkung() {
  90:        return this.bemerkung;
  91:    }
  92:
  93:    public void setBemerkung(String bemerkung) {
  94:        this.bemerkung = bemerkung;
  95:    }
  96:
  97:    public String getVorname() {
  98:        return this.vorname;
  99:    }
 100:
 101:    public void setVorname(String vorname) {
 102:        this.vorname = vorname;
 103:    }
 104:
 105:    public Date getTodesDatum() {
 106:        return this.todesDatum;
 107:    }
 108:
 109:    public void setTodesDatum(Date todesDatum) {
 110:        this.todesDatum = todesDatum;
 111:    }
 112:
 113:    public Set getZitate() {
 114:        return this.zitate;
 115:    }
 116:
 117:    public void setZitate(Set zitate) {
 118:        this.zitate = zitate;
 119:    }
 120:
 121:    public String toString() {
 122:        return new ToStringBuilder(this)
 123:            .append("id", getId())
 124:            .toString();
 125:    }
 126:
 127:}

Und eine für die Zitate:

   1:package de.wenzlaff.twzitat.mapping;
   2:
   3:import java.io.Serializable;
   4:import org.apache.commons.lang.builder.ToStringBuilder;
   5:
   6:
   7:/** @author Hibernate CodeGenerator */
   8:public class Zitat implements Serializable {
   9:
  10:    /** identifier field */
  11:    private Integer id;
  12:
  13:    /** persistent field */
  14:    private int autorNr;
  15:
  16:    /** persistent field */
  17:    private String zitat;
  18:
  19:    /** nullable persistent field */
  20:    private Integer kategorie;
  21:
  22:    /** full constructor */
  23:    public Zitat(int autorNr, String zitat, Integer kategorie) {
  24:        this.autorNr = autorNr;
  25:        this.zitat = zitat;
  26:        this.kategorie = kategorie;
  27:    }
  28:
  29:    /** default constructor */
  30:    public Zitat() {
  31:    }
  32:
  33:    /** minimal constructor */
  34:    public Zitat(int autorNr, String zitat) {
  35:        this.autorNr = autorNr;
  36:        this.zitat = zitat;
  37:    }
  38:
  39:    public Integer getId() {
  40:        return this.id;
  41:    }
  42:
  43:    public void setId(Integer id) {
  44:        this.id = id;
  45:    }
  46:
  47:    public int getAutorNr() {
  48:        return this.autorNr;
  49:    }
  50:
  51:    public void setAutorNr(int autorNr) {
  52:        this.autorNr = autorNr;
  53:    }
  54:
  55:    public String getZitat() {
  56:        return this.zitat;
  57:    }
  58:
  59:    public void setZitat(String zitat) {
  60:        this.zitat = zitat;
  61:    }
  62:
  63:    public Integer getKategorie() {
  64:        return this.kategorie;
  65:    }
  66:
  67:    public void setKategorie(Integer kategorie) {
  68:        this.kategorie = kategorie;
  69:    }
  70:
  71:    public String toString() {
  72:        return new ToStringBuilder(this)
  73:            .append("id", getId())
  74:            .toString();
  75:    }
  76:
  77:}

3.4 Mapping Java nach XML

Um aus vorhandenen Java Beans eine Hiberate Mapping Datei zu erhalten, kann das class2hbm Tool verwendet werden. Dabei wird die Java Datei die gemappt werden soll, wie folgt mit dem MapGenerator aufgerufen.
rem  tw-zitat-mapping.bat

set BASIS=E:\Java\lokal\TWZitat
set LIB=%BASIS%\lib
set BIN=%BASIS%\bin
set OUTPUT_DATEI=tw-zitat-mapping.xml

set MAPPING_CLASS=de.wenzlaff.twzitat.mapping.Autor de.wenzlaff.twzitat.mapping.Zitat

set CP=%LIB%;
%BIN%;
%CLASSPATH%;
%LIB%\hibernate2.jar;
%LIB%\commons-logging-1.0.4.jar;
%LIB%\commons-lang-1.0.1.jar;
%LIB%\cglib-2.0-rc2.jar;
%LIB%\dom4j-1.4.jar;
%LIB%\odmg-3.0.jar;
%LIB%\xml-apis.jar;
%LIB%\xerces-2.4.0.jar;
%LIB%\xalan-2.4.0.jar;
%LIB%\jdom.jar;
%LIB%\commons-collections-2.1.1.jar;
%LIB%\hibernate-tools.jar

java -classpath %CP% net.sf.hibernate.tool.class2hbm.MapGenerator
--output=%OUTPUT_DATEI% %MAPPING_CLASS%

Das Ergebnis sind die automatisch erzeugten XML Dateien. Die für den Autor:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

	<class name="de.wenzlaff.twzitat.mapping.Autor" table="AUTOREN">

		<id name="id" column="AUTOREN_ID" type="integer">
			<generator class="identity"/>
		</id

Und die für die Zitate:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

	<class name="de.wenzlaff.twzitat.mapping.Zitat" table="ZITATE">
		<id name="id" column="ZITATE_ID" type="integer">
                  <generator class="identity"/>
		</id

3.5 Mapping Java nach XML mit XDoclet

//todo

4. Java Anbindung

Das folgende Java Beispiel zeigt den Zugriff mit Hibernate.

   1:/*
   2: * Thomas Wenzlaff 05.05.2006
   3: */
   4:package test.de.wenzlaff.twzitat;
   5:
   6:import java.util.Date;
   7:import java.util.List;
   8:
   9:import net.sf.hibernate.HibernateException;
  10:import net.sf.hibernate.Session;
  11:import net.sf.hibernate.SessionFactory;
  12:import net.sf.hibernate.Transaction;
  13:import net.sf.hibernate.cfg.Configuration;
  14:import de.wenzlaff.twzitat.mapping.Autor;
  15:import de.wenzlaff.twzitat.mapping.Zitat;
  16:
  17:/**
  18: * @author Thomas Wenzlaff
  19: *  
  20: */
  21:public class ZitatGenerator {
  22:
  23:    private SessionFactory sessionFactory;
  24:
  25:    public static void main(String[] args) {
  26:
  27:        ZitatGenerator ivZitatInstanz = new ZitatGenerator();
  28:        // ivZitatInstanz.showAlleZitat();
  29:        // ivZitatInstanz.showAlleAutoren();
  30:        ivZitatInstanz.showAlleZitatMitAutoren();
  31:    }
  32:
  33:    public ZitatGenerator() {
  34:        try {
  35:            System.out.println("Initializing Hibernate");
  36:            sessionFactory = new Configuration().configure()
  37:                    .buildSessionFactory();
  38:            System.out.println("Finished Initializing Hibernate");
  39:        } catch (HibernateException ex) {
  40:            ex.printStackTrace();
  41:            System.exit(5);
  42:        }
  43:    }
  44:
  45:    private void showAlleZitat() {
  46:        Session sess = null;
  47:        Transaction trx = null;
  48:        try {
  49:            sess = sessionFactory.openSession();
  50:            trx = sess.beginTransaction();
  51:
  52:            List lvZitate = sess.find("from Zitat");
  53:            for (int i = 0; i < lvZitate.size(); i++) {
  54:                Zitat lvZitat = (Zitat) lvZitate.get(i);
  55:                System.out.println("Autor Nr.:  " + lvZitat.getAutorNr()
  56:                        + " : " + lvZitat.getZitat());
  57:
  58:            }
  59:            trx.commit();
  60:        } catch (HibernateException ex) {
  61:            if (trx != null) try {
  62:                trx.rollback();
  63:            } catch (HibernateException exRb) {
  64:            }
  65:            throw new RuntimeException(ex.getMessage());
  66:        } finally {
  67:            try {
  68:                sess.close();
  69:            } catch (Exception exCl) {
  70:            }
  71:        }
  72:    }
  73:
  74:    private void showAlleAutoren() {
  75:        Session sess = null;
  76:        Transaction trx = null;
  77:        try {
  78:            sess = sessionFactory.openSession();
  79:            trx = sess.beginTransaction();
  80:
  81:            List lvZitate = sess.find("from Autor");
  82:            for (int i = 0; i < lvZitate.size(); i++) {
  83:                Autor lvAutor = (Autor) lvZitate.get(i);
  84:                System.out.println("Autor Nr.: " + lvAutor.getId() + " = "
  85:                        + lvAutor.getVorname() + " " + lvAutor.getName() + "( "
  86:                        + lvAutor.getBeruf() + " )");
  87:            }
  88:            trx.commit();
  89:        } catch (HibernateException ex) {
  90:            if (trx != null) try {
  91:                trx.rollback();
  92:            } catch (HibernateException exRb) {
  93:            }
  94:            throw new RuntimeException(ex.getMessage());
  95:        } finally {
  96:            try {
  97:                sess.close();
  98:            } catch (Exception exCl) {
  99:            }
 100:        }
 101:    }
 102:
 103:    private void showAlleZitatMitAutoren() {
 104:        Session sess = null;
 105:        Transaction trx = null;
 106:        try {
 107:            sess = sessionFactory.openSession();
 108:            trx = sess.beginTransaction();
 109:
 110:            List lvZitate = sess.find("from Zitat where AUTOR_NR=2");
 111:            List lvAutor = sess.find("from Autor where AUTOREN_ID=2");
 112:
 113:            for (int i = 0; i < lvZitate.size(); i++) {
 114:                Zitat lvZitat = (Zitat) lvZitate.get(i);
 115:                System.out.println("Autor Nr.:  " + lvZitat.getAutorNr() + " "
 116:                        + lvZitat.getZitat());
 117:
 118:            }
 119:            System.out
 120:                    .println("Autor :  " + ((Autor) lvAutor.get(0)).getName());
 121:
 122:            // Einen neuen Autor speichern
 123:            Autor lvNeuerAutor = new Autor();
 124:            lvNeuerAutor.setName("Wenzlaff");
 125:            lvNeuerAutor.setVorname("Thomas");
 126:            lvNeuerAutor.setBeruf("IT-Berater");
 127:            lvNeuerAutor.setGebDatum(new Date());
 128:            lvNeuerAutor.setTodesDatum(new Date());
 129:            lvNeuerAutor.setBemerkung("");
 130:            sess.save(lvNeuerAutor);
 131:
 132:            // Ein neues Zitat speichern unter dem neuen Autor.
 133:            Zitat lvZitat = new Zitat();
 134:            lvZitat.setZitat("Mein neues Zitat was immer hinten ran kommt.");
 135:            lvZitat.setAutorNr(((Integer)lvNeuerAutor.getId()).intValue());
 136:            sess.save(lvZitat);
 137:
 138:
 139:
 140:            sess.flush();
 141:
 142:            trx.commit();
 143:
 144:        } catch (HibernateException ex) {
 145:            if (trx != null) try {
 146:                trx.rollback();
 147:            } catch (HibernateException exRb) {
 148:            }
 149:            throw new RuntimeException(ex.getMessage());
 150:        } finally {
 151:            try {
 152:                sess.close();
 153:            } catch (Exception exCl) {
 154:            }
 155:        }
 156:    }
 157:
 158:}

Damit das Beispiel läuft, ist die Anwendung noch zu konfigurieren. Dazu diese hibernate.cfg.xml Datei erstellen.

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

<session-factory>
    <property name="hibernate.connection.driver_class">
     	org.gjt.mm.mysql.Driver
    </property>
   <property name="hibernate.connection.url">
      jdbc:mysql://localhost:3306/twzitat
    </property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="dialect"<net.sf.hibernate.dialect.MySQLDialect</property>
    <property name="show_sql">true</property>
    <property name="transaction.factory_class">
      net.sf.hibernate.transaction.JDBCTransactionFactory
    </property>
    <property name="hibernate.cache.provider_class">
      net.sf.hibernate.cache.HashtableCacheProvider
    </property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <mapping resource="de/wenzlaff/twzitat/mapping/Autor.hbm.xml"/>
    <mapping resource="de/wenzlaff/twzitat/mapping/Zitat.hbm.xml"/>
  </session-factory>

</hibernate-configuration>

Die Hibernate Properties kann für MySQL so aussehen:

#
# TWZitat Properties
#

######################
### Query Language ###
######################

## define query language constants / function names
hibernate.query.substitutions true 1, false 0, yes 'Y', no 'N'

#################
### Platforms ###
#################

## MySQL

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class org.gjt.mm.mysql.Driver
#hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost/twzitat
hibernate.connection.username public
hibernate.connection.password public

#################################
### Hibernate Connection Pool ###
#################################

hibernate.connection.pool_size 1

##############################
### Proxool Connection Pool###
##############################

## Properties for external configuration of Proxool
hibernate.proxool.pool_alias pool1

#################################
### Plugin ConnectionProvider ###
#################################

## use a custom ConnectionProvider (if not set, Hibernate will choose a built-in ConnectionProvider using hueristics)

#hibernate.connection.provider_class net.sf.hibernate.connection.DriverManagerConnectionProvider
net.sf.hibernate.connection.DatasourceConnectionProvider

##############################
### Miscellaneous Settings ###
##############################

## print all generated SQL to the console
hibernate.show_sql true

## set the maximum JDBC 2 batch size (a nonzero value enables batching)
hibernate.jdbc.batch_size 0

## use JDBC batching for versioned data
hibernate.jdbc.batch_versioned_data true

## use streams when writing binary types to / from JDBC
hibernate.jdbc.use_streams_for_binary true

## set the maximum depth of the outer join fetch tree
hibernate.max_fetch_depth 1

##########################
### Second-level Cache ###
##########################

## set a prefix for cache region names
hibernate.cache.region_prefix hibernate.test

## enable the query cache
hibernate.cache.use_query_cache true

## choose a cache implementation
hibernate.cache.provider_class net.sf.hibernate.cache.EhCacheProvider



[Spende] - [Top] - [Home] - [Tools] - [Text] - [Suche] - [Kontakt]  RSS wenzlaff.de XML Feed [Valid Wenzlaff RSS XML feed] Valid HTML 4.0!
Copyright © 2017 by Thomas Wenzlaff. Alle Rechte vorbehalten. http://www.wenzlaff.de