From 2501e1fded94bb0a8bfe43686161d91dd1cfcd02 Mon Sep 17 00:00:00 2001 From: ChabVlad Date: Fri, 6 Sep 2024 12:36:44 +0400 Subject: [PATCH 1/3] hw-2, test --- pom.xml | 39 ++++++++++++++++++- .../bookstore/config/MapperConfig.java | 13 +++++++ .../bookstore/controller/BookController.java | 35 +++++++++++++++++ .../java/project/bookstore/dto/BookDto.java | 16 ++++++++ .../bookstore/dto/CreateBookRequestDto.java | 16 ++++++++ .../exception/EntityNotFoundException.java | 7 ++++ .../project/bookstore/mapper/BookMapper.java | 14 +++++++ .../bookstore/repository/BookRepository.java | 5 ++- .../repository/impl/BookRepositoryImpl.java | 18 ++++++++- .../bookstore/service/BookService.java | 8 +++- .../service/impl/BookServiceImpl.java | 20 +++++++--- 11 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 src/main/java/project/bookstore/config/MapperConfig.java create mode 100644 src/main/java/project/bookstore/controller/BookController.java create mode 100644 src/main/java/project/bookstore/dto/BookDto.java create mode 100644 src/main/java/project/bookstore/dto/CreateBookRequestDto.java create mode 100644 src/main/java/project/bookstore/exception/EntityNotFoundException.java create mode 100644 src/main/java/project/bookstore/mapper/BookMapper.java diff --git a/pom.xml b/pom.xml index 208bb5f..0584137 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent 3.3.3 - + project BookStore @@ -29,6 +29,8 @@ 17 checkstyle.xml + 0.2.0 + 1.5.5.Final @@ -66,15 +68,49 @@ mysql-connector-java 8.0.33 + + org.mapstruct + mapstruct + 1.5.5.Final + com.h2database h2 test + + org.springframework.boot + spring-boot-starter-web + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + + org.projectlombok + lombok + 1.18.32 + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + org.mapstruct + mapstruct-processor + 1.5.5.Final + + + + org.springframework.boot spring-boot-maven-plugin @@ -96,6 +132,7 @@ true true false + src diff --git a/src/main/java/project/bookstore/config/MapperConfig.java b/src/main/java/project/bookstore/config/MapperConfig.java new file mode 100644 index 0000000..3396b4b --- /dev/null +++ b/src/main/java/project/bookstore/config/MapperConfig.java @@ -0,0 +1,13 @@ +package project.bookstore.config; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.NullValueCheckStrategy; + +@org.mapstruct.MapperConfig( + componentModel = "spring", + injectionStrategy = InjectionStrategy.CONSTRUCTOR, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + implementationPackage = ".impl" +) +public class MapperConfig { +} diff --git a/src/main/java/project/bookstore/controller/BookController.java b/src/main/java/project/bookstore/controller/BookController.java new file mode 100644 index 0000000..7d5a9fd --- /dev/null +++ b/src/main/java/project/bookstore/controller/BookController.java @@ -0,0 +1,35 @@ +package project.bookstore.controller; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import project.bookstore.dto.BookDto; +import project.bookstore.dto.CreateBookRequestDto; +import project.bookstore.mapper.BookMapper; +import project.bookstore.service.BookService; + +@RequiredArgsConstructor +@RestController +@RequestMapping(value = "/books") +public class BookController { + private final BookService bookService; + private final BookMapper bookMapper; + + @GetMapping + public List getAll() { + return bookService.findAll(); + } + + @GetMapping + public BookDto getBookById(Long id) { + return bookService.getBookById(id); + } + + @PostMapping + public BookDto createBook(CreateBookRequestDto requestBookDto) { + return bookMapper.toDto(bookService.save(requestBookDto)); + } +} diff --git a/src/main/java/project/bookstore/dto/BookDto.java b/src/main/java/project/bookstore/dto/BookDto.java new file mode 100644 index 0000000..b0a29a3 --- /dev/null +++ b/src/main/java/project/bookstore/dto/BookDto.java @@ -0,0 +1,16 @@ +package project.bookstore.dto; + +import java.math.BigDecimal; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class BookDto { + private String title; + private String author; + private String isbn; + private BigDecimal price; + private String description; + private String coverImage; +} diff --git a/src/main/java/project/bookstore/dto/CreateBookRequestDto.java b/src/main/java/project/bookstore/dto/CreateBookRequestDto.java new file mode 100644 index 0000000..85ff4eb --- /dev/null +++ b/src/main/java/project/bookstore/dto/CreateBookRequestDto.java @@ -0,0 +1,16 @@ +package project.bookstore.dto; + +import java.math.BigDecimal; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CreateBookRequestDto { + private String title; + private String author; + private String isbn; + private BigDecimal price; + private String description; + private String coverImage; +} diff --git a/src/main/java/project/bookstore/exception/EntityNotFoundException.java b/src/main/java/project/bookstore/exception/EntityNotFoundException.java new file mode 100644 index 0000000..944d4d7 --- /dev/null +++ b/src/main/java/project/bookstore/exception/EntityNotFoundException.java @@ -0,0 +1,7 @@ +package project.bookstore.exception; + +public class EntityNotFoundException extends RuntimeException { + public EntityNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/project/bookstore/mapper/BookMapper.java b/src/main/java/project/bookstore/mapper/BookMapper.java new file mode 100644 index 0000000..63205dd --- /dev/null +++ b/src/main/java/project/bookstore/mapper/BookMapper.java @@ -0,0 +1,14 @@ +package project.bookstore.mapper; + +import org.mapstruct.Mapper; +import project.bookstore.config.MapperConfig; +import project.bookstore.dto.BookDto; +import project.bookstore.dto.CreateBookRequestDto; +import project.bookstore.model.Book; + +@Mapper(config = MapperConfig.class) +public interface BookMapper { + public BookDto toDto(Book book); + + public Book toModel(CreateBookRequestDto requestDto); +} diff --git a/src/main/java/project/bookstore/repository/BookRepository.java b/src/main/java/project/bookstore/repository/BookRepository.java index 253cb9b..3d2dd6f 100644 --- a/src/main/java/project/bookstore/repository/BookRepository.java +++ b/src/main/java/project/bookstore/repository/BookRepository.java @@ -1,10 +1,13 @@ package project.bookstore.repository; import java.util.List; +import project.bookstore.dto.BookDto; import project.bookstore.model.Book; public interface BookRepository { Book save(Book book); - List findAll(); + List findAll(); + + Book getBookById(Long id); } diff --git a/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java b/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java index 0599ad3..e7bc013 100644 --- a/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java +++ b/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java @@ -8,6 +8,7 @@ import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.stereotype.Repository; +import project.bookstore.exception.EntityNotFoundException; import project.bookstore.model.Book; import project.bookstore.repository.BookRepository; @@ -38,14 +39,27 @@ public Book save(Book book) { } @Override - public List findAll() { + public List findAll() { try (Session session = sessionFactory.openSession()) { CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Book.class); Root root = criteriaQuery.from(Book.class); return session.createQuery(criteriaQuery).getResultList(); } catch (Exception e) { - throw new RuntimeException("Cannot find all books", e); + throw new EntityNotFoundException("Can't found books ", e); + } + } + + @Override + public Book getBookById(Long id) { + try (Session session = sessionFactory.openSession()) { + CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Book.class); + Root root = criteriaQuery.from(Book.class); + criteriaQuery.where(criteriaBuilder.equal(root.get("id"), id)); + return session.createQuery(criteriaQuery).getSingleResult(); + } catch (Exception e) { + throw new EntityNotFoundException("Can't found book by id: " + id, e); } } } diff --git a/src/main/java/project/bookstore/service/BookService.java b/src/main/java/project/bookstore/service/BookService.java index a8ab006..9a2d827 100644 --- a/src/main/java/project/bookstore/service/BookService.java +++ b/src/main/java/project/bookstore/service/BookService.java @@ -1,10 +1,14 @@ package project.bookstore.service; import java.util.List; +import project.bookstore.dto.BookDto; +import project.bookstore.dto.CreateBookRequestDto; import project.bookstore.model.Book; public interface BookService { - Book save(Book book); + Book save(CreateBookRequestDto requestBookDto); - List findAll(); + List findAll(); + + BookDto getBookById(Long id); } diff --git a/src/main/java/project/bookstore/service/impl/BookServiceImpl.java b/src/main/java/project/bookstore/service/impl/BookServiceImpl.java index edb1683..ef0f4c4 100644 --- a/src/main/java/project/bookstore/service/impl/BookServiceImpl.java +++ b/src/main/java/project/bookstore/service/impl/BookServiceImpl.java @@ -1,24 +1,34 @@ package project.bookstore.service.impl; import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import project.bookstore.dto.BookDto; +import project.bookstore.dto.CreateBookRequestDto; +import project.bookstore.mapper.BookMapper; import project.bookstore.model.Book; import project.bookstore.repository.BookRepository; import project.bookstore.service.BookService; @Service public class BookServiceImpl implements BookService { - @Autowired private BookRepository bookRepository; + private BookMapper bookMapper; @Override - public Book save(Book book) { + public Book save(CreateBookRequestDto requestBookDto) { + Book book = bookMapper.toModel(requestBookDto); return bookRepository.save(book); } @Override - public List findAll() { - return bookRepository.findAll(); + public List findAll() { + return bookRepository.findAll().stream() + .map(bookMapper::toDto) + .toList(); + } + + @Override + public BookDto getBookById(Long id) { + return bookMapper.toDto(bookRepository.getBookById(id)); } } From 463a5153196da0293842f6388499ded445985d64 Mon Sep 17 00:00:00 2001 From: ChabVlad Date: Fri, 6 Sep 2024 14:53:04 +0400 Subject: [PATCH 2/3] BookDto,BookController, BookMapper was added --- src/main/java/project/bookstore/BookStoreApplication.java | 1 - .../java/project/bookstore/controller/BookController.java | 8 +++++--- .../java/project/bookstore/repository/BookRepository.java | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/bookstore/BookStoreApplication.java b/src/main/java/project/bookstore/BookStoreApplication.java index 497b2b6..9b4f470 100644 --- a/src/main/java/project/bookstore/BookStoreApplication.java +++ b/src/main/java/project/bookstore/BookStoreApplication.java @@ -5,7 +5,6 @@ @SpringBootApplication public class BookStoreApplication { - public static void main(String[] args) { SpringApplication.run(BookStoreApplication.class, args); } diff --git a/src/main/java/project/bookstore/controller/BookController.java b/src/main/java/project/bookstore/controller/BookController.java index 7d5a9fd..39f1e09 100644 --- a/src/main/java/project/bookstore/controller/BookController.java +++ b/src/main/java/project/bookstore/controller/BookController.java @@ -3,7 +3,9 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import project.bookstore.dto.BookDto; @@ -23,13 +25,13 @@ public List getAll() { return bookService.findAll(); } - @GetMapping - public BookDto getBookById(Long id) { + @GetMapping("/{id}") + public BookDto getBookById(@PathVariable Long id) { return bookService.getBookById(id); } @PostMapping - public BookDto createBook(CreateBookRequestDto requestBookDto) { + public BookDto createBook(@RequestBody CreateBookRequestDto requestBookDto) { return bookMapper.toDto(bookService.save(requestBookDto)); } } diff --git a/src/main/java/project/bookstore/repository/BookRepository.java b/src/main/java/project/bookstore/repository/BookRepository.java index 3d2dd6f..c08dc94 100644 --- a/src/main/java/project/bookstore/repository/BookRepository.java +++ b/src/main/java/project/bookstore/repository/BookRepository.java @@ -1,7 +1,6 @@ package project.bookstore.repository; import java.util.List; -import project.bookstore.dto.BookDto; import project.bookstore.model.Book; public interface BookRepository { From f189a30331b5e0ffb90099a4db9c8352596064ee Mon Sep 17 00:00:00 2001 From: ChabVlad Date: Fri, 6 Sep 2024 17:37:26 +0400 Subject: [PATCH 3/3] DataProcessingException added, repo modified --- .../bookstore/controller/BookController.java | 2 +- .../exception/DataProcessingException.java | 7 ++++++ .../exception/EntityNotFoundException.java | 4 +++ .../bookstore/repository/BookRepository.java | 3 ++- .../repository/impl/BookRepositoryImpl.java | 25 +++++++------------ .../service/impl/BookServiceImpl.java | 4 ++- 6 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 src/main/java/project/bookstore/exception/DataProcessingException.java diff --git a/src/main/java/project/bookstore/controller/BookController.java b/src/main/java/project/bookstore/controller/BookController.java index 39f1e09..d8fabed 100644 --- a/src/main/java/project/bookstore/controller/BookController.java +++ b/src/main/java/project/bookstore/controller/BookController.java @@ -15,7 +15,7 @@ @RequiredArgsConstructor @RestController -@RequestMapping(value = "/books") +@RequestMapping("/books") public class BookController { private final BookService bookService; private final BookMapper bookMapper; diff --git a/src/main/java/project/bookstore/exception/DataProcessingException.java b/src/main/java/project/bookstore/exception/DataProcessingException.java new file mode 100644 index 0000000..8c6e39e --- /dev/null +++ b/src/main/java/project/bookstore/exception/DataProcessingException.java @@ -0,0 +1,7 @@ +package project.bookstore.exception; + +public class DataProcessingException extends RuntimeException { + public DataProcessingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/project/bookstore/exception/EntityNotFoundException.java b/src/main/java/project/bookstore/exception/EntityNotFoundException.java index 944d4d7..ee87925 100644 --- a/src/main/java/project/bookstore/exception/EntityNotFoundException.java +++ b/src/main/java/project/bookstore/exception/EntityNotFoundException.java @@ -4,4 +4,8 @@ public class EntityNotFoundException extends RuntimeException { public EntityNotFoundException(String message, Throwable cause) { super(message, cause); } + + public EntityNotFoundException(String message) { + super(message); + } } diff --git a/src/main/java/project/bookstore/repository/BookRepository.java b/src/main/java/project/bookstore/repository/BookRepository.java index c08dc94..a09bdc6 100644 --- a/src/main/java/project/bookstore/repository/BookRepository.java +++ b/src/main/java/project/bookstore/repository/BookRepository.java @@ -1,6 +1,7 @@ package project.bookstore.repository; import java.util.List; +import java.util.Optional; import project.bookstore.model.Book; public interface BookRepository { @@ -8,5 +9,5 @@ public interface BookRepository { List findAll(); - Book getBookById(Long id); + Optional findBookById(Long id); } diff --git a/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java b/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java index e7bc013..2b3d86d 100644 --- a/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java +++ b/src/main/java/project/bookstore/repository/impl/BookRepositoryImpl.java @@ -1,14 +1,12 @@ package project.bookstore.repository.impl; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; import java.util.List; +import java.util.Optional; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.stereotype.Repository; -import project.bookstore.exception.EntityNotFoundException; +import project.bookstore.exception.DataProcessingException; import project.bookstore.model.Book; import project.bookstore.repository.BookRepository; @@ -41,25 +39,20 @@ public Book save(Book book) { @Override public List findAll() { try (Session session = sessionFactory.openSession()) { - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Book.class); - Root root = criteriaQuery.from(Book.class); - return session.createQuery(criteriaQuery).getResultList(); + return session.createQuery("FROM Book", Book.class).getResultList(); } catch (Exception e) { - throw new EntityNotFoundException("Can't found books ", e); + throw new DataProcessingException("Can't found books ", e); } } @Override - public Book getBookById(Long id) { + public Optional findBookById(Long id) { try (Session session = sessionFactory.openSession()) { - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Book.class); - Root root = criteriaQuery.from(Book.class); - criteriaQuery.where(criteriaBuilder.equal(root.get("id"), id)); - return session.createQuery(criteriaQuery).getSingleResult(); + return Optional.ofNullable(session.createQuery( + "FROM Book WHERE id = :id", Book.class) + .setParameter("id", id).uniqueResult()); } catch (Exception e) { - throw new EntityNotFoundException("Can't found book by id: " + id, e); + throw new DataProcessingException("Can't found book by id: " + id, e); } } } diff --git a/src/main/java/project/bookstore/service/impl/BookServiceImpl.java b/src/main/java/project/bookstore/service/impl/BookServiceImpl.java index ef0f4c4..0c895d2 100644 --- a/src/main/java/project/bookstore/service/impl/BookServiceImpl.java +++ b/src/main/java/project/bookstore/service/impl/BookServiceImpl.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service; import project.bookstore.dto.BookDto; import project.bookstore.dto.CreateBookRequestDto; +import project.bookstore.exception.EntityNotFoundException; import project.bookstore.mapper.BookMapper; import project.bookstore.model.Book; import project.bookstore.repository.BookRepository; @@ -29,6 +30,7 @@ public List findAll() { @Override public BookDto getBookById(Long id) { - return bookMapper.toDto(bookRepository.getBookById(id)); + return bookMapper.toDto(bookRepository.findBookById(id).orElseThrow( + () -> new EntityNotFoundException("Book not found by id: " + id))); } }