diff --git a/.gitignore b/.gitignore
index 1901201..d7884b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+.idea/
+target/
# Default ignored files
/shelf/
/.idea/workspace.xml
diff --git a/pom.xml b/pom.xml
index 48b39fd..5391f43 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,9 @@
17
checkstyle.xml
+ 1.18.30
+ 0.2.0
+ 1.5.5.Final
@@ -77,6 +80,25 @@
h2
test
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.mapstruct
+ mapstruct
+ ${mapstruct.version}
+
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ 0.2.0
+ provided
+
+
+
@@ -85,12 +107,25 @@
org.apache.maven.plugins
maven-compiler-plugin
-
-
- org.projectlombok
- lombok
-
-
+ ${java.version}
+ ${java.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ ${lombok.mapstruct.binding.version}
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
@@ -110,6 +145,7 @@
true
true
false
+ src/main
diff --git a/spring-boot-intro (1).iml b/spring-boot-intro (1).iml
new file mode 100644
index 0000000..95df0ad
--- /dev/null
+++ b/spring-boot-intro (1).iml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/boot/BootIntroApplication.java b/src/main/java/boot/BootIntroApplication.java
index 0739a11..9a51151 100644
--- a/src/main/java/boot/BootIntroApplication.java
+++ b/src/main/java/boot/BootIntroApplication.java
@@ -29,7 +29,6 @@ public CommandLineRunner init(BookService bookService) {
book.setPrice(new BigDecimal("19.99"));
book.setCoverImage("https://example.com/cover.jpg");
- bookService.save(book);
System.out.println(bookService.findAll());
};
}
diff --git a/src/main/java/boot/config/MapperConfig.java b/src/main/java/boot/config/MapperConfig.java
new file mode 100644
index 0000000..5fc527e
--- /dev/null
+++ b/src/main/java/boot/config/MapperConfig.java
@@ -0,0 +1,14 @@
+package boot.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/boot/controller/BookController.java b/src/main/java/boot/controller/BookController.java
new file mode 100644
index 0000000..545b685
--- /dev/null
+++ b/src/main/java/boot/controller/BookController.java
@@ -0,0 +1,37 @@
+package boot.controller;
+
+import boot.dto.BookDto;
+import boot.dto.CreateBookRequestDto;
+import boot.service.BookService;
+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.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/books")
+public class BookController {
+ private final BookService bookService;
+
+ @GetMapping
+ public List getAll() {
+ return bookService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ @ResponseBody
+ public BookDto getBookById(@PathVariable Long id) {
+ return bookService.findById(id);
+ }
+
+ @PostMapping
+ public BookDto createBook(@RequestBody CreateBookRequestDto bookDto) {
+ return bookService.save(bookDto);
+ }
+}
diff --git a/src/main/java/boot/dto/BookDto.java b/src/main/java/boot/dto/BookDto.java
new file mode 100644
index 0000000..1a40884
--- /dev/null
+++ b/src/main/java/boot/dto/BookDto.java
@@ -0,0 +1,13 @@
+package boot.dto;
+
+import lombok.Data;
+
+@Data
+public class BookDto {
+ private Long id;
+ private String title;
+ private String author;
+ private Double price;
+ private String description;
+ private String coverImage;
+}
diff --git a/src/main/java/boot/dto/CreateBookRequestDto.java b/src/main/java/boot/dto/CreateBookRequestDto.java
new file mode 100644
index 0000000..b149603
--- /dev/null
+++ b/src/main/java/boot/dto/CreateBookRequestDto.java
@@ -0,0 +1,14 @@
+package boot.dto;
+
+import lombok.Data;
+
+@Data
+public class CreateBookRequestDto {
+ private Long id;
+ private String title;
+ private String author;
+ private String isbn;
+ private Double price;
+ private String description;
+ private String coverImage;
+}
diff --git a/src/main/java/boot/exception/EntityNotFoundException.java b/src/main/java/boot/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..5b9fcad
--- /dev/null
+++ b/src/main/java/boot/exception/EntityNotFoundException.java
@@ -0,0 +1,7 @@
+package boot.exception;
+
+public class EntityNotFoundException extends RuntimeException {
+ public EntityNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/boot/mapper/BookMapper.java b/src/main/java/boot/mapper/BookMapper.java
new file mode 100644
index 0000000..ee8646b
--- /dev/null
+++ b/src/main/java/boot/mapper/BookMapper.java
@@ -0,0 +1,14 @@
+package boot.mapper;
+
+import boot.config.MapperConfig;
+import boot.dto.BookDto;
+import boot.dto.CreateBookRequestDto;
+import boot.model.Book;
+import org.mapstruct.Mapper;
+
+@Mapper(config = MapperConfig.class)
+public interface BookMapper {
+ BookDto toBookDto(Book book);
+
+ Book toBook(CreateBookRequestDto bookDto);
+}
diff --git a/src/main/java/boot/repository/BookRepository.java b/src/main/java/boot/repository/BookRepository.java
index d2d06b7..5395c1b 100644
--- a/src/main/java/boot/repository/BookRepository.java
+++ b/src/main/java/boot/repository/BookRepository.java
@@ -2,9 +2,12 @@
import boot.model.Book;
import java.util.List;
+import java.util.Optional;
public interface BookRepository {
Book save(Book book);
List findAll();
+
+ Optional findById(Long id);
}
diff --git a/src/main/java/boot/repository/BookRepositoryImpl.java b/src/main/java/boot/repository/BookRepositoryImpl.java
index 9eb40be..3ef4e27 100644
--- a/src/main/java/boot/repository/BookRepositoryImpl.java
+++ b/src/main/java/boot/repository/BookRepositoryImpl.java
@@ -3,6 +3,7 @@
import boot.exception.DataProcessingException;
import boot.model.Book;
import java.util.List;
+import java.util.Optional;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
@@ -48,4 +49,13 @@ public List findAll() {
throw new DataProcessingException("Could not find all books", e);
}
}
+
+ @Override
+ public Optional findById(Long id) {
+ try (Session session = sessionFactory.openSession()) {
+ return Optional.ofNullable(session.get(Book.class, id));
+ } catch (Exception e) {
+ throw new DataProcessingException("Could not find book with id: " + id, e);
+ }
+ }
}
diff --git a/src/main/java/boot/service/BookService.java b/src/main/java/boot/service/BookService.java
index 79337af..954aed0 100644
--- a/src/main/java/boot/service/BookService.java
+++ b/src/main/java/boot/service/BookService.java
@@ -1,10 +1,13 @@
package boot.service;
-import boot.model.Book;
+import boot.dto.BookDto;
+import boot.dto.CreateBookRequestDto;
import java.util.List;
public interface BookService {
- Book save(Book book);
+ BookDto save(CreateBookRequestDto bookDto);
- List findAll();
+ List findAll();
+
+ BookDto findById(Long id);
}
diff --git a/src/main/java/boot/service/BookServiceImpl.java b/src/main/java/boot/service/BookServiceImpl.java
index d0c0f72..fd63317 100644
--- a/src/main/java/boot/service/BookServiceImpl.java
+++ b/src/main/java/boot/service/BookServiceImpl.java
@@ -1,25 +1,40 @@
package boot.service;
+import boot.dto.BookDto;
+import boot.dto.CreateBookRequestDto;
+import boot.exception.EntityNotFoundException;
+import boot.mapper.BookMapper;
import boot.model.Book;
import boot.repository.BookRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class BookServiceImpl implements BookService {
- @Autowired
private final BookRepository bookRepository;
+ private final BookMapper bookMapper;
+
+ @Override
+ public BookDto save(CreateBookRequestDto bookDto) {
+ Book book = bookMapper.toBook(bookDto);
+ return bookMapper.toBookDto(bookRepository.save(book));
+ }
+
@Override
- public Book save(Book book) {
- return bookRepository.save(book);
+ public List findAll() {
+ return bookRepository.findAll().stream()
+ .map(bookMapper::toBookDto)
+ .toList();
}
@Override
- public List findAll() {
- return bookRepository.findAll();
+ public BookDto findById(Long id) {
+ Book book = bookRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(
+ "Can't find Book with id:" + id)
+ );
+ return bookMapper.toBookDto(book);
}
}