diff --git a/build.gradle b/build.gradle index 40bbb42..6833345 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,13 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'com.h2database:h2:2.1.210' + + implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5' + + implementation 'org.hibernate.validator:hibernate-validator:7.0.1.Final' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Category.java b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Category.java new file mode 100644 index 0000000..1ce20ed --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Category.java @@ -0,0 +1,53 @@ +package ru.ulstu.is.sbapp.HardwareShop.models; + +import javax.persistence.*; +import java.util.List; +import java.util.Objects; + +@Entity +public class Category { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @OneToMany(mappedBy = "category") + private List productList; + + @Column + private String name; + + public Category() { + + } + + public Category(String name) { + this.name = name; + } + + public Long getId() { return id;} + + public String getName() { return name; } + + public void setName(String name) { this.name = name; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Category category = (Category) o; + return Objects.equals(id, category.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Category{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Manufacturer.java b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Manufacturer.java new file mode 100644 index 0000000..55ca96a --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Manufacturer.java @@ -0,0 +1,62 @@ +package ru.ulstu.is.sbapp.HardwareShop.models; + +import javax.persistence.*; +import java.util.List; +import java.util.Objects; + +@Entity +public class Manufacturer { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToMany(mappedBy = "manufacturerList") + private List productList; + + @Column + private String name; + private String address; + + + public Manufacturer() { + + } + + public Manufacturer(String name, String address) { + this.name = name; + this.address = address; + } + + public Long getId() { return id;} + + public String getName() { return name; } + + public String getAddress() { return address; } + + public List getProductList() { return productList; } + public void setName(String name) { this.name = name; } + + public void setAddress(String address) { this.address = address; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Manufacturer manufacturer = (Manufacturer) o; + return Objects.equals(id, manufacturer.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Manufacturer{" + + "id=" + id + + ", name='" + name + '\'' + + ", address='" + address + '\'' + + '}'; + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Product.java b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Product.java new file mode 100644 index 0000000..b4b8927 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/models/Product.java @@ -0,0 +1,80 @@ +package ru.ulstu.is.sbapp.HardwareShop.models; + +import java.util.List; +import java.util.Objects; +import javax.persistence.*; +import javax.validation.groups.ConvertGroup; + +@Entity +public class Product { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "category_id") + private Category category; + + + @ManyToMany + @JoinTable(name = "products_manufacturers", + joinColumns = @JoinColumn(name = "product_fk"), + inverseJoinColumns = @JoinColumn(name = "manufacturer_fk")) + private List manufacturerList; + + @Column + private Integer price; + + public Product() { + + } + + public Product(Integer price) + { + this.price = price; + } + + public Long getId() { return id; } + + public Integer getPrice() { return price; } + + public void setPrice(Integer price) { this.price = price; } + + public List getManufacturerList() { return manufacturerList; } + + public Category getCategory() { return category; } + + public void addCategory(Category category) { + this.category = category; + } + + public void addManufacturer(Manufacturer manufacturer) { + manufacturerList.add(manufacturer); + } + + public void removeManufacturer(Manufacturer manufacturer) { + manufacturerList.remove(manufacturer); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product product = (Product) o; + return Objects.equals(id, product.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Product{" + + "id=" + id + + ", price='" + price + '\'' + + '}'; + } + +} diff --git a/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/CategoryService.java b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/CategoryService.java new file mode 100644 index 0000000..2acdcd1 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/CategoryService.java @@ -0,0 +1,64 @@ +package ru.ulstu.is.sbapp.HardwareShop.services; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.HardwareShop.models.Category; + +import javax.persistence.EntityManager; +import javax.persistence.EntityNotFoundException; +import javax.persistence.PersistenceContext; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; + +@Service +public class CategoryService { + @PersistenceContext + private EntityManager em; + + @Transactional + public Category addCategory(String name) { + if (!StringUtils.hasText(name)) { + throw new IllegalArgumentException("Category name is null or empty"); + } + final Category category = new Category(name); + em.persist(category); + return category; + } + + @Transactional(readOnly = true) + public Category findCategory(Long id) { + final Category category = em.find(Category.class, id); + if (category == null) { + throw new EntityNotFoundException(String.format("Category with id [%s] is not found", id)); + } + return category; + } + + @Transactional(readOnly = true) + public List findAllCategories() { + return em.createQuery("select s from Category s", Category.class) + .getResultList(); + } + + @Transactional + public Category updateCategory(Long id, String name) { + if (!StringUtils.hasText(name)) { + throw new IllegalArgumentException("Category name is null or empty"); + } + final Category currentCategory = findCategory(id); + currentCategory.setName(name); + return em.merge(currentCategory); + } + + @Transactional + public Category deleteCategory(Long id) { + final Category currentCategory = findCategory(id); + em.remove(currentCategory); + return currentCategory; + } + + @Transactional + public void deleteAllCategories() { + em.createQuery("delete from Category").executeUpdate(); + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/ManufacturerService.java b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/ManufacturerService.java new file mode 100644 index 0000000..9828a6a --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/ManufacturerService.java @@ -0,0 +1,66 @@ +package ru.ulstu.is.sbapp.HardwareShop.services; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.HardwareShop.models.Manufacturer; + + +import javax.persistence.EntityManager; +import javax.persistence.EntityNotFoundException; +import javax.persistence.PersistenceContext; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; + +@Service +public class ManufacturerService { + @PersistenceContext + private EntityManager em; + + @Transactional + public Manufacturer addManufacturer(String name, String address) { + if (!StringUtils.hasText(name) || !StringUtils.hasText(address)) { + throw new IllegalArgumentException("Manufacturer name or address is null or empty"); + } + final Manufacturer manufacturer = new Manufacturer(name, address); + em.persist(manufacturer); + return manufacturer; + } + + @Transactional(readOnly = true) + public Manufacturer findManufacturer(Long id) { + final Manufacturer manufacturer = em.find(Manufacturer.class, id); + if (manufacturer == null) { + throw new EntityNotFoundException(String.format("Manufacturer with id [%s] is not found", id)); + } + return manufacturer; + } + + @Transactional(readOnly = true) + public List findAllManufacturers() { + return em.createQuery("select s from Manufacturer s", Manufacturer.class) + .getResultList(); + } + + @Transactional + public Manufacturer updateManufacturer(Long id, String name, String address) { + if (!StringUtils.hasText(name) || !StringUtils.hasText(address)) { + throw new IllegalArgumentException("Manufacturer name or address is null or empty"); + } + final Manufacturer currentManufacturer = findManufacturer(id); + currentManufacturer.setName(name); + currentManufacturer.setName(address); + return em.merge(currentManufacturer); + } + + @Transactional + public Manufacturer deleteManufacturer(Long id) { + final Manufacturer currentManufacturer = findManufacturer(id); + em.remove(currentManufacturer); + return currentManufacturer; + } + + @Transactional + public void deleteAllManufacturers() { + em.createQuery("delete from Manufacturer").executeUpdate(); + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/ProductService.java b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/ProductService.java new file mode 100644 index 0000000..97146e0 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/HardwareShop/services/ProductService.java @@ -0,0 +1,85 @@ +package ru.ulstu.is.sbapp.HardwareShop.services; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.HardwareShop.models.Manufacturer; +import ru.ulstu.is.sbapp.HardwareShop.models.Product; + +import javax.persistence.EntityManager; +import javax.persistence.EntityNotFoundException; +import javax.persistence.PersistenceContext; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; + +@Service +public class ProductService { + @PersistenceContext + private EntityManager em; + + @Transactional + public Product addProduct(Integer price) { + if (price == 0) { + throw new IllegalArgumentException("Product price equal 0"); + } + final Product product = new Product(price); + em.persist(product); + return product; + } + + @Transactional(readOnly = true) + public Product findProduct(Long id) { + final Product product = em.find(Product.class, id); + if (product == null) { + throw new EntityNotFoundException(String.format("Product with id [%s] is not found", id)); + } + return product; + } + + @Transactional(readOnly = true) + public List findAllProducts() { + return em.createQuery("select s from Product s", Product.class) + .getResultList(); + } + + @Transactional + public Product updateProduct(Long id, Integer price) { + if (price == 0) { + throw new IllegalArgumentException("Product price equal 0"); + } + final Product currentProduct = findProduct(id); + currentProduct.setPrice(price); + return em.merge(currentProduct); + } + + @Transactional + public Product deleteProduct(Long id) { + final Product currentProduct = findProduct(id); + em.remove(currentProduct); + return currentProduct; + } + + @Transactional + public void deleteAllProducts() { + em.createQuery("delete from Product").executeUpdate(); + } + + @Transactional + public void addManufacturersToProduct(Long id, Manufacturer manufacturer) { + final Product product = findProduct(id); + if (product == null) { + throw new IllegalArgumentException("Product with id " + id + " not found"); + } + product.addManufacturer(manufacturer); + em.merge(product); + } + + @Transactional + public void removeManufacturersToProduct(Long id, Manufacturer manufacturer) { + final Product product = findProduct(id); + if (product == null) { + throw new IllegalArgumentException("Product with id " + id + " not found"); + } + product.removeManufacturer(manufacturer); + em.merge(product); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..ccc05e8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,11 @@ - +spring.main.banner-mode=off +#server.port=8080 +spring.datasource.url=jdbc:h2:file:./data +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=update +spring.h2.console.enabled=true +spring.h2.console.settings.trace=false +spring.h2.console.settings.web-allow-others=false \ No newline at end of file diff --git a/src/test/java/ru/ulstu/is/sbapp/JpaCategoryTests.java b/src/test/java/ru/ulstu/is/sbapp/JpaCategoryTests.java new file mode 100644 index 0000000..ea24f26 --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/JpaCategoryTests.java @@ -0,0 +1,63 @@ +package ru.ulstu.is.sbapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.HardwareShop.models.Category; +import ru.ulstu.is.sbapp.HardwareShop.services.CategoryService; + +import javax.persistence.EntityNotFoundException; +import java.util.List; + +@SpringBootTest +public class JpaCategoryTests { + private static final Logger log = LoggerFactory.getLogger(JpaCategoryTests.class); + + @Autowired + private CategoryService categoryService; + + @Test + void testCategoryCreate() { + categoryService.deleteAllCategories(); + final Category category = categoryService.addCategory("Электроника"); + log.info(category.toString()); + Assertions.assertNotNull(category.getId()); + } + + @Test + void testCategoryRead() { + categoryService.deleteAllCategories(); + final Category category = categoryService.addCategory("Электроника"); + log.info(category.toString()); + final Category findCategory = categoryService.findCategory(category.getId()); + log.info(findCategory.toString()); + Assertions.assertEquals(category, findCategory); + } + + @Test + void testCategoryReadNotFound() { + categoryService.deleteAllCategories(); + Assertions.assertThrows(EntityNotFoundException.class, () -> categoryService.findCategory(-1L)); + } + + @Test + void testCategoryReadAll() { + categoryService.deleteAllCategories(); + categoryService.addCategory("Электроника"); + categoryService.addCategory("Электроника 2"); + final List categoryList = categoryService.findAllCategories(); + log.info(categoryList.toString()); + Assertions.assertEquals(categoryList.size(), 2); + } + + @Test + void testCategoryReadAllEmpty() { + categoryService.deleteAllCategories(); + final List categoryList = categoryService.findAllCategories(); + log.info(categoryList.toString()); + Assertions.assertEquals(categoryList.size(), 0); + } +} diff --git a/src/test/java/ru/ulstu/is/sbapp/JpaManufacturerTests.java b/src/test/java/ru/ulstu/is/sbapp/JpaManufacturerTests.java new file mode 100644 index 0000000..76945df --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/JpaManufacturerTests.java @@ -0,0 +1,63 @@ +package ru.ulstu.is.sbapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.HardwareShop.models.Manufacturer; +import ru.ulstu.is.sbapp.HardwareShop.services.ManufacturerService; + +import javax.persistence.EntityNotFoundException; +import java.util.List; + +@SpringBootTest +public class JpaManufacturerTests { + private static final Logger log = LoggerFactory.getLogger(JpaManufacturerTests.class); + + @Autowired + private ManufacturerService manufacturerService; + + @Test + void testManufacturerCreate() { + manufacturerService.deleteAllManufacturers(); + final Manufacturer manufacturer = manufacturerService.addManufacturer("Производитель 1", "ул.Камышинская д.107"); + log.info(manufacturer.toString()); + Assertions.assertNotNull(manufacturer.getId()); + } + + @Test + void testManufacturerRead() { + manufacturerService.deleteAllManufacturers(); + final Manufacturer manufacturer = manufacturerService.addManufacturer("Производитель 1", "ул.Камышинская д.107"); + log.info(manufacturer.toString()); + final Manufacturer findManufacturer = manufacturerService.findManufacturer(manufacturer.getId()); + log.info(findManufacturer.toString()); + Assertions.assertEquals(manufacturer, findManufacturer); + } + + @Test + void testManufacturerReadNotFound() { + manufacturerService.deleteAllManufacturers(); + Assertions.assertThrows(EntityNotFoundException.class, () -> manufacturerService.findManufacturer(-1L)); + } + + @Test + void testManufacturerReadAll() { + manufacturerService.deleteAllManufacturers(); + manufacturerService.addManufacturer("Производитель 1", "ул.Камышинская д.107"); + manufacturerService.addManufacturer("Производитель 2", "ул.Камышинская д.108"); + final List manufacturerList = manufacturerService.findAllManufacturers(); + log.info(manufacturerList.toString()); + Assertions.assertEquals(manufacturerList.size(), 2); + } + + @Test + void testManufacturerReadAllEmpty() { + manufacturerService.deleteAllManufacturers(); + final List manufacturerList = manufacturerService.findAllManufacturers(); + log.info(manufacturerList.toString()); + Assertions.assertEquals(manufacturerList.size(), 0); + } +} diff --git a/src/test/java/ru/ulstu/is/sbapp/JpaProductTests.java b/src/test/java/ru/ulstu/is/sbapp/JpaProductTests.java new file mode 100644 index 0000000..ae2d976 --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/JpaProductTests.java @@ -0,0 +1,90 @@ +package ru.ulstu.is.sbapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.HardwareShop.models.Category; +import ru.ulstu.is.sbapp.HardwareShop.services.CategoryService; +import ru.ulstu.is.sbapp.HardwareShop.models.Product; +import ru.ulstu.is.sbapp.HardwareShop.services.ProductService; + +import javax.persistence.EntityNotFoundException; +import java.util.List; + +@SpringBootTest +public class JpaProductTests { + private static final Logger log = LoggerFactory.getLogger(JpaProductTests.class); + + @Autowired + private ProductService productService; + + @Autowired + private CategoryService categoryService; + + @Test + void testProductCreate() { + productService.deleteAllProducts(); + final Product product = productService.addProduct(15000); + log.info(product.toString()); + Assertions.assertNotNull(product.getId()); + } + + @Test + void testProductRead() { + productService.deleteAllProducts(); + final Product product = productService.addProduct(15000); + log.info(product.toString()); + final Product findProduct = productService.findProduct(product.getId()); + log.info(findProduct.toString()); + Assertions.assertEquals(product, findProduct); + } + + @Test + void testProductReadNotFound() { + productService.deleteAllProducts(); + Assertions.assertThrows(EntityNotFoundException.class, () -> productService.findProduct(-1L)); + } + + @Test + void testProductReadAll() { + productService.deleteAllProducts(); + productService.addProduct(15000); + productService.addProduct(20000); + final List productList = productService.findAllProducts(); + log.info(productList.toString()); + Assertions.assertEquals(productList.size(), 2); + } + + @Test + void testProductReadAllEmpty() { + productService.deleteAllProducts(); + final List productList = productService.findAllProducts(); + log.info(productList.toString()); + Assertions.assertEquals(productList.size(), 0); + } + + @Test + void testProductUpdate() { + productService.deleteAllProducts(); + final Product product = productService.addProduct(15000); + log.info(product.toString()); + productService.updateProduct(product.getId(), 20000); + log.info(product.toString()); + Assertions.assertEquals(product.getPrice(), 20000); + } + + @Test + void testProductAddCategory() { + productService.deleteAllProducts(); + final Product product = productService.addProduct(15000); + final Category category = categoryService.addCategory("Электроника"); + product.addCategory(category); + log.info(product.toString() + product.getCategory().getName()); + Assertions.assertEquals(product.getCategory().getName(), "Электроника"); + productService.deleteAllProducts(); + categoryService.deleteAllCategories(); + } +}