@ManyToMany - relacja jedno i dwukierunkowa

Relacja @ManyToMany jest to połączenie dwóch tabel za pomocą relacji trzeciej tabeli.






✅ Stworzenie tabel w bazie danych 


CREATE DATABASE IF NOT EXISTS `bazatestowa2`;

USE `bazatestowa2`;

CREATE TABLE IF NOT EXISTS recipe (

    recipe_id INT AUTO_INCREMENT,

    recipe_name VARCHAR(40) DEFAULT NULL,

    PRIMARY KEY (recipe_id)

) ENGINE=InnoDB;


CREATE TABLE IF NOT EXISTS ingredient (

    ingredient_id INT AUTO_INCREMENT,

    ingredient_name VARCHAR(40) DEFAULT NULL,

    PRIMARY KEY (ingredient_id)

) ENGINE=InnoDB;


CREATE TABLE IF NOT EXISTS recipe_ingredient (

    recipe_id int NOT NULL,

    ingredient_id int NOT NULL,

    PRIMARY KEY (recipe_id, ingredient_id),

    CONSTRAINT FK_RECIPE FOREIGN KEY (recipe_id) 

    REFERENCES recipe (recipe_id) ON DELETE NO ACTION ON UPDATE NO ACTION,

    CONSTRAINT FK_INGREDIENT FOREIGN KEY (ingredient_id) 

    REFERENCES ingredient (ingredient_id) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB;









 Stworzenie klas Entity 


👉 Entity Recipe 

package myhibernate.direction.entity;
import java.util.ArrayList;
import java.util.List;
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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "recipe")

public class Recipe {
@Id
@Column(name = "recipe_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long recipeId;

@Column(name = "recipe_name")
private String recipeName;

@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@JoinTable(name = "recipe_ingredient", joinColumns = @JoinColumn(name = "recipe_id"), inverseJoinColumns = @JoinColumn(name = "ingredient_id"))
List<Ingredient> ingredients;

public Recipe() {
}

public Recipe(String recipeName) {
this.recipeName = recipeName;
}
public String getRecipeName() {
return recipeName;
}
public void setRecipeName(String recipeName) {
this.recipeName = recipeName;
}
public List<Ingredient> getIngredients() {
return ingredients;
}
public void addIngredient(Ingredient ingredient) {
if (ingredients == null) {
ingredients = new ArrayList<Ingredient>();
}
ingredients.add(ingredient);
}
public void setIngredients(List<Ingredient> ingredients) {
this.ingredients = ingredients;
}
@Override
public String toString() {
return "Recipe [recipeId=" + recipeId + ", recipeName=" + recipeName + "]";
}
}

👉 Entity Ingredient

package myhibernate.direction.entity;
import java.util.ArrayList;
import java.util.List;
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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "ingredient")

public class Ingredient {
@Id
@Column(name = "ingredient_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long ingredientId;

@Column(name = "ingredient_name")
private String ingredientName;

@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@JoinTable(name = "recipe_ingredient", joinColumns = @JoinColumn(name = "ingredient_id"), inverseJoinColumns = @JoinColumn(name = "recipe_id"))
List<Recipe> recipes;

public Ingredient() {
}

public Ingredient(String ingredientName) {
this.ingredientName = ingredientName;
}
public String getIngredientName() {
return ingredientName;
}
public void setIngredientName(String ingredientName) {
this.ingredientName = ingredientName;
}
public List<Recipe> getRecipes() {
return recipes;
}
public void setRecipes(List<Recipe> recipes) {
this.recipes = recipes;
}

public void addRecipe(Recipe recipe) {
if (recipes == null) {
recipes = new ArrayList<Recipe>();
}

recipes.add(recipe);
}
@Override
public String toString() {
return "Ingredient [ingredientId=" + ingredientId + ", ingredientName=" + ingredientName + "]";
}
}



 Klasa testująca dodawanie obiektu


👉 Klasa testująca

package myhibernate.direction;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import myhibernate.direction.entity.Recipe;
import myhibernate.direction.entity.Ingredient;

public class AddManyToManyApp {

public static void main(String[] args) {

Configuration conf = new Configuration();
conf.configure("hibernate.cfg.xml");
conf.addAnnotatedClass(Recipe.class);
conf.addAnnotatedClass(Ingredient.class);
SessionFactory factory = conf.buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();

//create ingredients
Ingredient ingredient1 = new Ingredient("mleko");
Ingredient ingredient2 = new Ingredient("proszek do pieczenia");
Ingredient ingredient3 = new Ingredient("biały ser");
Ingredient ingredient4 = new Ingredient("czekolada");
//create recipes
Recipe recipe1 = new Recipe("sernik");
recipe1.addIngeredient(ingredient1);
recipe1.addIngeredient(ingredient2);
recipe1.addIngeredient(ingredient3);
Recipe recipe2 = new Recipe("tort czekoladowy");
recipe2.addIngeredient(ingredient1);
recipe2.addIngeredient(ingredient2);
recipe2.addIngeredient(ingredient4);

//utrwalenie obiektu w bazie
session.persist(recipe1);
session.persist(recipe2);
session.getTransaction().commit();
factory.close();
}

}


❗ Wynik działania w konsoli: 






❗Wynik w bazie danych: 

1. tabela recipe




2. tabela ingredient



3. tabela recipe_ingredient





 Klasa testująca usuwanie obiektu


❗ Aktualy stan w bazie danych:

1. tabela recipe


2. tabela ingredient



3. tabela recipe_ingredient



👉 Klasa testująca


package myhibernate.direction;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import myhibernate.direction.entity.Ingredient;
import myhibernate.direction.entity.Recipe;

public class DeleteManyToManyApp {

public static void main(String[] args) {
Configuration conf = new Configuration();
conf.configure("hibernate.cfg.xml");
conf.addAnnotatedClass(Recipe.class);
conf.addAnnotatedClass(Ingredient.class);
SessionFactory factory = conf.buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();

String sql = "select distinct r from Recipe r join fetch r.ingredients where r.recipeName= :recipeName ";
Query<Recipe> query = session.createQuery(sql);
query.setParameter("recipeName", "sernik");

Recipe recipe = query.getSingleResult();
System.out.println("Recipe istnieje w baze:" + recipe);
for(Ingredient ingredient : recipe.getIngredients()) {
System.out.println("Ingredient: " + ingredient);
//kasujemy tylko składniki należące do przepisu sernik
if (ingredient.getRecipes().size() == 1) {
System.out.println("kasuje Ingredient: " + ingredient);
session.delete(ingredient);
}
}
session.delete(recipe);
session.getTransaction().commit();
factory.close();

}

}


❗ Wynik działania w konsoli: 



❗ Wynik w bazie danych: 


1. tabela recipe


2. tabela ingredient



3. tabela recipe_ingredient







 Klasa testująca odczytywanie obiektu



❗ Aktualy stan w bazie danych:

1. tabela recipe



2. tabela ingredient



3. tabela recipe_ingredient



👉 Klasa testująca

package myhibernate.direction;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import myhibernate.direction.entity.Ingredient;
import myhibernate.direction.entity.Recipe;

public class ReadManyToManyApp {

public static void main(String[] args) {
Configuration conf = new Configuration();
conf.configure("hibernate.cfg.xml");
conf.addAnnotatedClass(Recipe.class);
conf.addAnnotatedClass(Ingredient.class);
SessionFactory factory = conf.buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();

String sql = "select distinct r from Recipe r join fetch r.ingredients ";
Query<Recipe> query = session.createQuery(sql);
for(Recipe recipe : query.list()) {
System.out.println("Recipe istnieje w baze:" + recipe);
for(Ingredient ingredient : recipe.getIngredients()) {
System.out.println("Ingredient: " + ingredient);
}
}
session.getTransaction().commit();
factory.close();

}

}


❗ Wynik działania w konsoli: 




SELECT DISTINCT recipe0_.recipe_id           AS recipe_i1_1_0_,
                ingredient2_.ingredient_id   AS ingredie1_0_1_,
                recipe0_.recipe_name         AS recipe_n2_1_0_,
                ingredient2_.ingredient_name AS ingredie2_0_1_,
                ingredient1_.recipe_id       AS recipe_i2_2_0__,
                ingredient1_.ingredient_id   AS ingredie1_2_0__
FROM   recipe recipe0_
       INNER JOIN recipe_ingredient ingredient1_
               ON recipe0_.recipe_id = ingredient1_.recipe_id
       INNER JOIN ingredient ingredient2_
               ON ingredient1_.ingredient_id = ingredient2_.ingredient_id 

Brak komentarzy:

Prześlij komentarz