Java >> Tutoriel Java >  >> Tag >> hibernate

Exemple de clé étrangère Hibernate

1. Présentation

Dans cet article, nous présentons un exemple complet sur Hibernate Foreign Key. La clé étrangère fait référence à une colonne unique ou à un groupe de colonnes dans une table qui relient les données présentes dans une autre table via sa clé primaire. Une clé étrangère ne peut pas exister sans sa clé parente, mais l'inverse n'est pas vrai.

Exemple – Un menu peut avoir des sous-menus. Il peut être représenté sous forme de tableau comme indiqué ci-dessous où la colonne MENU_ID est la clé primaire de T_MENU table et elle agit comme clé étrangère (lien entre les deux tables) pour T_SUBMENU tableau :

Illustration de clé étrangère



Les spécifications de persistance Java proposent différentes manières de créer des mappages de clés étrangères, comme indiqué ci-dessous :

1 - Utiliser des mappages d'associations
2 - En enregistrant des collections à l'aide de @ElementCollection

Dans cet article, nous allons montrer la création de clé étrangère à l'aide du mappage d'association bidirectionnel un à plusieurs .

Mappage des associations - C'est une fonctionnalité fournie par JPA pour lier deux tables en utilisant les associations ci-dessous. Chaque association peut être unidirectionnelle ou bidirectionnelle.

Association Exemple
Un à Un Une personne peut avoir un numéro d'identification unique
Un à plusieurs Un menu peut avoir plusieurs sous-menus
Plusieurs à un De nombreux sous-menus peuvent avoir un menu parent unique (inverse de plusieurs à un)
Plusieurs à plusieurs Un étudiant peut s'inscrire à plusieurs cours et un cours peut être inscrit par plusieurs étudiants.

2. Technologies utilisées

Nous allons construire ce projet à partir de zéro en utilisant les outils et technologies suivants :

  • Éclipse
  • Démarrage de printemps 1.5.10
  • Maven
  • Oracle
  • Hiberner
  • Java 8 ou supérieur

3. Créer un projet

Nous créons un projet Spring Boot à l'aide de l'initialiseur Spring. Les étapes sont mentionnées ci-dessous :
1 - Accédez à http://start.spring.io/
2 - Sélectionnez ce qui suit :

Initialisation du projet Spring Boot

3 – Cliquez sur le bouton Générer un projet qui téléchargera un projet Maven prêt à être déployé.
4 – Extrayez le dossier Zip téléchargé et collez-le dans votre espace de travail.
5 – Ouvrez Eclipse -> Fichier -> Importer -> Maven -> Projets Maven existants et sélectionnez votre projet. Cochez la case (Ajouter le(s) projet(s) au jeu de travail). Terminer

Ce projet de printemps est prêt à être déployé et vous pouvez l'exécuter en tant qu'application Java dans Eclipse. Nous allons maintenant construire notre exemple de mappage un à plusieurs. Pour la simplicité, nous allons créer les classes Service, Repository et Model dans le même package - com.example.hibernateExample .

3.1 Configurations du projet

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>hibernateExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>hibernateExample</name>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Dépendances utilisées dans pom.xml :Spring Boot MVC(spring-boot-starter-web ), Hiberner (spring-boot-starter-data-jpa ) et jaxb-api .

application.propriétés

# create and drop tables and sequences, loads import.sql
spring.jpa.hibernate.ddl-auto=create-drop

# Oracle settings
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver.class=oracle.jdbc.driver.OracleDriver
 
# logging
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.level.org.hibernate.SQL=debug

application.properties le fichier est présent dans src/main/resources dossier d'un projet Spring Boot. Nous faisons ici des configurations Hibernate en utilisant le pilote Oracle JDBC (Puisque Oracle limite le téléchargement automatique de la dépendance OJDBC par Maven, il faut télécharger explicitement ojdbc6.jar/ojdbc7.jar du site d'Oracle et doit l'inclure dans ClassPath )

3.2 Classes de modèles - MainMenu et SubMenu

Dans cette section, nous allons concevoir notre modèle ou nos classes d'entités à l'aide des annotations fournies par JPA et Hibernate. Le framework Hibernate utilisera ces annotations pour créer des tables et leur relation de clé étrangère dans la base de données. Les variables de la classe Entity seront créées en tant que Colonnes dans la table de la base de données.

MainMenu.java

package com.example.hibernateExample;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "T_Menu")
public class MainMenu implements Serializable{
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id;
	
	private String description;
	
	@OneToMany(mappedBy="mainMenu", cascade = CascadeType.ALL)
	Set subMenu = new HashSet();

	public MainMenu() {	
	}
	
	public MainMenu(String description) {
		this.description = description;
	}

// Getters and Setters (Omitted for brevity)

MainMenu la classe est Un(Référence) côté de la relation et SubMenu la classe représente Plusieurs (propriétaires) côté de la relation comme "Un menu peut avoir plusieurs sous-menus". Dans la terminologie de la base de données, la table qui a une clé étrangère est le propriétaire du mappage d'association. Voyons en détail quelques annotations utilisées par le framework Hibernate pour créer et gérer les classes Entity.
Ligne 16 :@Entity désigne la classe en tant que classe Entity. Hibernate créera une instance de ces classes et créera également une table correspondante dans la base de données.
Ligne 17 :@Table est utilisé pour spécifier les détails de la table qui va être créée dans la base de données correspondant à la classe d'entité. name L'attribut de cette annotation permet au programmeur de créer une table avec le nom souhaité dans la base de données. Si nous ne spécifions pas cette annotation, le nom de la table sera le même que le nom de la classe d'entité.
Ligne 20 :@Id spécifiez la variable comme colonne de clé primaire pour la table de base de données.
Ligne 21 :@GeneratedValue spécifiez la stratégie de génération pour la clé primaire.
Ligne 26 :mappedBy est utilisé avec @OnetoMany côté associatif. Il indique que l'entité de ce côté est l'inverse de la relation, et le propriétaire réside dans « l'autre » entité. Il est utilisé pour créer une relation bidirectionnelle, ce qui signifie que la classe SubMenu peut également être conservée ou récupérée via la classe Menu.

mainMenu en mappedBy="mainMenu" est le champ/variable annoté ManyToOne de la classe SubMenu comme indiqué ci-dessous :

Cartographie des associations

CascadeType.ALL effectuera tous les EntityManager opérations (PERSIST, REMOVE, REFRESH, MERGE, DETACH ) aux entités/collections associées, par exemple lorsque le menu sera persistant, le sous-menu sera également persistant.

SubMenu.java

package com.example.hibernateExample;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "T_SubMenu")
public class SubMenu implements Serializable{
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id;
	
	@Column(name="SUBMENU_DESC", nullable=false, length=50)
	private String description;
	
	
	@ManyToOne
	@JoinColumn(name ="FK_MainMenuId")
	private MainMenu mainMenu;
	
	public SubMenu() {
		
	}
	
	public SubMenu(String description, MainMenu mainMenu) {
		this.description = description;
		this.mainMenu = mainMenu;
	}
// Getters and Setters (Omitted for brevity)

Classe d'entité SubMenu sera utilisé par Hibernate pour créer T_Submenu table dans la base de données. @JoinColumn l'annotation à la ligne 27 indique que cette entité est le propriétaire de la relation (qui contiendra la clé étrangère dans la perspective de la base de données). Cette annotation est toujours utilisée avec @ManyToOne côté associatif. name L'attribut est utilisé pour donner un nom logique à la colonne de clé étrangère, bien qu'il ne soit pas obligatoire.

3.3 Interface du référentiel

MainMenuRepository.java

package com.example.hibernateExample;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MainMenuRepository extends CrudRepository<MainMenu, Integer>{
	
}

Dans cette section, nous créons MainMenuRepository interface qui est une interface Marker (qui ne définit aucune méthode). Lors de l'utilisation de Spring Data, nous devons définir un dépôt interface correspondant à chaque Entité du domaine. Il étendra le CrudRepository de Spring Data interface qui déclare les opérations CRUD standard pouvant être effectuées sur une entité. Utilisation de CrudRepository l'interface nous empêchera d'écrire beaucoup de code passe-partout pour accéder à la source de données, écrire des requêtes SQL, un ensemble de résultats, etc. Elle acceptera deux paramètres :
1 - Classe d'entité correspondant à l'interface Marker.
2 - Type de données de la clé primaire définie dans la classe Entity.

3.4 Coureur

HibernateExampleApplication.java

package com.example.hibernateExample;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class HibernateExampleApplication implements CommandLineRunner
{
	 @Autowired
	   MenuService menuService;
	 
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }

        @Override
	public void run(String... args) throws Exception {
		menuService.addMenu();
	}
}

HibernateExampleApplication la classe Java implémentera CommandLineRunner interface. Cette classe est annotée avec @SpringBootApplication qui équivaut à utiliser @Configuration , @EnableAutoConfiguration , et @ComponentScan . Nous ajouterons de nouveaux menus et sous-menus dans addMenu() de la classe de service, qui est invoquée dans run() remplacé de CommandLineRunner interface.

3.5 Couche de service

Dans cette section, nous allons créer de nouveaux menus et leurs sous-menus en utilisant les méthodes fournies par le CrudRepository de Spring Data. interface. Les menus nouvellement créés et leurs sous-menus associés seront ajoutés sous forme de lignes dans T_menu et T_submenu table par le framework Hibernate.

MenuService.java

package com.example.hibernateExample;

public interface MenuService {
	public void addMenu();
}

MenuServiceImpl.java

package com.example.hibernateExample;

import java.util.HashSet;
import java.util.Set;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MenuServiceImpl implements MenuService{
	
	@Autowired
	MainMenuRepository mainMenuRepository;

	@Transactional
	public void addMenu(){
		// For User MainMenu
		 MainMenu menu1 = new MainMenu("User");
		 //Creating sub-menus for user
		 Set subMenu1 = new HashSet();
		 subMenu1.add(new SubMenu("Manager", menu1));
		 subMenu1.add(new SubMenu("Administrator", menu1));
		 subMenu1.add(new SubMenu("Student", menu1));
		 menu1.setSubMenu(subMenu1);
		 
		// For Courses MainMenu
				 MainMenu menu2 = new MainMenu("Course");
				 //Creating sub-menus for user
				 Set subMenu2 = new HashSet();
				 subMenu2.add(new SubMenu("B-Tech", menu2));
				 subMenu2.add(new SubMenu("BCA", menu2));
				 subMenu2.add(new SubMenu("MBA", menu2));
				 menu2.setSubMenu(subMenu2);
				 
		// For Department MainMenu
				 MainMenu menu3 = new MainMenu("Department");
				 //Creating sub-menus for user
				 Set subMenu3 = new HashSet();
				 subMenu3.add(new SubMenu("Accounts", menu3));
				 subMenu3.add(new SubMenu("Information Technology", menu3));
				 subMenu3.add(new SubMenu("Sports", menu3));
				 menu3.setSubMenu(subMenu3);
		
	   //Save MainMenu  
		 Set mainMenu = new HashSet();
		 mainMenu.add(menu1);
		 mainMenu.add(menu2);
		 mainMenu.add(menu3);
	   mainMenuRepository.save(mainMenu);
	     	    	
	}
}

addMenu() de MenuServiceImpl la classe ajoute 3 MainMenu nommés Cours, Département et Utilisateur et leurs sous-menus en utilisant le save() de CrudRepository .
Lors de l'exécution de ce projet en tant qu'application Java dans Eclipse, nous obtiendrons la sortie suivante où FK_MAIN_MENU_ID est la clé étrangère dans T_submenu table :

ID DESCRIPTION
1 Département
5 Cours
9 Utilisateur

ID SUBMENU_DESC FK_MAIN_MENU_ID
2 Sports 1
3 Technologie de l'information 1
4 Comptes 1
6 B-Tech 5
7 BCA 5
8 MBA 5
10 Gestionnaire 9
11 Étudiant 9
12 Administrateur 9

4. Résumé

Pour résumer, nous avons créé un projet Spring Boot qui ajoute 3 mainMenu dans T_menu tableau, c'est-à-dire Cours, Département et Utilisateur. Chaque mainMenu peut avoir plusieurs sous-menus qui sont stockés dans T_submenu table. Ces deux tables sont liées via une clé étrangère nommée FK_MAIN_MENU_ID qui est créé via un mappage bidirectionnel un à plusieurs entre MainMenu.java et SubMenu.java Classes d'entités.

5. Télécharger le code source

Ceci était un exemple de création d'une Hibernate Foreign Key.core java hibernate spring spring boot spring data

Balise Java