From 6c59ef37a57bd10c9cf047c3d2e11094e7de4990 Mon Sep 17 00:00:00 2001 From: mynameiszp Date: Wed, 25 Oct 2023 23:28:46 +0300 Subject: [PATCH 1/6] Added user for service and repository --- .../configuration/StoreConfiguration.java | 16 ++++++ .../com/example/springlabs/model/User.java | 1 + .../repositories/UserRepository.java | 18 +++++++ .../repositories/UserRepositoryImpl.java | 54 +++++++++++++++++++ .../springlabs/services/UserService.java | 40 ++++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 src/main/java/com/example/springlabs/repositories/UserRepository.java create mode 100644 src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java create mode 100644 src/main/java/com/example/springlabs/services/UserService.java diff --git a/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java b/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java index 923a066..deaa58e 100644 --- a/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java +++ b/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java @@ -3,6 +3,7 @@ import com.example.springlabs.model.Category; import com.example.springlabs.model.Product; +import com.example.springlabs.model.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -13,10 +14,12 @@ public class StoreConfiguration { private final ArrayList categories; private final ArrayList products; + private final ArrayList users; public StoreConfiguration() { this.categories = new ArrayList<>(); this.products = new ArrayList<>(); + this.users = new ArrayList<>(); // Створюємо категорії Category category4 = new Category("Кондиціонери"); @@ -34,6 +37,10 @@ public StoreConfiguration() { Product product2 = new Product(2, "BOSH KGN39VI306", 1000.0, category3); category3.getProducts().add(product2); + //Створюємо юзерів + User user1 = new User(1, "Petro", "Petrynenko", "petro@gmail.com", "1234", true); + User user2 = new User(2, "Maria", "Ivanova", "maria@gmail.com", "11223344", false); + // Створюємо список категорій categories.add(category1); categories.add(category5); @@ -41,6 +48,10 @@ public StoreConfiguration() { // Створюємо список товарів products.add(product1); products.add(product2); + + // Створюємо список юзерів + users.add(user1); + users.add(user2); } @Bean @@ -52,4 +63,9 @@ ArrayList categories() { ArrayList products() { return products; } + + @Bean + ArrayList users() { + return users; + } } diff --git a/src/main/java/com/example/springlabs/model/User.java b/src/main/java/com/example/springlabs/model/User.java index 46ba91c..d1cb30d 100644 --- a/src/main/java/com/example/springlabs/model/User.java +++ b/src/main/java/com/example/springlabs/model/User.java @@ -7,6 +7,7 @@ @ToString @EqualsAndHashCode @NoArgsConstructor +@AllArgsConstructor public class User { private long id; private String name; diff --git a/src/main/java/com/example/springlabs/repositories/UserRepository.java b/src/main/java/com/example/springlabs/repositories/UserRepository.java new file mode 100644 index 0000000..2d62b0a --- /dev/null +++ b/src/main/java/com/example/springlabs/repositories/UserRepository.java @@ -0,0 +1,18 @@ +package com.example.springlabs.repositories; + +import com.example.springlabs.model.User; + +import java.util.List; + +public interface UserRepository { + + List getUsers(); + + void deleteUserById(int id); + + User getUserById(int id); + + void updateUser(User updatedUser); + + void addUser(User user); +} diff --git a/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java b/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java new file mode 100644 index 0000000..c4c74fa --- /dev/null +++ b/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java @@ -0,0 +1,54 @@ +package com.example.springlabs.repositories; + +import com.example.springlabs.model.User; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; + +@Repository +public class UserRepositoryImpl implements UserRepository{ + private final List users; + + public UserRepositoryImpl(ArrayList users) { + this.users = users; + } + + @Override + public List getUsers() { + return users; + } + + @Override + public void deleteUserById(int id) { + users.removeIf(user -> user.getId() == id); + } + + @Override + public User getUserById(int id) { + return users.stream() + .filter(user -> user.getId() == id) + .findFirst() + .orElse(null); + } + + @Override + public void updateUser(User updatedUser) { + for (User user : users) { + if (user.getId() == updatedUser.getId()) { + user.setName(updatedUser.getName()); + user.setSurname(updatedUser.getSurname()); + user.setEmail(updatedUser.getEmail()); + user.setPassword(updatedUser.getPassword()); + user.setAdmin(updatedUser.isAdmin()); + } + } + } + + @Override + public void addUser(User user) { + users.add(user); + } +} + + diff --git a/src/main/java/com/example/springlabs/services/UserService.java b/src/main/java/com/example/springlabs/services/UserService.java new file mode 100644 index 0000000..210dac9 --- /dev/null +++ b/src/main/java/com/example/springlabs/services/UserService.java @@ -0,0 +1,40 @@ +package com.example.springlabs.services; + +import com.example.springlabs.model.User; +import com.example.springlabs.repositories.UserRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class UserService { + private final UserRepository userRepository; + + public UserService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + public List getAllUsers() { + return userRepository.getUsers(); + } + + public User getUserById(int id) { + return userRepository.getUserById(id); + } + + public List deleteUserById(int id) { + userRepository.deleteUserById(id); + return userRepository.getUsers(); + } + + public List updateUser(User updatedUser) { + userRepository.updateUser(updatedUser); + return userRepository.getUsers(); + } + + public List addUser(User user) { + userRepository.addUser(user); + return userRepository.getUsers(); + } +} + From 9377ad0ee179e02c35c05fd872a4645ebafaeeab Mon Sep 17 00:00:00 2001 From: mynameiszp Date: Thu, 26 Oct 2023 23:58:01 +0300 Subject: [PATCH 2/6] changed int to long in signatures, inserted 'break;' --- .../example/springlabs/repositories/CategoryRepository.java | 6 +++--- .../springlabs/repositories/CategoryRepositoryImpl.java | 6 +++--- .../example/springlabs/repositories/ProductRepository.java | 4 ++-- .../springlabs/repositories/ProductRepositoryImpl.java | 4 ++-- .../com/example/springlabs/repositories/UserRepository.java | 4 ++-- .../example/springlabs/repositories/UserRepositoryImpl.java | 5 +++-- .../com/example/springlabs/services/CategoryService.java | 6 +++--- .../com/example/springlabs/services/ProductService.java | 4 ++-- .../java/com/example/springlabs/services/UserService.java | 4 ++-- 9 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/example/springlabs/repositories/CategoryRepository.java b/src/main/java/com/example/springlabs/repositories/CategoryRepository.java index 786f10d..ea31fc3 100644 --- a/src/main/java/com/example/springlabs/repositories/CategoryRepository.java +++ b/src/main/java/com/example/springlabs/repositories/CategoryRepository.java @@ -9,11 +9,11 @@ public interface CategoryRepository { void addCategory(Category category); - Category getCategoryById(int id); + Category getCategoryById(long id); ArrayList updateCategories(Category updatedCategory); - void updateCategory(int id, String newName, Category newParentCategory); + void updateCategory(long id, String newName, Category newParentCategory); - void deleteCategoryById(int id); + void deleteCategoryById(long id); } diff --git a/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java b/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java index 9e362ae..e688174 100644 --- a/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java +++ b/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java @@ -24,7 +24,7 @@ public void addCategory(Category category) { } @Override - public Category getCategoryById(int id) { + public Category getCategoryById(long id) { return categories.stream() .filter(category -> category.getId() == id) .findFirst() @@ -43,7 +43,7 @@ public ArrayList updateCategories(Category updatedCategory) { return categories; } @Override - public void updateCategory(int id, String newName, Category newParentCategory) { + public void updateCategory(long id, String newName, Category newParentCategory) { // for (Category category : categories) { // if (category.getId() == id) { // category.setName(newName); @@ -52,7 +52,7 @@ public void updateCategory(int id, String newName, Category newParentCategory) { // } } @Override - public void deleteCategoryById(int id) { + public void deleteCategoryById(long id) { categories.removeIf(category -> category.getId() == id); } } diff --git a/src/main/java/com/example/springlabs/repositories/ProductRepository.java b/src/main/java/com/example/springlabs/repositories/ProductRepository.java index ebf0229..c0a27ee 100644 --- a/src/main/java/com/example/springlabs/repositories/ProductRepository.java +++ b/src/main/java/com/example/springlabs/repositories/ProductRepository.java @@ -8,9 +8,9 @@ public interface ProductRepository { List getProducts(); - void deleteProductById(int id); + void deleteProductById(long id); - Product getProductById(int id); + Product getProductById(long id); void updateProduct(Product updatedProduct); diff --git a/src/main/java/com/example/springlabs/repositories/ProductRepositoryImpl.java b/src/main/java/com/example/springlabs/repositories/ProductRepositoryImpl.java index 057edf6..3c9dc6a 100644 --- a/src/main/java/com/example/springlabs/repositories/ProductRepositoryImpl.java +++ b/src/main/java/com/example/springlabs/repositories/ProductRepositoryImpl.java @@ -18,11 +18,11 @@ public List getProducts() { return products; } @Override - public void deleteProductById(int id) { + public void deleteProductById(long id) { products.removeIf(product -> product.getId() == id); } @Override - public Product getProductById(int id) { + public Product getProductById(long id) { return products.stream() .filter(product -> product.getId() == id) .findFirst() diff --git a/src/main/java/com/example/springlabs/repositories/UserRepository.java b/src/main/java/com/example/springlabs/repositories/UserRepository.java index 2d62b0a..bbba834 100644 --- a/src/main/java/com/example/springlabs/repositories/UserRepository.java +++ b/src/main/java/com/example/springlabs/repositories/UserRepository.java @@ -8,9 +8,9 @@ public interface UserRepository { List getUsers(); - void deleteUserById(int id); + void deleteUserById(long id); - User getUserById(int id); + User getUserById(long id); void updateUser(User updatedUser); diff --git a/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java b/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java index c4c74fa..cbc3088 100644 --- a/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java +++ b/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java @@ -20,12 +20,12 @@ public List getUsers() { } @Override - public void deleteUserById(int id) { + public void deleteUserById(long id) { users.removeIf(user -> user.getId() == id); } @Override - public User getUserById(int id) { + public User getUserById(long id) { return users.stream() .filter(user -> user.getId() == id) .findFirst() @@ -41,6 +41,7 @@ public void updateUser(User updatedUser) { user.setEmail(updatedUser.getEmail()); user.setPassword(updatedUser.getPassword()); user.setAdmin(updatedUser.isAdmin()); + break; } } } diff --git a/src/main/java/com/example/springlabs/services/CategoryService.java b/src/main/java/com/example/springlabs/services/CategoryService.java index 4ccfaa0..ca48c0d 100644 --- a/src/main/java/com/example/springlabs/services/CategoryService.java +++ b/src/main/java/com/example/springlabs/services/CategoryService.java @@ -22,17 +22,17 @@ public ArrayList getAllCategories() { return categoryRepository.getCategories(); } - public Category getCategoryById(int id) { + public Category getCategoryById(long id) { return categoryRepository.getCategoryById(id); } - public List deleteCategoryById(int id) { + public List deleteCategoryById(long id) { categoryRepository.deleteCategoryById(id); return categoryRepository.getCategories(); } - public List updateCategory(int id, String newName, Category newParentCategory){ + public List updateCategory(long id, String newName, Category newParentCategory){ categoryRepository.updateCategory(id, newName, newParentCategory); return categoryRepository.getCategories(); } diff --git a/src/main/java/com/example/springlabs/services/ProductService.java b/src/main/java/com/example/springlabs/services/ProductService.java index cc25adf..5d9f8d8 100644 --- a/src/main/java/com/example/springlabs/services/ProductService.java +++ b/src/main/java/com/example/springlabs/services/ProductService.java @@ -18,11 +18,11 @@ public List getAllProducts() { return productRepository.getProducts(); } - public Product getProductById(int id) { + public Product getProductById(long id) { return productRepository.getProductById(id); } - public List deleteProductById(int id) { + public List deleteProductById(long id) { productRepository.deleteProductById(id); return productRepository.getProducts(); } diff --git a/src/main/java/com/example/springlabs/services/UserService.java b/src/main/java/com/example/springlabs/services/UserService.java index 210dac9..40819da 100644 --- a/src/main/java/com/example/springlabs/services/UserService.java +++ b/src/main/java/com/example/springlabs/services/UserService.java @@ -18,11 +18,11 @@ public List getAllUsers() { return userRepository.getUsers(); } - public User getUserById(int id) { + public User getUserById(long id) { return userRepository.getUserById(id); } - public List deleteUserById(int id) { + public List deleteUserById(long id) { userRepository.deleteUserById(id); return userRepository.getUsers(); } From 579b241e81f91caf8c8c370050eaa5d7d3d64c9f Mon Sep 17 00:00:00 2001 From: mynameiszp Date: Wed, 6 Dec 2023 00:23:43 +0200 Subject: [PATCH 3/6] Add Spring JPA data layer --- docker-compose-db.yml | 12 ++++ pom.xml | 14 ++-- .../springlabs/SpringLabsApplication.java | 2 +- .../configuration/StoreConfiguration.java | 45 ------------- .../controllers/CategoryController.java | 18 ++--- .../example/springlabs/model/Category.java | 24 ++++--- .../com/example/springlabs/model/Product.java | 21 +++--- .../com/example/springlabs/model/User.java | 14 +++- .../repositories/CategoryRepository.java | 29 +++++--- .../repositories/CategoryRepositoryImpl.java | 67 ------------------- .../repositories/UserRepository.java | 29 ++++++-- .../repositories/UserRepositoryImpl.java | 54 --------------- .../springlabs/services/CategoryService.java | 51 +++++++------- .../springlabs/services/UserService.java | 23 ++++--- src/main/resources/application.properties | 10 ++- start.sh | 13 ++++ 16 files changed, 162 insertions(+), 264 deletions(-) create mode 100644 docker-compose-db.yml delete mode 100644 src/main/java/com/example/springlabs/configuration/StoreConfiguration.java delete mode 100644 src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java delete mode 100644 src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java create mode 100644 start.sh diff --git a/docker-compose-db.yml b/docker-compose-db.yml new file mode 100644 index 0000000..a2014aa --- /dev/null +++ b/docker-compose-db.yml @@ -0,0 +1,12 @@ +version: '3.8' +services: + web_db: + image: postgres + container_name: spring_db + environment: + - POSTGRES_DB=localdb + - POSTGRES_PASSWORD=localdb + - POSTGRES_USER=localdb + restart: always + ports: + - '5430:5432' \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9a6e07f..920a90f 100644 --- a/pom.xml +++ b/pom.xml @@ -31,11 +31,11 @@ spring-boot-starter-web - - - - - + + org.postgresql + postgresql + runtime + org.projectlombok lombok @@ -62,6 +62,10 @@ tomcat-embed-core 10.1.13 + + org.springframework.boot + spring-boot-starter-data-jpa + diff --git a/src/main/java/com/example/springlabs/SpringLabsApplication.java b/src/main/java/com/example/springlabs/SpringLabsApplication.java index 49789e9..2950473 100644 --- a/src/main/java/com/example/springlabs/SpringLabsApplication.java +++ b/src/main/java/com/example/springlabs/SpringLabsApplication.java @@ -12,7 +12,7 @@ ), servers = { @Server( - url = "http://localhost:8080", + url = "http://localhost:8081", description = "Local Development Server" ) } diff --git a/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java b/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java deleted file mode 100644 index c852a0a..0000000 --- a/src/main/java/com/example/springlabs/configuration/StoreConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.springlabs.configuration; - - -import com.example.springlabs.model.Category; -import com.example.springlabs.model.User; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.List; -import lombok.AccessLevel; -import lombok.SneakyThrows; -import lombok.experimental.FieldDefaults; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -@FieldDefaults(level = AccessLevel.PRIVATE) -public class StoreConfiguration { - - final ObjectMapper objectMapper = new ObjectMapper(); - - @Value("${path.data}") - String pathData; - - @Value("${path.users}") - String pathUsers; - - @SneakyThrows - @Bean - List categories() { - try (InputStream inputStream = new FileInputStream(pathData)) { - return objectMapper.readValue(inputStream, new TypeReference<>() {}); - } - } - - @SneakyThrows - @Bean - List users() { - try (InputStream inputStream = new FileInputStream(pathUsers)) { - return objectMapper.readValue(inputStream, new TypeReference<>() {}); - } - } -} diff --git a/src/main/java/com/example/springlabs/controllers/CategoryController.java b/src/main/java/com/example/springlabs/controllers/CategoryController.java index 07677a6..8bc460d 100644 --- a/src/main/java/com/example/springlabs/controllers/CategoryController.java +++ b/src/main/java/com/example/springlabs/controllers/CategoryController.java @@ -23,15 +23,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.util.AntPathMatcher; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.HandlerMapping; @Tag(name = "Category", description = "Operations related to categories") @@ -122,12 +114,10 @@ public CategoryDto updateCategory(HttpServletRequest request, @ApiResponses({ @ApiResponse(responseCode = "204", description = "Category was successfully deleted"), @ApiResponse(responseCode = "404", description = "Category is not found by id")}) - @DeleteMapping("/**") + @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.NO_CONTENT) - public void deleteCategory(HttpServletRequest request) { - List urlComponents = new ArrayList<>(getUrlComponents(request)); - String id = urlComponents.remove(urlComponents.size() - 1); - categoryService.deleteCategory(urlComponents, id); + public void deleteCategory(@PathVariable long id) { + categoryService.deleteCategory(id); } private List getUrlComponents(HttpServletRequest request) { diff --git a/src/main/java/com/example/springlabs/model/Category.java b/src/main/java/com/example/springlabs/model/Category.java index 7d9b064..0026520 100644 --- a/src/main/java/com/example/springlabs/model/Category.java +++ b/src/main/java/com/example/springlabs/model/Category.java @@ -5,22 +5,28 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; +import jakarta.persistence.*; +import lombok.*; + +@Entity(name = "categories") +@NamedQuery(name = "Categories.getCategoryById", + query = "SELECT u FROM categories u WHERE u.id = :id") @Getter @Setter @ToString @EqualsAndHashCode @NoArgsConstructor + public class Category implements Comparable { - private static long nextId = 10; // temporary solution for id generation - private long id = nextId++; + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private long id; + @Column(nullable = false) private String name; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Set subCategories = new TreeSet<>(); + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List products = new ArrayList<>(); public Category(String name, Set subCategories, List products) { @@ -29,10 +35,8 @@ public Category(String name, Set subCategories, List products this.products = products; } - @Override public int compareTo(Category o) { return this.name.compareTo(o.name); } -} - +} \ No newline at end of file diff --git a/src/main/java/com/example/springlabs/model/Product.java b/src/main/java/com/example/springlabs/model/Product.java index 43e5e53..e4108cc 100644 --- a/src/main/java/com/example/springlabs/model/Product.java +++ b/src/main/java/com/example/springlabs/model/Product.java @@ -1,26 +1,23 @@ package com.example.springlabs.model; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; +import jakarta.persistence.*; +import lombok.*; +@Entity @NoArgsConstructor +@AllArgsConstructor @Getter @Setter @ToString @EqualsAndHashCode public class Product { - private static long nextId = 10; // temporary solution for id generation - private long id = nextId++; + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private long id; + @Column(nullable = false) private String name; + @Column(nullable = false) private double price; - - public Product(String name, double price) { - this.name = name; - this.price = price; - } } diff --git a/src/main/java/com/example/springlabs/model/User.java b/src/main/java/com/example/springlabs/model/User.java index 2a1afb5..8d27293 100644 --- a/src/main/java/com/example/springlabs/model/User.java +++ b/src/main/java/com/example/springlabs/model/User.java @@ -1,5 +1,6 @@ package com.example.springlabs.model; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -7,6 +8,9 @@ import lombok.Setter; import lombok.ToString; +@Entity(name = "users") +@NamedQuery(name = "Users.getUserById", + query = "SELECT u FROM users u WHERE u.id = :id") @Getter @Setter @ToString @@ -14,11 +18,17 @@ @NoArgsConstructor @AllArgsConstructor public class User { - private static long nextId = 10; // temporary solution for id generation - private long id = nextId++; + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private long id; + @Column(nullable = false) private String name; + @Column(nullable = false) private String surname; + @Column(nullable = false, unique = true) private String email; + @Column(nullable = false) private String password; + @Column(nullable = false) private boolean isAdmin; } diff --git a/src/main/java/com/example/springlabs/repositories/CategoryRepository.java b/src/main/java/com/example/springlabs/repositories/CategoryRepository.java index 1c50fd3..74fe34c 100644 --- a/src/main/java/com/example/springlabs/repositories/CategoryRepository.java +++ b/src/main/java/com/example/springlabs/repositories/CategoryRepository.java @@ -1,21 +1,30 @@ package com.example.springlabs.repositories; import com.example.springlabs.model.Category; -import java.util.Collection; +import jakarta.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + import java.util.List; import java.util.Optional; -public interface CategoryRepository { - List getCategories(); - - void addCategory(Category category); +public interface CategoryRepository extends JpaRepository { - Category getCategoryById(long id); + //find by id - @NamedEntity + @Query(nativeQuery = true, name = "Categories.getCategoryById") + Category getCategoryById(@Param("id") Long id); - Optional updateCategory(long id, Category newCategory, - Collection subcategories); + // read all - jpa + List findAll(); - void deleteCategory(long id, Collection subcategories); + // Delete - @Query + @Modifying + @Transactional + @Query("DELETE FROM categories u WHERE u.id = :id") + void deleteCategory(@Param("id") Long id); - Optional getCategoryByName(String name); + @Query(value = "SELECT c FROM categories c WHERE c.name = :name", nativeQuery = true) + Optional getCategoryByName(@Param("name") String name); } diff --git a/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java b/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java deleted file mode 100644 index ffcf53f..0000000 --- a/src/main/java/com/example/springlabs/repositories/CategoryRepositoryImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.example.springlabs.repositories; - -import com.example.springlabs.model.Category; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; -import lombok.experimental.FieldDefaults; -import org.springframework.stereotype.Repository; - -@Repository -@RequiredArgsConstructor -@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) -public class CategoryRepositoryImpl implements CategoryRepository { - - List categories; - - @Override - public List getCategories() { - return categories; - } - - @Override - public void addCategory(Category category) { - categories.add(category); - } - - @Override - public Category getCategoryById(long id) { - return categories.stream() - .filter(category -> category.getId() == id) - .findFirst() - .orElse(null); - } - - @Override - public Optional updateCategory(long id, Category newCategory, - Collection subcategories) { - Collection categoriesToIterate = - subcategories.isEmpty() ? categories : subcategories; - - for (Category category : categoriesToIterate) { - if (category.getId() == id) { - category.setName(newCategory.getName()); - category.setSubCategories(newCategory.getSubCategories()); - category.setProducts(newCategory.getProducts()); - return Optional.of(category); - } - } - return Optional.empty(); - } - - @Override - public void deleteCategory(long id, Collection subcategories) { - Collection categoriesToIterate = - subcategories.isEmpty() ? categories : subcategories; - categoriesToIterate.removeIf(category -> category.getId() == id); - } - - @Override - public Optional getCategoryByName(String name) { - return categories.stream() - .filter(category -> category.getName().equals(name)) - .findFirst(); - } -} diff --git a/src/main/java/com/example/springlabs/repositories/UserRepository.java b/src/main/java/com/example/springlabs/repositories/UserRepository.java index 3135e5d..c683619 100644 --- a/src/main/java/com/example/springlabs/repositories/UserRepository.java +++ b/src/main/java/com/example/springlabs/repositories/UserRepository.java @@ -1,17 +1,32 @@ package com.example.springlabs.repositories; import com.example.springlabs.model.User; -import java.util.List; +import jakarta.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; -public interface UserRepository { +import java.util.List; - List getUsers(); +public interface UserRepository extends JpaRepository { - void deleteUserById(long id); + //find by id - @NamedEntity + @Query(nativeQuery = true, name = "Users.getUserById") + User getUserById(@Param("id") Long id); - User getUserById(long id); + // read all - jpa + List findAll(); - void updateUser(User updatedUser); + // Update - @Query + @Modifying + @Transactional + @Query("UPDATE users u SET u.name = :name, u.surname = :surname, u.email = :email, u.password = :password, u.isAdmin = :isAdmin WHERE u.id = :id") + void updateUser(@Param("id") Long id, @Param("name") String name, @Param("surname") String surname, @Param("email") String email, @Param("password") String password, @Param("isAdmin") boolean isAdmin); - void addUser(User user); + // Delete - @Query + @Modifying + @Transactional + @Query("DELETE FROM users u WHERE u.id = :id") + void deleteUserById(@Param("id") Long id); } diff --git a/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java b/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java deleted file mode 100644 index 7a643cf..0000000 --- a/src/main/java/com/example/springlabs/repositories/UserRepositoryImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.example.springlabs.repositories; - -import com.example.springlabs.model.User; -import java.util.List; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; -import lombok.experimental.FieldDefaults; -import org.springframework.stereotype.Repository; - -@Repository -@RequiredArgsConstructor -@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) -public class UserRepositoryImpl implements UserRepository{ - List users; - - @Override - public List getUsers() { - return users; - } - - @Override - public void deleteUserById(long id) { - users.removeIf(user -> user.getId() == id); - } - - @Override - public User getUserById(long id) { - return users.stream() - .filter(user -> user.getId() == id) - .findFirst() - .orElse(null); - } - - @Override - public void updateUser(User updatedUser) { - for (User user : users) { - if (user.getId() == updatedUser.getId()) { - user.setName(updatedUser.getName()); - user.setSurname(updatedUser.getSurname()); - user.setEmail(updatedUser.getEmail()); - user.setPassword(updatedUser.getPassword()); - user.setAdmin(updatedUser.isAdmin()); - break; - } - } - } - - @Override - public void addUser(User user) { - users.add(user); - } -} - - diff --git a/src/main/java/com/example/springlabs/services/CategoryService.java b/src/main/java/com/example/springlabs/services/CategoryService.java index 8d525d4..4b7145f 100644 --- a/src/main/java/com/example/springlabs/services/CategoryService.java +++ b/src/main/java/com/example/springlabs/services/CategoryService.java @@ -3,6 +3,7 @@ import com.example.springlabs.exception.CategoryNotFoundException; import com.example.springlabs.model.Category; import com.example.springlabs.repositories.CategoryRepository; +import jakarta.transaction.Transactional; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; @@ -18,15 +19,16 @@ public class CategoryService { CategoryRepository categoryRepository; - String CATEGORY_NAME_NOT_FOUND = "Category with name: %s doesn't exist!"; - String CATEGORY_ID_NOT_FOUND = "Category with id: %s doesn't exist!"; + String CATEGORY_NAME_NOT_FOUND = "Category with name: %s doesn't exist!"; + String CATEGORY_ID_NOT_FOUND = "Category with id: %s doesn't exist!"; public List getAllCategories() { - return categoryRepository.getCategories(); + return categoryRepository.findAll(); } - public Category addCategory(Category category) { - categoryRepository.addCategory(category); + @Transactional + public Category addCategory(Category category) { + categoryRepository.save(category); return category; } @@ -39,11 +41,11 @@ public Collection getSubcategories(List categoriesNames) { return getCategoryByName(categoriesNames).getSubCategories(); } - private Optional getSubcategoryByName(Category category, String name) { - return category.getSubCategories().stream() - .filter(subCategory -> subCategory.getName().equals(name)) - .findFirst(); - } + private Optional getSubcategoryByName(Category category, String name) { + return category.getSubCategories().stream() + .filter(subCategory -> subCategory.getName().equals(name)) + .findFirst(); + } public Category getCategoryByName(List categoriesNamesPath) { Optional parentCategory = categoryRepository.getCategoryByName(categoriesNamesPath.get(0)); @@ -54,31 +56,30 @@ public Category getCategoryByName(List categoriesNamesPath) { } parentCategory = getSubcategoryByName(parentCategory.get(), categoriesNamesPath.get(i)); } - return parentCategory.orElseThrow( () -> new CategoryNotFoundException( CATEGORY_NAME_NOT_FOUND.formatted(categoriesNamesPath.get(categoriesNamesPath.size() - 1)))); } + @Transactional public Category updateCategory(List categoriesNames, String stringId, Category categoryFromDto) { - long id = saveParseId(stringId); - return categoryRepository.updateCategory(id, categoryFromDto, getSubcategories(categoriesNames)) - .orElseThrow(() -> new CategoryNotFoundException(CATEGORY_ID_NOT_FOUND.formatted(stringId))); + getCategoryByName(categoriesNames); + categoryFromDto.setId(saveParseId(stringId)); + return categoryRepository.save(categoryFromDto); } - public void deleteCategory(List categoriesNames, String stringId) { - long id = saveParseId(stringId); - categoryRepository.deleteCategory(id, getSubcategories(categoriesNames)); - } + public void deleteCategory(long id) { + categoryRepository.deleteCategory(id); + } - private long saveParseId(String s) { - try { - return Long.parseLong(s); - } catch (NumberFormatException e) { - throw new CategoryNotFoundException(CATEGORY_ID_NOT_FOUND.formatted(s), e); - } - } + private long saveParseId(String s) { + try { + return Long.parseLong(s); + } catch (NumberFormatException e) { + throw new CategoryNotFoundException(CATEGORY_ID_NOT_FOUND.formatted(s), e); + } + } public Collection getAllCategories(int page, int size, String name) { Collection categories = getAllCategories().stream().filter(c -> c.getName().contains(name)).toList(); diff --git a/src/main/java/com/example/springlabs/services/UserService.java b/src/main/java/com/example/springlabs/services/UserService.java index a10659a..0410855 100644 --- a/src/main/java/com/example/springlabs/services/UserService.java +++ b/src/main/java/com/example/springlabs/services/UserService.java @@ -3,6 +3,8 @@ import com.example.springlabs.model.User; import com.example.springlabs.repositories.UserRepository; import java.util.List; + +import jakarta.transaction.Transactional; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; @@ -15,26 +17,25 @@ public class UserService { UserRepository userRepository; public List getAllUsers() { - return userRepository.getUsers(); + return userRepository.findAll(); } - public User getUserById(long id) { - return userRepository.getUserById(id); + @Transactional + public void updateUser(Long id, String name, String surname, String email, String password, boolean isAdmin) { + userRepository.updateUser(id, name, surname, email, password, isAdmin); } - public List deleteUserById(long id) { + public void deleteUserById(Long id) { userRepository.deleteUserById(id); - return userRepository.getUsers(); } - public List updateUser(User updatedUser) { - userRepository.updateUser(updatedUser); - return userRepository.getUsers(); + @Transactional + public User addUser(User user) { + return userRepository.save(user); } - public List addUser(User user) { - userRepository.addUser(user); - return userRepository.getUsers(); + public User getUserById(long id) { + return userRepository.getUserById(id); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b854b2..f27ac9c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,10 @@ path.data=src/main/resources/data.json -path.users=src/main/resources/users.json \ No newline at end of file +path.users=src/main/resources/users.json +#server.port=8081 + +spring.datasource.url=jdbc:postgresql://localhost:5430/localdb +spring.datasource.username=localdb +spring.datasource.password=localdb +spring.jpa.hibernate.ddl-auto=create +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..05f0a1e --- /dev/null +++ b/start.sh @@ -0,0 +1,13 @@ +#!/bin/bash +docker-compose -f docker-compose-db.yml -p abc up -d +sleep 10 + +#docker exec -i spring_db psql -U localdb -d localdb < src/main/resources/schema.sql +#docker exec -i spring_db psql -U localdb -d localdb < src/main/resources/data.sql + +sed -i 's|spring.datasource.url=.*|spring.datasource.url=jdbc:postgresql://localhost:5430/localdb|' src/main/resources/application.properties +sed -i 's|spring.datasource.username=.*|spring.datasource.username=localdb|' src/main/resources/application.properties +sed -i 's|spring.datasource.password=.*|spring.datasource.password=localdb|' src/main/resources/application.properties + +#./mvnw clean install -D skipTests +#java -jar target/spring-labs-0.0.1-SNAPSHOT.jar From 93f2fb287c2b1466b8fbd7d00e465a22b3413459 Mon Sep 17 00:00:00 2001 From: mynameiszp Date: Wed, 6 Dec 2023 00:27:32 +0200 Subject: [PATCH 4/6] Changed localhost server --- src/main/java/com/example/springlabs/SpringLabsApplication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/springlabs/SpringLabsApplication.java b/src/main/java/com/example/springlabs/SpringLabsApplication.java index 2950473..49789e9 100644 --- a/src/main/java/com/example/springlabs/SpringLabsApplication.java +++ b/src/main/java/com/example/springlabs/SpringLabsApplication.java @@ -12,7 +12,7 @@ ), servers = { @Server( - url = "http://localhost:8081", + url = "http://localhost:8080", description = "Local Development Server" ) } From 4721660a566f941b20946c3ec9b24d13a13b1fad Mon Sep 17 00:00:00 2001 From: mynameiszp Date: Thu, 7 Dec 2023 11:27:12 +0200 Subject: [PATCH 5/6] Requested changes Spring JPA data layer --- .../controllers/CategoryController.java | 191 +++++++++--------- .../repositories/CategoryRepository.java | 12 +- .../springlabs/services/CategoryService.java | 24 +-- .../springlabs/services/UserService.java | 1 + 4 files changed, 119 insertions(+), 109 deletions(-) diff --git a/src/main/java/com/example/springlabs/controllers/CategoryController.java b/src/main/java/com/example/springlabs/controllers/CategoryController.java index 8bc460d..6d1af7a 100644 --- a/src/main/java/com/example/springlabs/controllers/CategoryController.java +++ b/src/main/java/com/example/springlabs/controllers/CategoryController.java @@ -2,6 +2,8 @@ import com.example.springlabs.controllers.dtos.CategoryDto; import com.example.springlabs.controllers.dtos.mappers.CategoryDtoMapper; +import com.example.springlabs.exception.CategoryNotFoundException; +import com.example.springlabs.model.Category; import com.example.springlabs.services.CategoryService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -11,12 +13,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; + import java.net.URLDecoder; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; + import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; @@ -28,105 +29,109 @@ @Tag(name = "Category", description = "Operations related to categories") @RestController -@RequestMapping(value = "/categories", produces = MediaType.APPLICATION_JSON_VALUE) +@RequestMapping(value = "/categories", produces = MediaType.APPLICATION_JSON_VALUE) @RequiredArgsConstructor @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class CategoryController { - CategoryService categoryService; + CategoryService categoryService; + + CategoryDtoMapper categoryDtoMapper; - CategoryDtoMapper categoryDtoMapper; + String CATEGORY_NAME_NOT_FOUND = "Category with name: %s doesn't exist!"; - @Operation(summary = "Get all categories", description = "Returns a list of all categories.", parameters = { - @Parameter(name = "page", description = "Page number starting from 0"), - @Parameter(name = "size", description = "Size of page"), - @Parameter(name = "name", description = "Value for filtering by category name") - }) - @ApiResponse(responseCode = "200", description = "Successful given categories", - content = @Content(schema = @Schema(implementation = CategoryDto.class))) - @GetMapping - public Collection getAll(@RequestParam(value = "page", defaultValue = "0") int page, - @RequestParam(value = "size", defaultValue = "0") int size, - @RequestParam(value = "name", defaultValue = "") String name) { - return categoryDtoMapper.createDtosSet(categoryService.getAllCategories(page, size, name)); - } + @Operation(summary = "Get all categories", description = "Returns a list of all categories.", parameters = { + @Parameter(name = "page", description = "Page number starting from 0"), + @Parameter(name = "size", description = "Size of page"), + @Parameter(name = "name", description = "Value for filtering by category name") + }) + @ApiResponse(responseCode = "200", description = "Successful given categories", + content = @Content(schema = @Schema(implementation = CategoryDto.class))) + @GetMapping + public Collection getAll(@RequestParam(value = "page", defaultValue = "0") int page, + @RequestParam(value = "size", defaultValue = "0") int size, + @RequestParam(value = "name", defaultValue = "") String name) { + return categoryDtoMapper.createDtosSet(categoryService.getAllCategories(page, size, name)); + } - @Operation(summary = "Get a category by name", description = "Returns a category by its name.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successful returned category", - content = @Content(schema = @Schema(implementation = CategoryDto.class))), - @ApiResponse(responseCode = "404", description = "Category not found by name", content = @Content) - }) - @GetMapping("/**") - public CategoryDto getCategory(HttpServletRequest request) { - List urlComponents = getUrlComponents(request); - return categoryDtoMapper.createDto(categoryService.getCategoryByName(urlComponents)); - } + @Operation(summary = "Get a category by name", description = "Returns a category by its name.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successful returned category", + content = @Content(schema = @Schema(implementation = CategoryDto.class))), + @ApiResponse(responseCode = "404", description = "Category not found by name", content = @Content) + }) + @GetMapping("/**") + public CategoryDto getCategory(HttpServletRequest request) { + List urlComponents = getUrlComponents(request); + return categoryDtoMapper.createDto(categoryService.getCategoryByName(urlComponents)); + } - @Operation(summary = "Add a new category", description = "Creates a new category.") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "A new category created", content = @Content(schema = @Schema(implementation = CategoryDto.class))), - @ApiResponse(responseCode = "400", description = "Invalid request data", content = @Content) - }) - @PostMapping - @ResponseStatus(HttpStatus.CREATED) - public CategoryDto addCategory(@RequestBody CategoryDto categoryDto) { - return categoryDtoMapper.createDto( - categoryService.addCategory(categoryDtoMapper.createCategoryFromDto(categoryDto))); - } + @Operation(summary = "Add a new category", description = "Creates a new category.") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "A new category created", content = @Content(schema = @Schema(implementation = CategoryDto.class))), + @ApiResponse(responseCode = "400", description = "Invalid request data", content = @Content) + }) + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public CategoryDto addCategory(@RequestBody CategoryDto categoryDto) { + return categoryDtoMapper.createDto( + categoryService.addCategory(categoryDtoMapper.createCategoryFromDto(categoryDto))); + } - @Operation(summary = "Add a subcategory to a category", description = "Creates a new subcategory for the specified category.") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "New subcategory for the specified category created", - content = @Content(schema = @Schema(implementation = CategoryDto.class))), - @ApiResponse(responseCode = "400", description = "Invalid request data", content = @Content), - @ApiResponse(responseCode = "404", description = "Parent category is not found by name", content = @Content) - }) - @PostMapping("/**") - @ResponseStatus(HttpStatus.CREATED) - public CategoryDto addSubcategory(HttpServletRequest request, - @RequestBody CategoryDto categoryDto) { - List urlComponents = getUrlComponents(request); - return categoryDtoMapper.createDto( - categoryService.addSubcategory(urlComponents, - categoryDtoMapper.createCategoryFromDto(categoryDto))); - } + @Operation(summary = "Add a subcategory to a category", description = "Creates a new subcategory for the specified category.") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "New subcategory for the specified category created", + content = @Content(schema = @Schema(implementation = CategoryDto.class))), + @ApiResponse(responseCode = "400", description = "Invalid request data", content = @Content), + @ApiResponse(responseCode = "404", description = "Parent category is not found by name", content = @Content) + }) + @PostMapping("/**") + @ResponseStatus(HttpStatus.CREATED) + public CategoryDto addSubcategory(HttpServletRequest request, + @RequestBody CategoryDto categoryDto) { + List urlComponents = getUrlComponents(request); + Optional category = categoryService.addCategory(categoryDtoMapper.createCategoryFromDto(categoryDto), urlComponents); + if (category.isEmpty()) { + throw new CategoryNotFoundException( + CATEGORY_NAME_NOT_FOUND.formatted("Category is empty")); + } else return categoryDtoMapper.createDto(category.get()); + } - @Operation(summary = "Update a category", description = "Updates an existing category.") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "Category updated", - content = @Content(schema = @Schema(implementation = CategoryDto.class))), - @ApiResponse(responseCode = "400", description = "Invalid category or request data", content = @Content), - @ApiResponse(responseCode = "404", description = "Category is not found by id", content = @Content) - }) - @PutMapping("/**") - @ResponseStatus(HttpStatus.OK) - public CategoryDto updateCategory(HttpServletRequest request, - @RequestBody CategoryDto categoryDto) { - List urlComponents = new ArrayList<>(getUrlComponents(request)); - String id = urlComponents.remove(urlComponents.size() - 1); - return categoryDtoMapper.createDto( - categoryService.updateCategory(urlComponents, id, - categoryDtoMapper.createCategoryFromDto(categoryDto))); - } + @Operation(summary = "Update a category", description = "Updates an existing category.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "Category updated", + content = @Content(schema = @Schema(implementation = CategoryDto.class))), + @ApiResponse(responseCode = "400", description = "Invalid category or request data", content = @Content), + @ApiResponse(responseCode = "404", description = "Category is not found by id", content = @Content) + }) + @PutMapping("/**") + @ResponseStatus(HttpStatus.OK) + public CategoryDto updateCategory(HttpServletRequest request, + @RequestBody CategoryDto categoryDto) { + List urlComponents = new ArrayList<>(getUrlComponents(request)); + String id = urlComponents.remove(urlComponents.size() - 1); + return categoryDtoMapper.createDto( + categoryService.updateCategory(urlComponents, id, + categoryDtoMapper.createCategoryFromDto(categoryDto))); + } - @Operation(summary = "Delete a category", description = "Deletes an existing category.") - @ApiResponses({ - @ApiResponse(responseCode = "204", description = "Category was successfully deleted"), - @ApiResponse(responseCode = "404", description = "Category is not found by id")}) - @DeleteMapping("/{id}") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void deleteCategory(@PathVariable long id) { - categoryService.deleteCategory(id); - } + @Operation(summary = "Delete a category", description = "Deletes an existing category.") + @ApiResponses({ + @ApiResponse(responseCode = "204", description = "Category was successfully deleted"), + @ApiResponse(responseCode = "404", description = "Category is not found by id")}) + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteCategory(@PathVariable long id) { + categoryService.deleteCategory(id); + } - private List getUrlComponents(HttpServletRequest request) { - return Arrays.stream(new AntPathMatcher().extractPathWithinPattern( - request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(), - URLDecoder.decode( - request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString(), - Charset.defaultCharset())) - .split("/")) - .toList(); - } + private List getUrlComponents(HttpServletRequest request) { + return Arrays.stream(new AntPathMatcher().extractPathWithinPattern( + request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(), + URLDecoder.decode( + request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString(), + Charset.defaultCharset())) + .split("/")) + .toList(); + } } \ No newline at end of file diff --git a/src/main/java/com/example/springlabs/repositories/CategoryRepository.java b/src/main/java/com/example/springlabs/repositories/CategoryRepository.java index 74fe34c..fd00629 100644 --- a/src/main/java/com/example/springlabs/repositories/CategoryRepository.java +++ b/src/main/java/com/example/springlabs/repositories/CategoryRepository.java @@ -6,11 +6,12 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.lang.Nullable; import java.util.List; import java.util.Optional; -public interface CategoryRepository extends JpaRepository { +public interface CategoryRepository extends JpaRepository { //find by id - @NamedEntity @Query(nativeQuery = true, name = "Categories.getCategoryById") @@ -25,6 +26,13 @@ public interface CategoryRepository extends JpaRepository { @Query("DELETE FROM categories u WHERE u.id = :id") void deleteCategory(@Param("id") Long id); - @Query(value = "SELECT c FROM categories c WHERE c.name = :name", nativeQuery = true) + //getCategoryByName + @Query(value = "SELECT * FROM categories c WHERE c.name = :name", nativeQuery = true) Optional getCategoryByName(@Param("name") String name); + + //addCategory + @Transactional + @Modifying + @Query(value = "INSERT INTO categories (name, parentCategoryId) VALUES (:name, :parentId)", nativeQuery = true) + void insertCategory(@Param("name") String name, @Param("parentId") Long parentId); } diff --git a/src/main/java/com/example/springlabs/services/CategoryService.java b/src/main/java/com/example/springlabs/services/CategoryService.java index 4b7145f..791182f 100644 --- a/src/main/java/com/example/springlabs/services/CategoryService.java +++ b/src/main/java/com/example/springlabs/services/CategoryService.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; import org.springframework.stereotype.Service; + import java.util.Collection; import java.util.List; import java.util.Optional; @@ -17,28 +18,23 @@ @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class CategoryService { - CategoryRepository categoryRepository; + CategoryRepository categoryRepository; String CATEGORY_NAME_NOT_FOUND = "Category with name: %s doesn't exist!"; String CATEGORY_ID_NOT_FOUND = "Category with id: %s doesn't exist!"; - public List getAllCategories() { - return categoryRepository.findAll(); - } + public List getAllCategories() { + return categoryRepository.findAll(); + } @Transactional public Category addCategory(Category category) { - categoryRepository.save(category); - return category; - } - - public Category addSubcategory(List categoriesNames, Category categoryFromDto) { - getSubcategories(categoriesNames).add(categoryFromDto); - return categoryFromDto; - } + return categoryRepository.save(category); + } - public Collection getSubcategories(List categoriesNames) { - return getCategoryByName(categoriesNames).getSubCategories(); + public Optional addCategory(Category category, List categoriesNames) { + categoryRepository.insertCategory(category.getName(), getCategoryByName(categoriesNames).getId()); + return categoryRepository.getCategoryByName(category.getName()); } private Optional getSubcategoryByName(Category category, String name) { diff --git a/src/main/java/com/example/springlabs/services/UserService.java b/src/main/java/com/example/springlabs/services/UserService.java index 0410855..edf3a53 100644 --- a/src/main/java/com/example/springlabs/services/UserService.java +++ b/src/main/java/com/example/springlabs/services/UserService.java @@ -2,6 +2,7 @@ import com.example.springlabs.model.User; import com.example.springlabs.repositories.UserRepository; + import java.util.List; import jakarta.transaction.Transactional; From 3973243888a05616df26108175529977d249145f Mon Sep 17 00:00:00 2001 From: mynameiszp Date: Thu, 7 Dec 2023 12:43:18 +0200 Subject: [PATCH 6/6] moved some logic to CategoryService --- .../springlabs/controllers/CategoryController.java | 6 +----- .../com/example/springlabs/services/CategoryService.java | 8 ++++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/springlabs/controllers/CategoryController.java b/src/main/java/com/example/springlabs/controllers/CategoryController.java index 6d1af7a..23a28b4 100644 --- a/src/main/java/com/example/springlabs/controllers/CategoryController.java +++ b/src/main/java/com/example/springlabs/controllers/CategoryController.java @@ -90,11 +90,7 @@ public CategoryDto addCategory(@RequestBody CategoryDto categoryDto) { public CategoryDto addSubcategory(HttpServletRequest request, @RequestBody CategoryDto categoryDto) { List urlComponents = getUrlComponents(request); - Optional category = categoryService.addCategory(categoryDtoMapper.createCategoryFromDto(categoryDto), urlComponents); - if (category.isEmpty()) { - throw new CategoryNotFoundException( - CATEGORY_NAME_NOT_FOUND.formatted("Category is empty")); - } else return categoryDtoMapper.createDto(category.get()); + return categoryDtoMapper.createDto(categoryService.addCategory(categoryDtoMapper.createCategoryFromDto(categoryDto), urlComponents)); } @Operation(summary = "Update a category", description = "Updates an existing category.") diff --git a/src/main/java/com/example/springlabs/services/CategoryService.java b/src/main/java/com/example/springlabs/services/CategoryService.java index 791182f..a22e825 100644 --- a/src/main/java/com/example/springlabs/services/CategoryService.java +++ b/src/main/java/com/example/springlabs/services/CategoryService.java @@ -32,9 +32,13 @@ public Category addCategory(Category category) { return categoryRepository.save(category); } - public Optional addCategory(Category category, List categoriesNames) { + public Category addCategory(Category category, List categoriesNames) { categoryRepository.insertCategory(category.getName(), getCategoryByName(categoriesNames).getId()); - return categoryRepository.getCategoryByName(category.getName()); + Optional returnedCategory = categoryRepository.getCategoryByName(category.getName()); + if (returnedCategory.isEmpty()) { + throw new CategoryNotFoundException( + CATEGORY_NAME_NOT_FOUND.formatted("Category is empty")); + } else return returnedCategory.get(); } private Optional getSubcategoryByName(Category category, String name) {