Третья лабораторная работа. Создана сущность CountProduct для подсчета товаров в корзине вместо обозначения связи многие ко многим через collectionTable.

This commit is contained in:
ksenianeva 2023-05-15 22:04:25 +04:00
parent 69897fcfa4
commit b4574b49d9
8 changed files with 210 additions and 101 deletions

View File

@ -17,9 +17,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210' implementation 'com.h2database:h2:2.1.210'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5' implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
implementation 'org.hibernate.validator:hibernate-validator'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
} }

Binary file not shown.

View File

@ -1,7 +1,6 @@
package com.example.lab.DataBaseLab3.Models; package com.example.lab.DataBaseLab3.Models;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.persistence.criteria.CriteriaBuilder;
import java.util.*; import java.util.*;
@ -12,79 +11,37 @@ public class Cart {
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
private Long id; private Long id;
@OneToMany
private List<CountProduct> countProducts;
@OneToOne @OneToOne
private Customer customer; private Customer customer;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "carts", cascade = CascadeType.ALL )
private List<Product> products; //can't count there because of "integer not @entity"
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "cart_products_count",
joinColumns = {@JoinColumn(name = "cart_id", referencedColumnName = "id")})
@MapKeyColumn(name = "product")
@Column(name = "amount")
private Map<Product, Integer> countProducts; //count amount of products
public Cart(){} public Cart(){}
public Cart(Customer customer) { public Cart(Customer customer) {
this.countProducts = new HashMap<>(); this.countProducts = new ArrayList<>();
this.customer = customer; this.customer = customer;
} }
public List<Product> getProducts() {
return products;
}
public Map<Product,Integer> getCountProducts(){
return countProducts;
}
//изменяет ее значение если есть такой товар на +1
public void addProduct(Product product){
if(!countProducts.containsKey(product) || !products.contains(product)){
this.countProducts.put(product, 1);
this.products.add(product);
}
else{
countProducts.put(product, countProducts.get(product) + 1);
}
if (!product.getCarts().contains(this)){
product.addCart(this);
}
}
public void deleteProduct(Product product){
products.remove(product);
if (product.getCarts().contains(this)) {
product.removeCart(this);
}
countProducts.remove(product);
}
public void reduceProduct(Product product){
if (!countProducts.containsKey(product)) return;
if(countProducts.get(product)==1){
//delete the last one
deleteProduct(product);
}
else{
countProducts.put(product, countProducts.get(product) - 1);
}
}
@PreRemove @PreRemove
public void deleteThis(){ public void deleteThis(){
deleteAllProducts(); //deleteAllProducts();
this.getCustomer().setCart(null); this.getCustomer().setCart(null);
} }
public void deleteAllProducts(){ public void addCountProduct(CountProduct countProduct){
ArrayList<Product> products = new ArrayList<>(this.products); countProducts.add(countProduct);
this.countProducts.clear(); if (countProduct.getCart() != this) {
this.products.clear(); countProduct.setCart(this);
for (var product: }
products) { }
if (product.getCarts().contains(this)) product.removeCart(this);
public void deleteCountProduct(CountProduct countProduct){
countProducts.remove(countProduct);
if (countProduct.getCart() == this) {
countProduct.setCart(null);
} }
} }

View File

@ -0,0 +1,87 @@
package com.example.lab.DataBaseLab3.Models;
import jakarta.persistence.*;
import java.util.*;
@Entity
public class CountProduct {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private Integer amount;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="cart_fk")
private Cart cart;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="product_fk")
private Product product;
public CountProduct(){}
public CountProduct(Cart cart, Product product) {
this.cart = cart;
this.product = product;
this.amount = 0;
this.cart.addCountProduct(this);
this.product.addCountProduct(this);
}
public void setProduct(Product product) {
this.product = product;
if (product != null && !product.getCountProducts().contains(this)){
product.addCountProduct(this);
}
}
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
public Product getProduct() {
return product;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public void incrementAmount(){
this.amount++;
}
public void decrementAmount(){
this.amount--;
}
@PreRemove
public void deleteThis(){
if(this.product !=null) this.product.deleteCountProduct(this);
if(this.cart !=null) this.cart.deleteCountProduct(this);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
CountProduct countProducts = (CountProduct) obj;
return Objects.equals(id, countProducts.id);
}
@Override
public int hashCode(){
return Objects.hashCode(id);
}
}

View File

@ -3,7 +3,6 @@ package com.example.lab.DataBaseLab3.Models;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -15,12 +14,9 @@ public class Product {
private String name; private String name;
private float price; private float price;
@OneToMany
private List<CountProduct> countProducts;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "products_carts",
joinColumns = @JoinColumn(name = "product_fk"),
inverseJoinColumns = @JoinColumn(name = "cart_fk"))
private List<Cart> carts;
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "productCategory_fk") @JoinColumn(name = "productCategory_fk")
private ProductCategory productCategory; private ProductCategory productCategory;
@ -31,6 +27,7 @@ public class Product {
this.name = name; this.name = name;
this.price = price; this.price = price;
this.productCategory = productCategory; this.productCategory = productCategory;
this.countProducts = new ArrayList<>();
} }
public ProductCategory getProductCategory() { public ProductCategory getProductCategory() {
@ -67,40 +64,31 @@ public class Product {
return price; return price;
} }
public void addCart(Cart cart) {
carts.add(cart);
if (!cart.getProducts().contains(this)) {
cart.addProduct(this);
}
}
@PreRemove @PreRemove
public void deleteThis(){ public void deleteThis(){
deleteAllCarts(); //deleteAllCarts();
this.productCategory.getProducts().remove(this); this.productCategory.getProducts().remove(this);
} }
public void deleteAllCarts(){
ArrayList<Cart> carts = new ArrayList<>(this.carts); public List<CountProduct> getCountProducts(){
this.carts.clear(); return countProducts;
for (var cart: }
carts) {
cart.deleteProduct(this); public void addCountProduct(CountProduct countProduct){
countProducts.add(countProduct);
if (countProduct.getProduct() != this) {
countProduct.setProduct(this);
} }
} }
public void removeCart(Cart cart) { public void deleteCountProduct(CountProduct countProduct){
carts.remove(cart); countProducts.remove(countProduct);
if (cart.getProducts().contains(this)) { if (countProduct.getProduct() == this) {
cart.deleteAllProducts(); countProduct.setProduct(null);
} }
} }
public List<Cart> getCarts() {
return carts;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) return true; if (this == obj) return true;

View File

@ -2,10 +2,10 @@ package com.example.lab.DataBaseLab3.Services;
import com.example.lab.DataBaseLab3.Models.Customer; import com.example.lab.DataBaseLab3.Models.Customer;
import com.example.lab.DataBaseLab3.Models.Product; import com.example.lab.DataBaseLab3.Models.Product;
import com.example.lab.DataBaseLab3.Models.CountProduct;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.example.lab.DataBaseLab3.Models.Cart; import com.example.lab.DataBaseLab3.Models.Cart;
import java.util.List; import java.util.List;
@ -15,9 +15,11 @@ public class CartService {
private EntityManager em; private EntityManager em;
private final ProductService productService; private final ProductService productService;
private final CountProductService countProductService;
public CartService(ProductService productService){ public CartService(ProductService productService, CountProductService countProductService){
this.productService = productService; this.productService = productService;
this.countProductService = countProductService;
} }
@Transactional @Transactional
@ -61,7 +63,9 @@ public class CartService {
public Product addProduct(Long cartId, Long productId){ public Product addProduct(Long cartId, Long productId){
Product product = productService.getProduct(productId); Product product = productService.getProduct(productId);
Cart cart = getCart(cartId); Cart cart = getCart(cartId);
cart.addProduct(product); var countProduct = countProductService.getCountProduct(productId, cartId);
if(countProduct == null) countProduct = countProductService.addCountProduct(product, cart);
countProduct.incrementAmount();
em.persist(cart); em.persist(cart);
return product; return product;
} }
@ -70,7 +74,9 @@ public class CartService {
public Product deleteProduct(Long cartId, Long productId){ public Product deleteProduct(Long cartId, Long productId){
Product product = productService.getProduct(productId); Product product = productService.getProduct(productId);
Cart cart = getCart(cartId); Cart cart = getCart(cartId);
cart.deleteProduct(product); var countProduct = countProductService.getCountProduct(productId, cartId);
if(countProduct == null) return null;
countProductService.deleteCountProduct(productId,cartId);
em.persist(cart); em.persist(cart);
return product; return product;
} }
@ -79,7 +85,10 @@ public class CartService {
public Product reduceProduct(Long cartId, Long productId){ public Product reduceProduct(Long cartId, Long productId){
Product product = productService.getProduct(productId); Product product = productService.getProduct(productId);
Cart cart = getCart(cartId); Cart cart = getCart(cartId);
cart.reduceProduct(product); var countProduct = countProductService.getCountProduct(productId, cartId);
if(countProduct == null) return null;
countProduct.decrementAmount();
em.persist(countProduct);
return product; return product;
} }
} }

View File

@ -0,0 +1,68 @@
package com.example.lab.DataBaseLab3.Services;
import com.example.lab.DataBaseLab3.Models.*;
import jakarta.persistence.*;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;
import com.example.lab.DataBaseLab3.Models.Product;
import java.util.List;
@Service
public class CountProductService {
@PersistenceContext
private EntityManager em;
@Transactional
public CountProduct addCountProduct(Product product,
Cart cart){
CountProduct countProduct = new CountProduct(cart, product);
em.persist(countProduct);
return countProduct;
}
@Transactional
public CountProduct getCountProduct(long productId, long cartId){
var count = getAllCountProducts();
var countProduct = count.stream().filter(x -> x.getProduct().getId() == productId
&& x.getCart().getId() == cartId ).findFirst();
if(countProduct.isEmpty()) return null;
else return countProduct.get();
}
@Transactional
public CountProduct incrementProduct (long productId, long cartId){
CountProduct countProduct = getCountProduct(productId, cartId);
countProduct.incrementAmount();
return em.merge(countProduct);
}
@Transactional
public CountProduct decrementProduct (long productId, long cartId){
CountProduct countProduct = getCountProduct(productId, cartId);
countProduct.decrementAmount();
return em.merge(countProduct);
}
@Transactional
public CountProduct deleteCountProduct(long productId, long cartId){
final CountProduct countProduct = getCountProduct(productId, cartId);
em.remove(countProduct);
return countProduct;
}
@Transactional
public void deleteAll(){
var list = getAllCountProducts();
for (var cp:
list) {
cp.deleteThis();
em.remove(cp);
}
}
@Transactional
public List<CountProduct> getAllCountProducts(){
return em.createQuery("from CountProduct", CountProduct.class).getResultList();
}
}

View File

@ -1,13 +1,11 @@
package com.example.lab; package com.example.lab;
import com.example.lab.DataBaseLab3.Models.Cart; import com.example.lab.DataBaseLab3.Models.*;
import com.example.lab.DataBaseLab3.Models.Customer;
import com.example.lab.DataBaseLab3.Models.Product;
import com.example.lab.DataBaseLab3.Models.ProductCategory;
import com.example.lab.DataBaseLab3.Services.CartService; import com.example.lab.DataBaseLab3.Services.CartService;
import com.example.lab.DataBaseLab3.Services.CustomerService; import com.example.lab.DataBaseLab3.Services.CustomerService;
import com.example.lab.DataBaseLab3.Services.ProductCategoryService; import com.example.lab.DataBaseLab3.Services.ProductCategoryService;
import com.example.lab.DataBaseLab3.Services.ProductService; import com.example.lab.DataBaseLab3.Services.ProductService;
import com.example.lab.DataBaseLab3.Services.CountProductService;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -23,6 +21,9 @@ public class DBTests {
ProductCategoryService productCategoryService; ProductCategoryService productCategoryService;
@Autowired @Autowired
ProductService productService; ProductService productService;
@Autowired
CountProductService countProductService;
@Test @Test
void testProductCategory(){ void testProductCategory(){
@ -63,10 +64,8 @@ public class DBTests {
@Test @Test
void testCustomer(){ void testCustomer(){
cleanAll(); cleanAll();
Customer customer = customerService.addCustomer("Ivan", Customer customer = customerService.addCustomer("Ivan",
"Ivanov", "cityExample"); "Ivanov", "cityExample");
Cart cart = cartService.addCart(customer);
Assertions.assertEquals("Ivan", customerService Assertions.assertEquals("Ivan", customerService
.getCustomer(customer.getId()).getFirstName()); .getCustomer(customer.getId()).getFirstName());
Assertions.assertEquals("Ivanov", customerService Assertions.assertEquals("Ivanov", customerService
@ -101,7 +100,6 @@ public class DBTests {
Cart cart = cartService.addCart(customer); Cart cart = cartService.addCart(customer);
Assertions.assertEquals(product,cartService.addProduct(cart.getId(), product.getId())); Assertions.assertEquals(product,cartService.addProduct(cart.getId(), product.getId()));
Assertions.assertEquals(cart,cartService.getCart(cart.getId())); Assertions.assertEquals(cart,cartService.getCart(cart.getId()));
Assertions.assertEquals(product, cartService.reduceProduct(cart.getId(),product.getId())); Assertions.assertEquals(product, cartService.reduceProduct(cart.getId(),product.getId()));
Assertions.assertEquals(product, cartService.deleteProduct(cart.getId(),product.getId())); Assertions.assertEquals(product, cartService.deleteProduct(cart.getId(),product.getId()));
@ -110,6 +108,7 @@ public class DBTests {
} }
public void cleanAll(){ public void cleanAll(){
countProductService.deleteAll();
productService.deleteAllProducts(); productService.deleteAllProducts();
cartService.deleteAllCarts(); cartService.deleteAllCarts();
customerService.deleteAllCustomers(); customerService.deleteAllCustomers();