Heute werden wir uns die Eins-zu-Eins-Zuordnung in Hibernate ansehen. Wir werden uns ein Beispiel für die Hibernate-Eins-zu-Eins-Zuordnung mit Annotationen und XML-Konfiguration ansehen.
Eins-zu-Eins-Zuordnung in Hibernate
Meistens stehen Datenbanktabellen miteinander in Beziehung. Es gibt viele Arten von Beziehungen – eins zu eins, eins zu viele und viele zu viele sind die grundlegenden Arten. Diese können weiterhin in unidirektionale und bidirektionale Zuordnungen unterteilt werden. Heute werden wir uns die Implementierung der Hibernate Eins-zu-Eins-Zuordnung mit XML-Konfiguration sowie mit Annotationen ansehen.
Beispiel für die Hibernate Eins-zu-Eins-Zuordnung – Datenbankeinrichtung
Zunächst müssen wir eine Eins-zu-Eins-Zuordnung in den Datenbanktabellen einrichten. Wir erstellen zwei Tabellen für unser Beispiel – Transaktion und Kunde. Beide Tabellen haben eine Eins-zu-Eins-Zuordnung. Die Transaktionstabelle ist die Primärtabelle, und wir verwenden den Fremdschlüssel in der Kundentabelle für die Eins-zu-Eins-Zuordnung. Hier ist das MySQL-Skript für dieses Tutorial. Wenn Sie eine andere Datenbank verwenden, ändern Sie das Skript entsprechend.
-- Transaktionstabelle erstellen
CREATE TABLE `Transaction` (
`txn_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`txn_date` date NOT NULL,
`txn_total` decimal(10,0) NOT NULL,
PRIMARY KEY (`txn_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
-- Kundentabelle erstellen
CREATE TABLE `Customer` (
`txn_id` int(11) unsigned NOT NULL,
`cust_name` varchar(20) NOT NULL DEFAULT '',
`cust_email` varchar(20) DEFAULT NULL,
`cust_address` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`txn_id`),
CONSTRAINT `customer_ibfk_1` FOREIGN KEY (`txn_id`) REFERENCES `Transaction` (`txn_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Das Entity-Beziehungsdiagramm (ERD) für die oben genannte Eins-zu-Eins-Zuordnung zwischen den Tabellen sieht wie auf dem folgenden Bild aus. Unsere Datenbank ist einsatzbereit, gehen wir nun zum Hibernate One-to-One-Beispielprojekt über.
Hibernate One-to-One Mapping Beispielprojektstruktur
Erstellen Sie ein einfaches Maven-Projekt in Ihrer Java-IDE, ich verwende Eclipse. Unsere abschließende Projektstruktur wird wie das folgende Bild aussehen. Zuerst werden wir uns ein XML-basiertes Hibernate One-to-One-Mapping-Beispiel ansehen und dann dasselbe mit Annotationen implementieren.
Hibernate Maven-Abhängigkeiten
Unsere abschließende pom.xml-Datei sieht folgendermaßen aus.
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.hibernate</groupId>
<artifactId>HibernateOneToOneMapping</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
</dependency>
</dependencies>
</project>
Die Abhängigkeiten beziehen sich nur auf Hibernate und den MySQL Java-Treiber. Beachten Sie, dass ich die neueste Hibernate-Version 4.3.5.Final und den MySQL Java-Treiber gemäß meiner MySQL-Datenbankserver-Version (5.0.5) verwende. Hibernate 4 verwendet JBoss-Protokollierung, die automatisch als transitive Abhängigkeit importiert wird. Sie können dies in den Maven-Abhängigkeiten des Projekts bestätigen. Wenn Sie ältere Hibernate-Versionen verwenden, müssen Sie möglicherweise slf4j-Abhängigkeiten hinzufügen.
Hibernate One-to-One Mapping Model Klassen
Die Modellklassen für das Hibernate One-to-One-Mapping, um Datenbanktabellen widerzuspiegeln, würden wie folgt aussehen.
package com.journaldev.hibernate.model;
import java.util.Date;
public class Txn {
private long id;
private Date date;
private double total;
private Customer customer;
@Override
public String toString(){
return id+", "+total+", "+customer.getName()+", "+customer.getEmail()+", "+customer.getAddress();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
package com.journaldev.hibernate.model;
public class Customer {
private long id;
private String name;
private String email;
private String address;
private Txn txn;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Txn getTxn() {
return txn;
}
public void setTxn(Txn txn) {
this.txn = txn;
}
}
Da wir eine XML-basierte Konfiguration für das Mapping verwenden, sind die obigen Modelklassen einfache POJO-Klassen oder Java Beans mit Getter-Setter-Methoden. Ich verwende den Klassennamen als Txn
, um Verwechslungen zu vermeiden, da die Hibernate-API einen Klassennamen als Transaction
hat.
Hibernate One to One Mapping Configuration
Erstellen wir Hibernate-One-to-One-Mapping-Konfigurationsdateien für die Tabellen Txn und Customer. txn.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.journaldev.hibernate.model.Txn" table="TRANSACTION" >
<id name="id" type="long">
<column name="txn_id" />
<generator class="identity" />
</id>
<property name="date" type="date">
<column name="txn_date" />
</property>
<property name="total" type="double">
<column name="txn_total" />
</property>
<one-to-one name="customer" class="com.journaldev.hibernate.model.Customer"
cascade="save-update" />
</class>
</hibernate-mapping>
Der wichtige Punkt oben ist das hibernate one-to-one
-Element für das Kundeneigenschaft. customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.journaldev.hibernate.model.Customer" table="CUSTOMER">
<id name="id" type="long">
<column name="txn_id" />
<generator class="foreign">
<param name="property">txn</param>
</generator>
</id>
<one-to-one name="txn" class="com.journaldev.hibernate.model.Txn"
constrained="true"></one-to-one>
<property name="name" type="string">
<column name="cust_name"></column>
</property>
<property name="email" type="string">
<column name="cust_email"></column>
</property>
<property name="address" type="string">
<column name="cust_address"></column>
</property>
</class>
</hibernate-mapping>
generator class=“foreign“ ist der wichtige Teil, der für die Hibernate foreign key-Implementierung verwendet wird.
Hibernate-Konfigurationsdatei
Hier ist die Hibernate-Konfigurationsdatei für die XML-basierte Hibernate-Mapping-Konfiguration. hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pankaj123</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
<property name="hibernate.connection.username">pankaj</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="txn.hbm.xml"/>
<mapping resource="customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Die Hibernate-Konfigurationsdatei ist einfach, sie enthält Datenbankverbindungsdaten und Hibernate-Mapping-Ressourcen.
Hibernate SessionFactory Utility
Hier ist das Dienstprogrammklasse zur Erstellung einer Hibernate SessionFactory-Instanz.
package com.journaldev.hibernate.util;
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 SessionFactory sessionFactory;
private static SessionFactory buildSessionFactory() {
try {
// Erstellen Sie die SessionFactory aus hibernate.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
System.out.println("Hibernate Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
if(sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
}
Das ist alles, schreiben wir ein Testprogramm, um die Hibernate-1-zu-1-Zuordnung XML-basierte Konfiguration zu testen.
Hibernate One to One Mapping XML-Konfiguration Testprogramm
In dem Hibernate-1-zu-1-Zuordnungsbeispiel-Testprogramm werden wir zuerst das Txn-Objekt erstellen und speichern. Sobald es in die Datenbank gespeichert ist, werden wir die generierte ID verwenden, um das Txn-Objekt abzurufen und es auszudrucken.
package com.journaldev.hibernate.main;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.hibernate.model.Customer;
import com.journaldev.hibernate.model.Txn;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateOneToOneMain {
public static void main(String[] args) {
Txn txn = buildDemoTransaction();
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try{
//Holen Sie sich die Sitzung
sessionFactory = HibernateUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
System.out.println("Session created");
//Transaktion starten
tx = session.beginTransaction();
//Speichern des Modellobjekts
session.save(txn);
//Transaktion bestätigen
tx.commit();
System.out.println("Transaction ID="+txn.getId());
//Holen Sie sich die gespeicherten Transaktionsdaten
printTransactionData(txn.getId(), sessionFactory);
}catch(Exception e){
System.out.println("Exception occured. "+e.getMessage());
e.printStackTrace();
}finally{
if(!sessionFactory.isClosed()){
System.out.println("Closing SessionFactory");
sessionFactory.close();
}
}
}
private static void printTransactionData(long id, SessionFactory sessionFactory) {
Session session = null;
Transaction tx = null;
try{
//Holen Sie sich die Sitzung
sessionFactory = HibernateUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
//Transaktion starten
tx = session.beginTransaction();
//Speichern des Modellobjekts
Txn txn = (Txn) session.get(Txn.class, id);
//Transaktion bestätigen
tx.commit();
System.out.println("Transaction Details=\n"+txn);
}catch(Exception e){
System.out.println("Exception occured. "+e.getMessage());
e.printStackTrace();
}
}
private static Txn buildDemoTransaction() {
Txn txn = new Txn();
txn.setDate(new Date());
txn.setTotal(100);
Customer cust = new Customer();
cust.setAddress("Bangalore, India");
cust.setEmail("[email protected]");
cust.setName("Pankaj Kumar");
txn.setCustomer(cust);
cust.setTxn(txn);
return txn;
}
}
Wenn wir nun das obige 1-zu-1-Zuordnung in Hibernate-Testprogramm ausführen, erhalten wir folgende Ausgabe.
Hibernate Configuration loaded
Hibernate serviceRegistry created
Session created
Hibernate: insert into TRANSACTION (txn_date, txn_total) values (?, ?)
Hibernate: insert into CUSTOMER (cust_name, cust_email, cust_address, txn_id) values (?, ?, ?, ?)
Transaction ID=19
Hibernate: select txn0_.txn_id as txn_id1_1_0_, txn0_.txn_date as txn_date2_1_0_, txn0_.txn_total as txn_tota3_1_0_,
customer1_.txn_id as txn_id1_0_1_, customer1_.cust_name as cust_nam2_0_1_, customer1_.cust_email as cust_ema3_0_1_,
customer1_.cust_address as cust_add4_0_1_ from TRANSACTION txn0_ left outer join CUSTOMER customer1_ on
txn0_.txn_id=customer1_.txn_id where txn0_.txn_id=?
Transaction Details=
19, 100.0, Pankaj Kumar, [email protected], Bangalore, India
Closing SessionFactory
Wie Sie sehen können, funktioniert es gut, und wir können Daten von beiden Tabellen mithilfe der Transaktions-ID abrufen. Überprüfen Sie den von Hibernate intern verwendeten SQL, um die Daten abzurufen. Es verwendet Joins, um Daten aus beiden Tabellen zu erhalten.
Hibernate One-to-One Mapping Annotation
In dem obigen Abschnitt haben wir gesehen, wie man die XML-basierte Konfiguration für das Hibernate One-to-One Mapping verwendet. Jetzt sehen wir, wie wir JPA und Hibernate Annotationen verwenden können, um dasselbe zu erreichen.
Hibernate-Konfigurationsdatei
hibernate-annotation.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pankaj123</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
<property name="hibernate.connection.username">pankaj</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<mapping class="com.journaldev.hibernate.model.Txn1"/>
<mapping class="com.journaldev.hibernate.model.Customer1"/>
</session-factory>
</hibernate-configuration>
Die Hibernate-Konfiguration ist einfach. Wie Sie sehen können, habe ich zwei Modelklassen, die wir mit Annotationen verwenden werden – Txn1
und Customer1
.
Hibernate One-to-One Mapping Annotation Beispiel Modellklassen
Für die Konfiguration der Hibernate-One-to-One-Mapping-Annotation sind die Modelklassen der wichtigste Teil. Schauen wir uns an, wie unsere Modelklassen aussehen.
package com.journaldev.hibernate.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
@Entity
@Table(name="TRANSACTION")
public class Txn1 {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="txn_id")
private long id;
@Column(name="txn_date")
private Date date;
@Column(name="txn_total")
private double total;
@OneToOne(mappedBy="txn")
@Cascade(value=org.hibernate.annotations.CascadeType.SAVE_UPDATE)
private Customer1 customer;
@Override
public String toString(){
return id+", "+total+", "+customer.getName()+", "+customer.getEmail()+", "+customer.getAddress();
}
// Getter-Setter-Methoden, aus Gründen der Klarheit ausgelassen
}
Beachten Sie, dass die meisten Annotationen aus der Java Persistence API stammen, da Hibernate sie bereitstellt. Für die Kaskadierung müssten wir jedoch die Hibernate-Annotation org.hibernate.annotations.Cascade
und das Enum org.hibernate.annotations.CascadeType
verwenden.
package com.journaldev.hibernate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name="CUSTOMER")
public class Customer1 {
@Id
@Column(name="txn_id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters={@Parameter(name="property", value="txn")})
private long id;
@Column(name="cust_name")
private String name;
@Column(name="cust_email")
private String email;
@Column(name="cust_address")
private String address;
@OneToOne
@PrimaryKeyJoinColumn
private Txn1 txn;
// Getter-Setter-Methoden
}
Beachten Sie, dass wir @GenericGenerator
verwenden müssen, damit die ID aus der Transaktion verwendet wird, anstatt sie zu generieren.
Hibernate SessionFactory Utility-Klasse
Die Erstellung der SessionFactory ist unabhängig von der Art und Weise, wie wir das Hibernate-Mapping bereitstellen. Unsere Utility-Klasse zur Erstellung der SessionFactory sieht wie folgt aus.
package com.journaldev.hibernate.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateAnnotationUtil {
private static SessionFactory sessionFactory;
private static SessionFactory buildSessionFactory() {
try {
// Erstellen der SessionFactory aus hibernate-annotation.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate-annotation.cfg.xml");
System.out.println("Hibernate Annotation Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Annotation serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
if(sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
}
Hibernate One to One Mapping Annotation Beispiel Testprogramm
Hier ist ein einfaches Testprogramm für unser Hibernate-One-to-One-Mapping-Annotation-Beispiel.
package com.journaldev.hibernate.main;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.hibernate.model.Customer1;
import com.journaldev.hibernate.model.Txn1;
import com.journaldev.hibernate.util.HibernateAnnotationUtil;
public class HibernateOneToOneAnnotationMain {
public static void main(String[] args) {
Txn1 txn = buildDemoTransaction();
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try{
//Holen Sie die Sitzung
sessionFactory = HibernateAnnotationUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
System.out.println("Session created using annotations configuration");
//Transaktion starten
tx = session.beginTransaction();
//Das Modellobjekt speichern
session.save(txn);
//Transaktion abschließen
tx.commit();
System.out.println("Annotation Example. Transaction ID="+txn.getId());
//Gespeicherte Transaktionsdaten abrufen
printTransactionData(txn.getId(), sessionFactory);
}catch(Exception e){
System.out.println("Exception occured. "+e.getMessage());
e.printStackTrace();
}finally{
if(sessionFactory != null && !sessionFactory.isClosed()){
System.out.println("Closing SessionFactory");
sessionFactory.close();
}
}
}
private static void printTransactionData(long id, SessionFactory sessionFactory) {
Session session = null;
Transaction tx = null;
try{
//Holen Sie die Sitzung
sessionFactory = HibernateAnnotationUtil.getSessionFactory();
session = sessionFactory.getCurrentSession();
//Transaktion starten
tx = session.beginTransaction();
//Das Modellobjekt speichern
Txn1 txn = (Txn1) session.get(Txn1.class, id);
//Transaktion abschließen
tx.commit();
System.out.println("Annotation Example. Transaction Details=\n"+txn);
}catch(Exception e){
System.out.println("Exception occured. "+e.getMessage());
e.printStackTrace();
}
}
private static Txn1 buildDemoTransaction() {
Txn1 txn = new Txn1();
txn.setDate(new Date());
txn.setTotal(100);
Customer1 cust = new Customer1();
cust.setAddress("San Jose, USA");
cust.setEmail("[email protected]");
cust.setName("Pankaj Kr");
txn.setCustomer(cust);
cust.setTxn(txn);
return txn;
}
}
Hier ist der Auszug, wenn wir das obige Programm ausführen.
Hibernate Annotation Configuration loaded
Hibernate Annotation serviceRegistry created
Session created using annotations configuration
Hibernate: insert into TRANSACTION (txn_date, txn_total) values (?, ?)
Hibernate: insert into CUSTOMER (cust_address, cust_email, cust_name, txn_id) values (?, ?, ?, ?)
Annotation Example. Transaction ID=20
Hibernate: select txn1x0_.txn_id as txn_id1_1_0_, txn1x0_.txn_date as txn_date2_1_0_, txn1x0_.txn_total as txn_tota3_1_0_,
customer1x1_.txn_id as txn_id1_0_1_, customer1x1_.cust_address as cust_add2_0_1_, customer1x1_.cust_email as cust_ema3_0_1_,
customer1x1_.cust_name as cust_nam4_0_1_ from TRANSACTION txn1x0_ left outer join CUSTOMER customer1x1_ on
txn1x0_.txn_id=customer1x1_.txn_id where txn1x0_.txn_id=?
Annotation Example. Transaction Details=
20, 100.0, Pankaj Kr, [email protected], San Jose, USA
Closing SessionFactory
Beachten Sie, dass die Ausgabe ähnlich der hibernate one to one XML-basierten Konfiguration ist. Das ist alles für das Hibernate One to One Mapping Beispiel, Sie können das endgültige Projekt von unten herunterladen und damit herumspielen, um mehr zu lernen.
Source:
https://www.digitalocean.com/community/tutorials/hibernate-one-to-one-mapping-example-annotation