From fd70cbb7f3031384d19d0e04f68c4c64f1165762 Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 19 Feb 2025 18:58:53 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Spring=20Boot=20Portfolio=20Project=20?= =?UTF-8?q?=E2=80=94=20Part=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 48 ++++++++++-------- .../SpringBootBookShopApplication.java | 12 ----- .../java/org/example/config/MapperConfig.java | 13 +++++ .../example/controller/BookController.java | 31 ++++++++++++ src/main/java/org/example/dto/BookDto.java | 15 ++++++ .../org/example/dto/CreateBookRequestDto.java | 14 ++++++ .../exception/EntityNotFoundException.java | 7 +++ .../java/org/example/mapper/BookMapper.java | 13 +++++ src/main/java/org/example/model/Book.java | 26 ++++++++++ .../example/repository/BookRepository.java | 7 +++ .../repository/impl/BookRepositoryImpl.java | 49 ++++++++++++++++++- .../java/org/example/service/BookService.java | 7 +++ .../example/service/impl/BookServiceImpl.java | 37 +++++++++++++- src/main/resources/application.properties | 2 +- .../SpringBootBookShopApplicationTests.java | 5 -- 15 files changed, 246 insertions(+), 40 deletions(-) create mode 100644 src/main/java/org/example/config/MapperConfig.java create mode 100644 src/main/java/org/example/controller/BookController.java create mode 100644 src/main/java/org/example/dto/BookDto.java create mode 100644 src/main/java/org/example/dto/CreateBookRequestDto.java create mode 100644 src/main/java/org/example/exception/EntityNotFoundException.java create mode 100644 src/main/java/org/example/mapper/BookMapper.java diff --git a/pom.xml b/pom.xml index ffbd96b..4915368 100644 --- a/pom.xml +++ b/pom.xml @@ -67,33 +67,41 @@ org.springframework.boot spring-boot-starter-web + + + org.mapstruct + mapstruct + 1.6.3 + + - - - org.springframework.boot - spring-boot-maven-plugin - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.3.0 - - - compile - - check - - - + maven-compiler-plugin + 3.13.0 - ${maven.checkstyle.plugin.configLocation} - true - true - false + 11 + 11 + + + org.projectlombok + lombok + 1.18.36 + + + org.mapstruct + mapstruct-processor + 1.6.3 + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + diff --git a/src/main/java/org/example/SpringBootBookShopApplication.java b/src/main/java/org/example/SpringBootBookShopApplication.java index 48c1e9f..d7dc995 100644 --- a/src/main/java/org/example/SpringBootBookShopApplication.java +++ b/src/main/java/org/example/SpringBootBookShopApplication.java @@ -1,9 +1,7 @@ package org.example; -import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringBootBookShopApplication { @@ -11,14 +9,4 @@ public class SpringBootBookShopApplication { public static void main(String[] args) { SpringApplication.run(SpringBootBookShopApplication.class, args); } - @Bean - public CommandLineRunner commandLineRunner() { - return new CommandLineRunner() { - @Override - public void run(String... args) throws Exception { - - } - }; - } - } diff --git a/src/main/java/org/example/config/MapperConfig.java b/src/main/java/org/example/config/MapperConfig.java new file mode 100644 index 0000000..0fd0054 --- /dev/null +++ b/src/main/java/org/example/config/MapperConfig.java @@ -0,0 +1,13 @@ +package org.example.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/org/example/controller/BookController.java b/src/main/java/org/example/controller/BookController.java new file mode 100644 index 0000000..79731c2 --- /dev/null +++ b/src/main/java/org/example/controller/BookController.java @@ -0,0 +1,31 @@ +package org.example.controller; + +import lombok.RequiredArgsConstructor; +import org.example.dto.BookDto; +import org.example.dto.CreateBookRequestDto; +import org.example.service.BookService; +import org.springframework.web.bind.annotation.*; +import java.util.List; + +@RequiredArgsConstructor +@RestController +@RequestMapping(value = "/books") +public class BookController { + + private final BookService bookService; + + @GetMapping + public List getAll() { + return bookService.getAll(); + } + + @GetMapping("/{id}") + public BookDto getBookById(@PathVariable Long id) { + return bookService.getById(id); + } + + @PostMapping + public BookDto createBook(@RequestBody CreateBookRequestDto createBookRequestDto) { + return bookService.create(createBookRequestDto); + } +} diff --git a/src/main/java/org/example/dto/BookDto.java b/src/main/java/org/example/dto/BookDto.java new file mode 100644 index 0000000..3a2bf19 --- /dev/null +++ b/src/main/java/org/example/dto/BookDto.java @@ -0,0 +1,15 @@ +package org.example.dto; + +import lombok.Data; +import java.math.BigDecimal; + +@Data +public class BookDto { + private Long id; + private String title; + private String author; + private String isbn; + private BigDecimal price; + private String description; + private String coverImage; +} diff --git a/src/main/java/org/example/dto/CreateBookRequestDto.java b/src/main/java/org/example/dto/CreateBookRequestDto.java new file mode 100644 index 0000000..e3da19c --- /dev/null +++ b/src/main/java/org/example/dto/CreateBookRequestDto.java @@ -0,0 +1,14 @@ +package org.example.dto; + +import lombok.Data; +import java.math.BigDecimal; + +@Data +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/org/example/exception/EntityNotFoundException.java b/src/main/java/org/example/exception/EntityNotFoundException.java new file mode 100644 index 0000000..ac0627d --- /dev/null +++ b/src/main/java/org/example/exception/EntityNotFoundException.java @@ -0,0 +1,7 @@ +package org.example.exception; + +public class EntityNotFoundException extends RuntimeException { + public EntityNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/org/example/mapper/BookMapper.java b/src/main/java/org/example/mapper/BookMapper.java new file mode 100644 index 0000000..a91858a --- /dev/null +++ b/src/main/java/org/example/mapper/BookMapper.java @@ -0,0 +1,13 @@ +package org.example.mapper; + +import org.example.config.MapperConfig; +import org.example.dto.BookDto; +import org.example.dto.CreateBookRequestDto; +import org.example.model.Book; +import org.mapstruct.Mapper; + +@Mapper(config = MapperConfig.class) +public interface BookMapper { + BookDto toDto(Book book); + Book toModel(CreateBookRequestDto createBookRequestDto); +} diff --git a/src/main/java/org/example/model/Book.java b/src/main/java/org/example/model/Book.java index dd2094f..94564ee 100644 --- a/src/main/java/org/example/model/Book.java +++ b/src/main/java/org/example/model/Book.java @@ -1,4 +1,30 @@ package org.example.model; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Column; +import lombok.Data; +import java.math.BigDecimal; + +@Entity +@Data +@Table(name = "books") public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Column(nullable = false) + private String title; + @Column(nullable = false) + private String author; + @Column(nullable = false, unique = true) + private String isbn; + @Column(nullable = false) + private BigDecimal price; + private String description; + private String coverImage; } diff --git a/src/main/java/org/example/repository/BookRepository.java b/src/main/java/org/example/repository/BookRepository.java index b23074b..d1817f5 100644 --- a/src/main/java/org/example/repository/BookRepository.java +++ b/src/main/java/org/example/repository/BookRepository.java @@ -1,4 +1,11 @@ package org.example.repository; +import org.example.model.Book; +import java.util.List; +import java.util.Optional; + public interface BookRepository { + Book create(Book book); + List getAll(); + Optional getById(Long id); } diff --git a/src/main/java/org/example/repository/impl/BookRepositoryImpl.java b/src/main/java/org/example/repository/impl/BookRepositoryImpl.java index ef51b30..7b78e7b 100644 --- a/src/main/java/org/example/repository/impl/BookRepositoryImpl.java +++ b/src/main/java/org/example/repository/impl/BookRepositoryImpl.java @@ -1,4 +1,51 @@ package org.example.repository.impl; -public class BookRepositoryImpl { +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import lombok.RequiredArgsConstructor; +import org.example.exception.EntityNotFoundException; +import org.example.model.Book; +import org.example.repository.BookRepository; +import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + +@Repository +@RequiredArgsConstructor +public class BookRepositoryImpl implements BookRepository { + + private final EntityManagerFactory entityManagerFactory; + + @Override + public Book create(Book book) { + EntityTransaction transaction = null; + try (EntityManager entityManager = entityManagerFactory.createEntityManager()) { + transaction = entityManager.getTransaction(); + transaction.begin(); + entityManager.persist(book); + transaction.commit(); + return book; + } catch (EntityNotFoundException e) { + if (transaction != null && transaction.isActive()) { + transaction.rollback(); + } + throw e; + } + } + + @Override + public List getAll() { + try (EntityManager entityManager = entityManagerFactory.createEntityManager()) { + return entityManager.createQuery("SELECT e FROM Book e", Book.class).getResultList(); + } + } + + @Override + public Optional getById(Long id) { + try (EntityManager entityManager = entityManagerFactory.createEntityManager()) { + Book book = entityManager.find(Book.class, id); + return book != null ? Optional.of(book) : Optional.empty(); + } + } } diff --git a/src/main/java/org/example/service/BookService.java b/src/main/java/org/example/service/BookService.java index e8a91ce..32d8f2c 100644 --- a/src/main/java/org/example/service/BookService.java +++ b/src/main/java/org/example/service/BookService.java @@ -1,4 +1,11 @@ package org.example.service; +import org.example.dto.BookDto; +import org.example.dto.CreateBookRequestDto; +import java.util.List; + public interface BookService { + BookDto create(CreateBookRequestDto createBookRequestDto); + List getAll(); + BookDto getById(Long id); } diff --git a/src/main/java/org/example/service/impl/BookServiceImpl.java b/src/main/java/org/example/service/impl/BookServiceImpl.java index 66e8c38..f4d3b48 100644 --- a/src/main/java/org/example/service/impl/BookServiceImpl.java +++ b/src/main/java/org/example/service/impl/BookServiceImpl.java @@ -1,4 +1,39 @@ package org.example.service.impl; -public class BookServiceImpl { +import lombok.RequiredArgsConstructor; +import org.example.dto.BookDto; +import org.example.dto.CreateBookRequestDto; +import org.example.mapper.BookMapper; +import org.example.model.Book; +import org.example.repository.BookRepository; +import org.example.service.BookService; +import org.springframework.stereotype.Service; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class BookServiceImpl implements BookService { + private final BookRepository bookRepository; + private final BookMapper bookMapper; + + @Override + public BookDto create(CreateBookRequestDto createBookRequestDto) { + Book book = bookMapper.toModel(createBookRequestDto); + Book savedBook = bookRepository.create(book); + return bookMapper.toDto(savedBook); + } + + @Override + public List getAll() { + return bookRepository.getAll().stream() + .map(bookMapper::toDto) + .toList(); + } + + @Override + public BookDto getById(Long id) { + Book book = bookRepository.getById(id).orElseThrow( + () -> new RuntimeException("Book not found" + id)); + return bookMapper.toDto(book); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 89c3eb7..41746e8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ -spring.datasource.url=jdbc:mysql://localhost:3306/svitlana?serverTimezone=UTC +spring.datasource.url=jdbc:mysql://localhost:3306/lombok?serverTimezone=UTC spring.datasource.username=root spring.datasource.password=Wetuop34! spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver diff --git a/src/test/java/org/example/SpringBootBookShopApplicationTests.java b/src/test/java/org/example/SpringBootBookShopApplicationTests.java index e491a4d..cb2c0bf 100644 --- a/src/test/java/org/example/SpringBootBookShopApplicationTests.java +++ b/src/test/java/org/example/SpringBootBookShopApplicationTests.java @@ -1,13 +1,8 @@ package org.example; -import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class SpringBootBookShopApplicationTests { - @Test - void contextLoads() { - } - } From 575e562ef77166d44b25893bc9ca207490d06284 Mon Sep 17 00:00:00 2001 From: Artur Date: Fri, 21 Feb 2025 15:40:04 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Spring=20Boot=20Portfolio=20Project=20?= =?UTF-8?q?=E2=80=94=20Part=203.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 62 ++++++++++--------- .../example/controller/BookController.java | 18 +++++- .../exception/BookNotFoundException.java | 7 +++ .../example/exception/BookSaveException.java | 7 +++ .../exception/BookValidationException.java | 7 +++ src/main/java/org/example/model/Book.java | 7 +++ .../example/repository/BookRepository.java | 23 +++++-- .../repository/impl/BookRepositoryImpl.java | 51 --------------- .../java/org/example/service/BookService.java | 8 ++- .../example/service/impl/BookServiceImpl.java | 47 +++++++++++--- src/main/resources/application.properties | 5 +- .../db.changelog/changes/01-test.yaml | 5 ++ .../db.changelog/db.changelog-master.yaml | 3 + src/main/resources/liquibase.properties | 7 +++ 14 files changed, 153 insertions(+), 104 deletions(-) create mode 100644 src/main/java/org/example/exception/BookNotFoundException.java create mode 100644 src/main/java/org/example/exception/BookSaveException.java create mode 100644 src/main/java/org/example/exception/BookValidationException.java delete mode 100644 src/main/java/org/example/repository/impl/BookRepositoryImpl.java create mode 100644 src/main/resources/db.changelog/changes/01-test.yaml create mode 100644 src/main/resources/db.changelog/db.changelog-master.yaml create mode 100644 src/main/resources/liquibase.properties diff --git a/pom.xml b/pom.xml index 4915368..59f6b0b 100644 --- a/pom.xml +++ b/pom.xml @@ -2,49 +2,40 @@ 4.0.0 + org.springframework.boot spring-boot-starter-parent 3.4.1 + org.example SpringBoot-BookShop 0.0.1-SNAPSHOT SpringBoot-BookShop SpringBoot-BookShop - - - - - - - - - - - - - + 17 checkstyle.xml + org.springframework.boot - spring-boot-starter + spring-boot-starter-web org.springframework.boot - spring-boot-starter-test - test + spring-boot-starter-data-jpa org.springframework.boot - spring-boot-starter-data-jpa + spring-boot-starter-test + test @@ -63,17 +54,17 @@ 6.2.7.Final - - org.springframework.boot - spring-boot-starter-web - - org.mapstruct mapstruct 1.6.3 + + org.liquibase + liquibase-core + 4.23.0 + @@ -83,8 +74,8 @@ maven-compiler-plugin 3.13.0 - 11 - 11 + 17 + 17 org.projectlombok @@ -96,15 +87,26 @@ mapstruct-processor 1.6.3 - - org.projectlombok - lombok-mapstruct-binding - 0.2.0 - + + + org.liquibase + liquibase-maven-plugin + 4.23.0 + + + process-resources + + src/main/resources/liquibase.properties + + + update + + + + - diff --git a/src/main/java/org/example/controller/BookController.java b/src/main/java/org/example/controller/BookController.java index 79731c2..2f4cf54 100644 --- a/src/main/java/org/example/controller/BookController.java +++ b/src/main/java/org/example/controller/BookController.java @@ -4,6 +4,7 @@ import org.example.dto.BookDto; import org.example.dto.CreateBookRequestDto; import org.example.service.BookService; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -16,16 +17,27 @@ public class BookController { @GetMapping public List getAll() { - return bookService.getAll(); + return bookService.findAll(); } @GetMapping("/{id}") public BookDto getBookById(@PathVariable Long id) { - return bookService.getById(id); + return bookService.findById(id); } @PostMapping public BookDto createBook(@RequestBody CreateBookRequestDto createBookRequestDto) { - return bookService.create(createBookRequestDto); + return bookService.save(createBookRequestDto); + } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping("/{id}") + public void deleteBookById(@PathVariable Long id) { + bookService.deleteById(id); + } + + @PutMapping("/{id}") + public void updateBookById(@PathVariable Long id, @RequestBody BookDto bookDto) { + bookService.updateBookById(id, bookDto); } } diff --git a/src/main/java/org/example/exception/BookNotFoundException.java b/src/main/java/org/example/exception/BookNotFoundException.java new file mode 100644 index 0000000..aca5f3e --- /dev/null +++ b/src/main/java/org/example/exception/BookNotFoundException.java @@ -0,0 +1,7 @@ +package org.example.exception; + +public class BookNotFoundException extends RuntimeException { + public BookNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/org/example/exception/BookSaveException.java b/src/main/java/org/example/exception/BookSaveException.java new file mode 100644 index 0000000..07a9142 --- /dev/null +++ b/src/main/java/org/example/exception/BookSaveException.java @@ -0,0 +1,7 @@ +package org.example.exception; + +public class BookSaveException extends RuntimeException { + public BookSaveException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/example/exception/BookValidationException.java b/src/main/java/org/example/exception/BookValidationException.java new file mode 100644 index 0000000..1ac75ff --- /dev/null +++ b/src/main/java/org/example/exception/BookValidationException.java @@ -0,0 +1,7 @@ +package org.example.exception; + +public class BookValidationException extends RuntimeException { + public BookValidationException(String message) { + super(message); + } +} diff --git a/src/main/java/org/example/model/Book.java b/src/main/java/org/example/model/Book.java index 94564ee..f636aae 100644 --- a/src/main/java/org/example/model/Book.java +++ b/src/main/java/org/example/model/Book.java @@ -7,10 +7,15 @@ import jakarta.persistence.Table; import jakarta.persistence.Column; import lombok.Data; +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.Where; + import java.math.BigDecimal; @Entity @Data +@SQLDelete(sql = "UPDATE books SET is_deleted = TRUE WHERE id=?") +@Where(clause = "is_deleted=false") @Table(name = "books") public class Book { @@ -27,4 +32,6 @@ public class Book { private BigDecimal price; private String description; private String coverImage; + @Column(nullable = false) + private boolean isDeleted = false; } diff --git a/src/main/java/org/example/repository/BookRepository.java b/src/main/java/org/example/repository/BookRepository.java index d1817f5..5cb6f40 100644 --- a/src/main/java/org/example/repository/BookRepository.java +++ b/src/main/java/org/example/repository/BookRepository.java @@ -1,11 +1,22 @@ package org.example.repository; import org.example.model.Book; -import java.util.List; -import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; -public interface BookRepository { - Book create(Book book); - List getAll(); - Optional getById(Long id); +import java.math.BigDecimal; + +public interface BookRepository extends JpaRepository { + + @Modifying + @Query("UPDATE Book b SET " + + " b.title = :title," + + " b.author = :author," + + " b.isbn = :isbn," + + " b.price = :price," + + " b.description = :description," + + " b.coverImage = :coverImage WHERE b.id = :id AND b.isDeleted = false") + void updateBookById(Long id, String title, String author, String isbn, + BigDecimal price, String description, String coverImage); } diff --git a/src/main/java/org/example/repository/impl/BookRepositoryImpl.java b/src/main/java/org/example/repository/impl/BookRepositoryImpl.java deleted file mode 100644 index 7b78e7b..0000000 --- a/src/main/java/org/example/repository/impl/BookRepositoryImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.example.repository.impl; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import lombok.RequiredArgsConstructor; -import org.example.exception.EntityNotFoundException; -import org.example.model.Book; -import org.example.repository.BookRepository; -import org.springframework.stereotype.Repository; -import java.util.List; -import java.util.Optional; - -@Repository -@RequiredArgsConstructor -public class BookRepositoryImpl implements BookRepository { - - private final EntityManagerFactory entityManagerFactory; - - @Override - public Book create(Book book) { - EntityTransaction transaction = null; - try (EntityManager entityManager = entityManagerFactory.createEntityManager()) { - transaction = entityManager.getTransaction(); - transaction.begin(); - entityManager.persist(book); - transaction.commit(); - return book; - } catch (EntityNotFoundException e) { - if (transaction != null && transaction.isActive()) { - transaction.rollback(); - } - throw e; - } - } - - @Override - public List getAll() { - try (EntityManager entityManager = entityManagerFactory.createEntityManager()) { - return entityManager.createQuery("SELECT e FROM Book e", Book.class).getResultList(); - } - } - - @Override - public Optional getById(Long id) { - try (EntityManager entityManager = entityManagerFactory.createEntityManager()) { - Book book = entityManager.find(Book.class, id); - return book != null ? Optional.of(book) : Optional.empty(); - } - } -} diff --git a/src/main/java/org/example/service/BookService.java b/src/main/java/org/example/service/BookService.java index 32d8f2c..872b954 100644 --- a/src/main/java/org/example/service/BookService.java +++ b/src/main/java/org/example/service/BookService.java @@ -5,7 +5,9 @@ import java.util.List; public interface BookService { - BookDto create(CreateBookRequestDto createBookRequestDto); - List getAll(); - BookDto getById(Long id); + BookDto save(CreateBookRequestDto createBookRequestDto); + List findAll(); + BookDto findById(Long id); + void deleteById(Long id); + void updateBookById(Long id, BookDto bookDto); } diff --git a/src/main/java/org/example/service/impl/BookServiceImpl.java b/src/main/java/org/example/service/impl/BookServiceImpl.java index f4d3b48..6ab4785 100644 --- a/src/main/java/org/example/service/impl/BookServiceImpl.java +++ b/src/main/java/org/example/service/impl/BookServiceImpl.java @@ -3,6 +3,9 @@ import lombok.RequiredArgsConstructor; import org.example.dto.BookDto; import org.example.dto.CreateBookRequestDto; +import org.example.exception.BookNotFoundException; +import org.example.exception.BookSaveException; +import org.example.exception.BookValidationException; import org.example.mapper.BookMapper; import org.example.model.Book; import org.example.repository.BookRepository; @@ -17,23 +20,49 @@ public class BookServiceImpl implements BookService { private final BookMapper bookMapper; @Override - public BookDto create(CreateBookRequestDto createBookRequestDto) { - Book book = bookMapper.toModel(createBookRequestDto); - Book savedBook = bookRepository.create(book); - return bookMapper.toDto(savedBook); + public BookDto save(CreateBookRequestDto createBookRequestDto) { + try { + if (createBookRequestDto.getTitle() == null) { + throw new BookValidationException("Title can't be null"); + } + + Book book = bookMapper.toModel(createBookRequestDto); + Book savedBook = bookRepository.save(book); + + return bookMapper.toDto(savedBook); + + } catch (Exception e) { + throw new BookSaveException("Can't save book", e); + } } @Override - public List getAll() { - return bookRepository.getAll().stream() + public List findAll() { + return bookRepository.findAll().stream() .map(bookMapper::toDto) .toList(); } @Override - public BookDto getById(Long id) { - Book book = bookRepository.getById(id).orElseThrow( - () -> new RuntimeException("Book not found" + id)); + public BookDto findById(Long id) { + Book book = bookRepository.findById(id) + .orElseThrow(() -> new BookNotFoundException("Book with id: " + id + " not found")); return bookMapper.toDto(book); } + + @Override + public void deleteById(Long id) { + bookRepository.deleteById(id); + } + + @Override + public void updateBookById(Long id, BookDto bookDto) { + if (!bookRepository.existsById(id)) { + throw new BookNotFoundException("Book not found with id " + id); + } + bookRepository.updateBookById(id, bookDto.getTitle(), + bookDto.getAuthor(), bookDto.getIsbn(), + bookDto.getPrice(), bookDto.getDescription(), + bookDto.getCoverImage()); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 41746e8..8e85d49 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -3,5 +3,6 @@ spring.datasource.username=root spring.datasource.password=Wetuop34! spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.show-sql=true \ No newline at end of file +spring.jpa.hibernate.ddl-auto=validate +spring.jpa.show-sql=true +spring.liquibase.enabled=false \ No newline at end of file diff --git a/src/main/resources/db.changelog/changes/01-test.yaml b/src/main/resources/db.changelog/changes/01-test.yaml new file mode 100644 index 0000000..d1ffc18 --- /dev/null +++ b/src/main/resources/db.changelog/changes/01-test.yaml @@ -0,0 +1,5 @@ +databaseChangeLog: + - changeSet: + id: 01-test.yaml + author: artur + changes: diff --git a/src/main/resources/db.changelog/db.changelog-master.yaml b/src/main/resources/db.changelog/db.changelog-master.yaml new file mode 100644 index 0000000..7ae7003 --- /dev/null +++ b/src/main/resources/db.changelog/db.changelog-master.yaml @@ -0,0 +1,3 @@ +databaseChangeLog: + - include: + file: \ No newline at end of file diff --git a/src/main/resources/liquibase.properties b/src/main/resources/liquibase.properties new file mode 100644 index 0000000..5b0fb64 --- /dev/null +++ b/src/main/resources/liquibase.properties @@ -0,0 +1,7 @@ +url=jdbc:mysql://localhost:3306/lombok?serverTimezone=UTC +username=root +password=Wetuop34! +changeLogFile=src/main/resources/db/changelog/db.changelog-master.yaml +driver=com.mysql.cj.jdbc.Driver + +