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;
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:
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