From 0dade8ceb2b9018647e8458883285f752888e752 Mon Sep 17 00:00:00 2001 From: stvort Date: Sun, 29 Oct 2023 23:25:50 +0400 Subject: [PATCH] jbdc hw templates added --- .gitignore | 1 + templates/hw05-jdbc-hard-template/.gitignore | 30 ++++ templates/hw05-jdbc-hard-template/pom.xml | 100 +++++++++++++ .../src/main/java/ru/otus/hw/Application.java | 13 ++ .../ru/otus/hw/commands/AuthorCommands.java | 25 ++++ .../ru/otus/hw/commands/BookCommands.java | 52 +++++++ .../ru/otus/hw/commands/GenreCommands.java | 25 ++++ .../otus/hw/converters/AuthorConverter.java | 11 ++ .../ru/otus/hw/converters/BookConverter.java | 27 ++++ .../ru/otus/hw/converters/GenreConverter.java | 11 ++ .../exceptions/EntityNotFoundException.java | 7 + .../main/java/ru/otus/hw/models/Author.java | 14 ++ .../src/main/java/ru/otus/hw/models/Book.java | 20 +++ .../main/java/ru/otus/hw/models/Genre.java | 14 ++ .../hw/repositories/AuthorRepository.java | 12 ++ .../hw/repositories/AuthorRepositoryJdbc.java | 33 +++++ .../otus/hw/repositories/BookRepository.java | 16 +++ .../hw/repositories/BookRepositoryJdbc.java | 112 +++++++++++++++ .../otus/hw/repositories/GenreRepository.java | 11 ++ .../hw/repositories/GenreRepositoryJdbc.java | 32 +++++ .../ru/otus/hw/services/AuthorService.java | 9 ++ .../otus/hw/services/AuthorServiceImpl.java | 19 +++ .../java/ru/otus/hw/services/BookService.java | 18 +++ .../ru/otus/hw/services/BookServiceImpl.java | 60 ++++++++ .../ru/otus/hw/services/GenreService.java | 9 ++ .../ru/otus/hw/services/GenreServiceImpl.java | 19 +++ .../src/main/resources/application.yml | 8 ++ .../src/main/resources/data.sql | 14 ++ .../src/main/resources/schema.sql | 24 ++++ .../repositories/BookRepositoryJdbcTest.java | 134 ++++++++++++++++++ .../src/test/resources/application.yml | 8 ++ .../src/test/resources/data.sql | 14 ++ .../hw05-jdbc-simple-template/.gitignore | 30 ++++ templates/hw05-jdbc-simple-template/pom.xml | 100 +++++++++++++ .../src/main/java/ru/otus/hw/Application.java | 13 ++ .../ru/otus/hw/commands/AuthorCommands.java | 25 ++++ .../ru/otus/hw/commands/BookCommands.java | 49 +++++++ .../ru/otus/hw/commands/GenreCommands.java | 25 ++++ .../otus/hw/converters/AuthorConverter.java | 11 ++ .../ru/otus/hw/converters/BookConverter.java | 21 +++ .../ru/otus/hw/converters/GenreConverter.java | 11 ++ .../exceptions/EntityNotFoundException.java | 7 + .../main/java/ru/otus/hw/models/Author.java | 14 ++ .../src/main/java/ru/otus/hw/models/Book.java | 18 +++ .../main/java/ru/otus/hw/models/Genre.java | 14 ++ .../hw/repositories/AuthorRepository.java | 12 ++ .../hw/repositories/AuthorRepositoryJdbc.java | 33 +++++ .../otus/hw/repositories/BookRepository.java | 16 +++ .../hw/repositories/BookRepositoryJdbc.java | 62 ++++++++ .../otus/hw/repositories/GenreRepository.java | 12 ++ .../hw/repositories/GenreRepositoryJdbc.java | 33 +++++ .../ru/otus/hw/services/AuthorService.java | 9 ++ .../otus/hw/services/AuthorServiceImpl.java | 19 +++ .../java/ru/otus/hw/services/BookService.java | 18 +++ .../ru/otus/hw/services/BookServiceImpl.java | 56 ++++++++ .../ru/otus/hw/services/GenreService.java | 9 ++ .../ru/otus/hw/services/GenreServiceImpl.java | 19 +++ .../src/main/resources/application.yml | 8 ++ .../src/main/resources/data.sql | 8 ++ .../src/main/resources/schema.sql | 19 +++ .../repositories/BookRepositoryJdbcTest.java | 128 +++++++++++++++++ .../src/test/resources/application.yml | 8 ++ .../src/test/resources/data.sql | 8 ++ 63 files changed, 1717 insertions(+) create mode 100644 templates/hw05-jdbc-hard-template/.gitignore create mode 100644 templates/hw05-jdbc-hard-template/pom.xml create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/Application.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/BookCommands.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/GenreCommands.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/BookConverter.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/GenreConverter.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Author.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Book.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Genre.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepository.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorService.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookService.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreService.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java create mode 100644 templates/hw05-jdbc-hard-template/src/main/resources/application.yml create mode 100644 templates/hw05-jdbc-hard-template/src/main/resources/data.sql create mode 100644 templates/hw05-jdbc-hard-template/src/main/resources/schema.sql create mode 100644 templates/hw05-jdbc-hard-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java create mode 100644 templates/hw05-jdbc-hard-template/src/test/resources/application.yml create mode 100644 templates/hw05-jdbc-hard-template/src/test/resources/data.sql create mode 100644 templates/hw05-jdbc-simple-template/.gitignore create mode 100644 templates/hw05-jdbc-simple-template/pom.xml create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/Application.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/BookCommands.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/GenreCommands.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/BookConverter.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/GenreConverter.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Author.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Book.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Genre.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepository.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorService.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookService.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreService.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java create mode 100644 templates/hw05-jdbc-simple-template/src/main/resources/application.yml create mode 100644 templates/hw05-jdbc-simple-template/src/main/resources/data.sql create mode 100644 templates/hw05-jdbc-simple-template/src/main/resources/schema.sql create mode 100644 templates/hw05-jdbc-simple-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java create mode 100644 templates/hw05-jdbc-simple-template/src/test/resources/application.yml create mode 100644 templates/hw05-jdbc-simple-template/src/test/resources/data.sql diff --git a/.gitignore b/.gitignore index e3d6056a..ffda238a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.iml .idea/ target/ +spring-shell.log !**/src/main/**/target/ !**/src/test/**/target/ diff --git a/templates/hw05-jdbc-hard-template/.gitignore b/templates/hw05-jdbc-hard-template/.gitignore new file mode 100644 index 00000000..b96df348 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/.gitignore @@ -0,0 +1,30 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +spring-shell.log + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/templates/hw05-jdbc-hard-template/pom.xml b/templates/hw05-jdbc-hard-template/pom.xml new file mode 100644 index 00000000..86f97d4b --- /dev/null +++ b/templates/hw05-jdbc-hard-template/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.2 + + + + ru.otus.hw + hw05-jdbc + 0.0.1-SNAPSHOT + spring-jdbc-demo + + + 17 + 17 + 17 + 2.2.220 + 3.1.3 + 2.0 + 3.2.2 + 10.11.0 + + https://raw.githubusercontent.com/OtusTeam/Spring/master/checkstyle.xml + + + + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + + org.springframework.shell + spring-shell-starter + ${spring.shell.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-plugin.version} + + + com.puppycrawl.tools + checkstyle + ${checkstyle.version} + + + + ${checkstyle.config.url} + + + + + check + + + + + + + + diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/Application.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/Application.java new file mode 100644 index 00000000..a3f0fd27 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/Application.java @@ -0,0 +1,13 @@ +package ru.otus.hw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java new file mode 100644 index 00000000..c832e8ea --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java @@ -0,0 +1,25 @@ +package ru.otus.hw.commands; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.hw.converters.AuthorConverter; +import ru.otus.hw.services.AuthorService; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@ShellComponent +public class AuthorCommands { + + private final AuthorService authorService; + + private final AuthorConverter authorConverter; + + @ShellMethod(value = "Find all authors", key = "aa") + public String findAllAuthors() { + return authorService.findAll().stream() + .map(authorConverter::authorToString) + .collect(Collectors.joining("," + System.lineSeparator())); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/BookCommands.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/BookCommands.java new file mode 100644 index 00000000..0716dd6a --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/BookCommands.java @@ -0,0 +1,52 @@ +package ru.otus.hw.commands; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.hw.converters.BookConverter; +import ru.otus.hw.services.BookService; + +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@ShellComponent +public class BookCommands { + + private final BookService bookService; + + private final BookConverter bookConverter; + + @ShellMethod(value = "Find all books", key = "ab") + public String findAllBooks() { + return bookService.findAll().stream() + .map(bookConverter::bookToString) + .collect(Collectors.joining("," + System.lineSeparator())); + } + + @ShellMethod(value = "Find book by id", key = "bbid") + public String findBookById(long id) { + return bookService.findById(id) + .map(bookConverter::bookToString) + .orElse("Book with id %d not found".formatted(id)); + } + + //bins aaaaaaaaaaaaa 1 1,6//bins aaaaaaaaaaaaa 1 1,6 + @ShellMethod(value = "Insert book", key = "bins") + public String insertBook(String title, long authorId, List genresIds) { + var savedBook = bookService.insert(title, authorId, genresIds); + return bookConverter.bookToString(savedBook); + } + + //bupd 4 dfasdfasdfasd 3 2,5 + @ShellMethod(value = "Update book", key = "bupd") + public String updateBook(long id, String title, long authorId, List genresIds) { + var savedBook = bookService.update(id, title, authorId, genresIds); + return bookConverter.bookToString(savedBook); + } + + @ShellMethod(value = "Delete book by id", key = "bdel") + public void updateBook(long id) { + bookService.deleteById(id); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/GenreCommands.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/GenreCommands.java new file mode 100644 index 00000000..2b5705b8 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/commands/GenreCommands.java @@ -0,0 +1,25 @@ +package ru.otus.hw.commands; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.hw.converters.GenreConverter; +import ru.otus.hw.services.GenreService; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@ShellComponent +public class GenreCommands { + + private final GenreService genreService; + + private final GenreConverter genreConverter; + + @ShellMethod(value = "Find all genres", key = "ag") + public String findAllGenres() { + return genreService.findAll().stream() + .map(genreConverter::genreToString) + .collect(Collectors.joining("," + System.lineSeparator())); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java new file mode 100644 index 00000000..7d4d6c9c --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java @@ -0,0 +1,11 @@ +package ru.otus.hw.converters; + +import org.springframework.stereotype.Component; +import ru.otus.hw.models.Author; + +@Component +public class AuthorConverter { + public String authorToString(Author author) { + return "Id: %d, FullName: %s".formatted(author.getId(), author.getFullName()); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/BookConverter.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/BookConverter.java new file mode 100644 index 00000000..c174791d --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/BookConverter.java @@ -0,0 +1,27 @@ +package ru.otus.hw.converters; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import ru.otus.hw.models.Book; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Component +public class BookConverter { + private final AuthorConverter authorConverter; + + private final GenreConverter genreConverter; + + public String bookToString(Book book) { + var genresString = book.getGenres().stream() + .map(genreConverter::genreToString) + .map("{%s}"::formatted) + .collect(Collectors.joining(", ")); + return "Id: %d, title: %s, author: {%s}, genres: [%s]".formatted( + book.getId(), + book.getTitle(), + authorConverter.authorToString(book.getAuthor()), + genresString); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/GenreConverter.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/GenreConverter.java new file mode 100644 index 00000000..92d500ca --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/converters/GenreConverter.java @@ -0,0 +1,11 @@ +package ru.otus.hw.converters; + +import org.springframework.stereotype.Component; +import ru.otus.hw.models.Genre; + +@Component +public class GenreConverter { + public String genreToString(Genre genre) { + return "Id: %d, Name: %s".formatted(genre.getId(), genre.getName()); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java new file mode 100644 index 00000000..eb27d491 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.hw.exceptions; + +public class EntityNotFoundException extends RuntimeException { + public EntityNotFoundException(String message) { + super(message); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Author.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Author.java new file mode 100644 index 00000000..7db6dbbe --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Author.java @@ -0,0 +1,14 @@ +package ru.otus.hw.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Author { + private long id; + + private String fullName; +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Book.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Book.java new file mode 100644 index 00000000..c71d15e1 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Book.java @@ -0,0 +1,20 @@ +package ru.otus.hw.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Book { + private long id; + + private String title; + + private Author author; + + private List genres; +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Genre.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Genre.java new file mode 100644 index 00000000..e59ddab3 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/models/Genre.java @@ -0,0 +1,14 @@ +package ru.otus.hw.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Genre { + private long id; + + private String name; +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java new file mode 100644 index 00000000..743de402 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java @@ -0,0 +1,12 @@ +package ru.otus.hw.repositories; + +import ru.otus.hw.models.Author; + +import java.util.List; +import java.util.Optional; + +public interface AuthorRepository { + List findAll(); + + Optional findById(long id); +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java new file mode 100644 index 00000000..b12c0c2c --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java @@ -0,0 +1,33 @@ +package ru.otus.hw.repositories; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.hw.models.Author; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Repository +public class AuthorRepositoryJdbc implements AuthorRepository { + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Optional findById(long id) { + return Optional.empty(); + } + + private static class AuthorRowMapper implements RowMapper { + + @Override + public Author mapRow(ResultSet rs, int i) throws SQLException { + return null; + } + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepository.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepository.java new file mode 100644 index 00000000..ab507c33 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepository.java @@ -0,0 +1,16 @@ +package ru.otus.hw.repositories; + +import ru.otus.hw.models.Book; + +import java.util.List; +import java.util.Optional; + +public interface BookRepository { + Optional findById(long id); + + List findAll(); + + Book save(Book book); + + void deleteById(long id); +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java new file mode 100644 index 00000000..bb99e66e --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java @@ -0,0 +1,112 @@ +package ru.otus.hw.repositories; + +import lombok.RequiredArgsConstructor; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.stereotype.Repository; +import ru.otus.hw.models.Book; +import ru.otus.hw.models.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Repository +@RequiredArgsConstructor +public class BookRepositoryJdbc implements BookRepository { + + private final GenreRepository genreRepository; + + @Override + public Optional findById(long id) { + return Optional.empty(); + } + + @Override + public List findAll() { + var genres = genreRepository.findAll(); + var relations = getAllGenreRelations(); + var books = getAllBooksWithoutGenres(); + mergeBooksInfo(books, genres, relations); + return books; + } + + @Override + public Book save(Book book) { + if (book.getId() == 0) { + return insert(book); + } + return update(book); + } + + @Override + public void deleteById(long id) { + //... + } + + private List getAllBooksWithoutGenres() { + return new ArrayList<>(); + } + + private List getAllGenreRelations() { + return new ArrayList<>(); + } + + private void mergeBooksInfo(List booksWithoutGenres, List genres, + List relations) { + // Добавить книгам (booksWithoutGenres) жанры (genres) в соответствии со связями (relations) + } + + private Book insert(Book book) { + var keyHolder = new GeneratedKeyHolder(); + + //... + + //noinspection DataFlowIssue + book.setId(keyHolder.getKeyAs(Long.class)); + batchInsertGenresRelationsFor(book); + return book; + } + + private Book update(Book book) { + //... + + removeGenresRelationsFor(book); + batchInsertGenresRelationsFor(book); + + return book; + } + + private void batchInsertGenresRelationsFor(Book book) { + // batchUpdate + } + + private void removeGenresRelationsFor(Book book) { + //... + } + + private static class BookRowMapper implements RowMapper { + + @Override + public Book mapRow(ResultSet rs, int rowNum) throws SQLException { + return null; + } + } + + @SuppressWarnings("ClassCanBeRecord") + @RequiredArgsConstructor + private static class BookResultSetExtractor implements ResultSetExtractor> { + + @Override + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + return new ArrayList<>(); + } + } + + private record BookGenreRelation(long bookId, long genreId) { + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java new file mode 100644 index 00000000..02e87b10 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java @@ -0,0 +1,11 @@ +package ru.otus.hw.repositories; + +import ru.otus.hw.models.Genre; + +import java.util.List; + +public interface GenreRepository { + List findAll(); + + List findAllByIds(List ids); +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java new file mode 100644 index 00000000..e87daa58 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java @@ -0,0 +1,32 @@ +package ru.otus.hw.repositories; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.hw.models.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@Repository +public class GenreRepositoryJdbc implements GenreRepository { + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public List findAllByIds(List ids) { + return new ArrayList<>(); + } + + private static class GnreRowMapper implements RowMapper { + + @Override + public Genre mapRow(ResultSet rs, int i) throws SQLException { + return null; + } + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorService.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorService.java new file mode 100644 index 00000000..87e92f8c --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorService.java @@ -0,0 +1,9 @@ +package ru.otus.hw.services; + +import ru.otus.hw.models.Author; + +import java.util.List; + +public interface AuthorService { + List findAll(); +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java new file mode 100644 index 00000000..36740ca1 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java @@ -0,0 +1,19 @@ +package ru.otus.hw.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.hw.models.Author; +import ru.otus.hw.repositories.AuthorRepository; + +import java.util.List; + +@RequiredArgsConstructor +@Service +public class AuthorServiceImpl implements AuthorService { + private final AuthorRepository authorRepository; + + @Override + public List findAll() { + return authorRepository.findAll(); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookService.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookService.java new file mode 100644 index 00000000..8b37a4b0 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookService.java @@ -0,0 +1,18 @@ +package ru.otus.hw.services; + +import ru.otus.hw.models.Book; + +import java.util.List; +import java.util.Optional; + +public interface BookService { + Optional findById(long id); + + List findAll(); + + Book insert(String title, long authorId, List genresIds); + + Book update(long id, String title, long authorId, List genresIds); + + void deleteById(long id); +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java new file mode 100644 index 00000000..a6495210 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java @@ -0,0 +1,60 @@ +package ru.otus.hw.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.hw.exceptions.EntityNotFoundException; +import ru.otus.hw.models.Book; +import ru.otus.hw.repositories.AuthorRepository; +import ru.otus.hw.repositories.BookRepository; +import ru.otus.hw.repositories.GenreRepository; + +import java.util.List; +import java.util.Optional; + +import static org.springframework.util.CollectionUtils.isEmpty; + +@RequiredArgsConstructor +@Service +public class BookServiceImpl implements BookService { + private final AuthorRepository authorRepository; + + private final GenreRepository genreRepository; + + private final BookRepository bookRepository; + + @Override + public Optional findById(long id) { + return bookRepository.findById(id); + } + + @Override + public List findAll() { + return bookRepository.findAll(); + } + + @Override + public Book insert(String title, long authorId, List genresIds) { + return save(0, title, authorId, genresIds); + } + + @Override + public Book update(long id, String title, long authorId, List genresIds) { + return save(id, title, authorId, genresIds); + } + + @Override + public void deleteById(long id) { + bookRepository.deleteById(id); + } + + private Book save(long id, String title, long authorId, List genresIds) { + var author = authorRepository.findById(authorId) + .orElseThrow(() -> new EntityNotFoundException("Author with id %d not found".formatted(authorId))); + var genres = genreRepository.findAllByIds(genresIds); + if (isEmpty(genres)) { + throw new EntityNotFoundException("Genres with ids %s not found".formatted(genresIds)); + } + var book = new Book(id, title, author, genres); + return bookRepository.save(book); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreService.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreService.java new file mode 100644 index 00000000..3fd4170b --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreService.java @@ -0,0 +1,9 @@ +package ru.otus.hw.services; + +import ru.otus.hw.models.Genre; + +import java.util.List; + +public interface GenreService { + List findAll(); +} diff --git a/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java new file mode 100644 index 00000000..8d1f620a --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java @@ -0,0 +1,19 @@ +package ru.otus.hw.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.hw.models.Genre; +import ru.otus.hw.repositories.GenreRepository; + +import java.util.List; + +@RequiredArgsConstructor +@Service +public class GenreServiceImpl implements GenreService { + private final GenreRepository genreRepository; + + @Override + public List findAll() { + return genreRepository.findAll(); + } +} diff --git a/templates/hw05-jdbc-hard-template/src/main/resources/application.yml b/templates/hw05-jdbc-hard-template/src/main/resources/application.yml new file mode 100644 index 00000000..c037758d --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + datasource: + url: jdbc:h2:mem:maindb + sql: + init: + mode: always + data-locations: data.sql + schema-locations: schema.sql \ No newline at end of file diff --git a/templates/hw05-jdbc-hard-template/src/main/resources/data.sql b/templates/hw05-jdbc-hard-template/src/main/resources/data.sql new file mode 100644 index 00000000..3dd3a166 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/resources/data.sql @@ -0,0 +1,14 @@ +insert into authors(full_name) +values ('Author_1'), ('Author_2'), ('Author_3'); + +insert into genres(name) +values ('Genre_1'), ('Genre_2'), ('Genre_3'), + ('Genre_4'), ('Genre_5'), ('Genre_6'); + +insert into books(title, author_id) +values ('BookTitle_1', 1), ('BookTitle_2', 2), ('BookTitle_3', 3); + +insert into books_genres(book_id, genre_id) +values (1, 1), (1, 2), + (2, 3), (2, 4), + (3, 5), (3, 6); diff --git a/templates/hw05-jdbc-hard-template/src/main/resources/schema.sql b/templates/hw05-jdbc-hard-template/src/main/resources/schema.sql new file mode 100644 index 00000000..b085e18a --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/main/resources/schema.sql @@ -0,0 +1,24 @@ +create table authors ( + id bigserial, + full_name varchar(255), + primary key (id) +); + +create table genres ( + id bigserial, + name varchar(255), + primary key (id) +); + +create table books ( + id bigserial, + title varchar(255), + author_id bigint references authors (id) on delete cascade, + primary key (id) +); + +create table books_genres ( + book_id bigint references books(id) on delete cascade, + genre_id bigint references genres(id) on delete cascade, + primary key (book_id, genre_id) +); \ No newline at end of file diff --git a/templates/hw05-jdbc-hard-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java b/templates/hw05-jdbc-hard-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java new file mode 100644 index 00000000..a226d7ab --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java @@ -0,0 +1,134 @@ +package ru.otus.hw.repositories; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; +import ru.otus.hw.models.Author; +import ru.otus.hw.models.Book; +import ru.otus.hw.models.Genre; + +import java.util.List; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("Репозиторий на основе Jdbc для работы с книгами ") +@JdbcTest +@Import({BookRepositoryJdbc.class, GenreRepositoryJdbc.class}) +class BookRepositoryJdbcTest { + + @Autowired + private BookRepositoryJdbc repositoryJdbc; + + private List dbAuthors; + + private List dbGenres; + + private List dbBooks; + + @BeforeEach + void setUp() { + dbAuthors = getDbAuthors(); + dbGenres = getDbGenres(); + dbBooks = getDbBooks(dbAuthors, dbGenres); + } + + @DisplayName("должен загружать книгу по id") + @ParameterizedTest + @MethodSource("getDbBooks") + void shouldReturnCorrectBookById(Book expectedBook) { + var actualBook = repositoryJdbc.findById(expectedBook.getId()); + assertThat(actualBook).isPresent() + .get() + .isEqualTo(expectedBook); + } + + @DisplayName("должен загружать список всех книг") + @Test + void shouldReturnCorrectBooksList() { + var actualBooks = repositoryJdbc.findAll(); + var expectedBooks = dbBooks; + + assertThat(actualBooks).containsExactlyElementsOf(expectedBooks); + actualBooks.forEach(System.out::println); + } + + @DisplayName("должен сохранять новую книгу") + @Test + void shouldSaveNewBook() { + var expectedBook = new Book(0, "BookTitle_10500", dbAuthors.get(0), + List.of(dbGenres.get(0), dbGenres.get(2))); + var returnedBook = repositoryJdbc.save(expectedBook); + assertThat(returnedBook).isNotNull() + .matches(book -> book.getId() > 0) + .usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedBook); + + assertThat(repositoryJdbc.findById(returnedBook.getId())) + .isPresent() + .get() + .isEqualTo(returnedBook); + } + + @DisplayName("должен сохранять измененную книгу") + @Test + void shouldSaveUpdatedBook() { + var expectedBook = new Book(1L, "BookTitle_10500", dbAuthors.get(2), + List.of(dbGenres.get(4), dbGenres.get(5))); + + assertThat(repositoryJdbc.findById(expectedBook.getId())) + .isPresent() + .get() + .isNotEqualTo(expectedBook); + + var returnedBook = repositoryJdbc.save(expectedBook); + assertThat(returnedBook).isNotNull() + .matches(book -> book.getId() > 0) + .usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedBook); + + assertThat(repositoryJdbc.findById(returnedBook.getId())) + .isPresent() + .get() + .isEqualTo(returnedBook); + } + + @DisplayName("должен удалять книгу по id ") + @Test + void shouldDeleteBook() { + assertThat(repositoryJdbc.findById(1L)).isPresent(); + repositoryJdbc.deleteById(1L); + assertThat(repositoryJdbc.findById(1L)).isEmpty(); + } + + private static List getDbAuthors() { + return IntStream.range(1, 4).boxed() + .map(id -> new Author(id, "Author_" + id)) + .toList(); + } + + private static List getDbGenres() { + return IntStream.range(1, 7).boxed() + .map(id -> new Genre(id, "Genre_" + id)) + .toList(); + } + + private static List getDbBooks(List dbAuthors, List dbGenres) { + return IntStream.range(1, 4).boxed() + .map(id -> new Book(id, + "BookTitle_" + id, + dbAuthors.get(id - 1), + dbGenres.subList((id - 1) * 2, (id - 1) * 2 + 2) + )) + .toList(); + } + + private static List getDbBooks() { + var dbAuthors = getDbAuthors(); + var dbGenres = getDbGenres(); + return getDbBooks(dbAuthors, dbGenres); + } +} \ No newline at end of file diff --git a/templates/hw05-jdbc-hard-template/src/test/resources/application.yml b/templates/hw05-jdbc-hard-template/src/test/resources/application.yml new file mode 100644 index 00000000..45c16b3d --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/test/resources/application.yml @@ -0,0 +1,8 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + sql: + init: + mode: always + data-locations: data.sql + schema-locations: schema.sql \ No newline at end of file diff --git a/templates/hw05-jdbc-hard-template/src/test/resources/data.sql b/templates/hw05-jdbc-hard-template/src/test/resources/data.sql new file mode 100644 index 00000000..3dd3a166 --- /dev/null +++ b/templates/hw05-jdbc-hard-template/src/test/resources/data.sql @@ -0,0 +1,14 @@ +insert into authors(full_name) +values ('Author_1'), ('Author_2'), ('Author_3'); + +insert into genres(name) +values ('Genre_1'), ('Genre_2'), ('Genre_3'), + ('Genre_4'), ('Genre_5'), ('Genre_6'); + +insert into books(title, author_id) +values ('BookTitle_1', 1), ('BookTitle_2', 2), ('BookTitle_3', 3); + +insert into books_genres(book_id, genre_id) +values (1, 1), (1, 2), + (2, 3), (2, 4), + (3, 5), (3, 6); diff --git a/templates/hw05-jdbc-simple-template/.gitignore b/templates/hw05-jdbc-simple-template/.gitignore new file mode 100644 index 00000000..b96df348 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/.gitignore @@ -0,0 +1,30 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +spring-shell.log + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/templates/hw05-jdbc-simple-template/pom.xml b/templates/hw05-jdbc-simple-template/pom.xml new file mode 100644 index 00000000..86f97d4b --- /dev/null +++ b/templates/hw05-jdbc-simple-template/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.2 + + + + ru.otus.hw + hw05-jdbc + 0.0.1-SNAPSHOT + spring-jdbc-demo + + + 17 + 17 + 17 + 2.2.220 + 3.1.3 + 2.0 + 3.2.2 + 10.11.0 + + https://raw.githubusercontent.com/OtusTeam/Spring/master/checkstyle.xml + + + + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + + org.springframework.shell + spring-shell-starter + ${spring.shell.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-plugin.version} + + + com.puppycrawl.tools + checkstyle + ${checkstyle.version} + + + + ${checkstyle.config.url} + + + + + check + + + + + + + + diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/Application.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/Application.java new file mode 100644 index 00000000..a3f0fd27 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/Application.java @@ -0,0 +1,13 @@ +package ru.otus.hw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java new file mode 100644 index 00000000..c832e8ea --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/AuthorCommands.java @@ -0,0 +1,25 @@ +package ru.otus.hw.commands; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.hw.converters.AuthorConverter; +import ru.otus.hw.services.AuthorService; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@ShellComponent +public class AuthorCommands { + + private final AuthorService authorService; + + private final AuthorConverter authorConverter; + + @ShellMethod(value = "Find all authors", key = "aa") + public String findAllAuthors() { + return authorService.findAll().stream() + .map(authorConverter::authorToString) + .collect(Collectors.joining("," + System.lineSeparator())); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/BookCommands.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/BookCommands.java new file mode 100644 index 00000000..2a6124f0 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/BookCommands.java @@ -0,0 +1,49 @@ +package ru.otus.hw.commands; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.hw.converters.BookConverter; +import ru.otus.hw.services.BookService; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@ShellComponent +public class BookCommands { + + private final BookService bookService; + + private final BookConverter bookConverter; + + @ShellMethod(value = "Find all books", key = "ab") + public String findAllBooks() { + return bookService.findAll().stream() + .map(bookConverter::bookToString) + .collect(Collectors.joining("," + System.lineSeparator())); + } + + @ShellMethod(value = "Find book by id", key = "bbid") + public String findBookById(long id) { + return bookService.findById(id) + .map(bookConverter::bookToString) + .orElse("Book with id %d not found".formatted(id)); + } + + @ShellMethod(value = "Insert book", key = "bins") + public String insertBook(String title, long authorId, long genreId) { + var savedBook = bookService.insert(title, authorId, genreId); + return bookConverter.bookToString(savedBook); + } + + @ShellMethod(value = "Update book", key = "bupd") + public String updateBook(long id, String title, long authorId, long genreId) { + var savedBook = bookService.update(id, title, authorId, genreId); + return bookConverter.bookToString(savedBook); + } + + @ShellMethod(value = "Delete book by id", key = "bdel") + public void updateBook(long id) { + bookService.deleteById(id); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/GenreCommands.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/GenreCommands.java new file mode 100644 index 00000000..2b5705b8 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/commands/GenreCommands.java @@ -0,0 +1,25 @@ +package ru.otus.hw.commands; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.hw.converters.GenreConverter; +import ru.otus.hw.services.GenreService; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@ShellComponent +public class GenreCommands { + + private final GenreService genreService; + + private final GenreConverter genreConverter; + + @ShellMethod(value = "Find all genres", key = "ag") + public String findAllGenres() { + return genreService.findAll().stream() + .map(genreConverter::genreToString) + .collect(Collectors.joining("," + System.lineSeparator())); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java new file mode 100644 index 00000000..7d4d6c9c --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/AuthorConverter.java @@ -0,0 +1,11 @@ +package ru.otus.hw.converters; + +import org.springframework.stereotype.Component; +import ru.otus.hw.models.Author; + +@Component +public class AuthorConverter { + public String authorToString(Author author) { + return "Id: %d, FullName: %s".formatted(author.getId(), author.getFullName()); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/BookConverter.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/BookConverter.java new file mode 100644 index 00000000..adcd894d --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/BookConverter.java @@ -0,0 +1,21 @@ +package ru.otus.hw.converters; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import ru.otus.hw.models.Book; + +@RequiredArgsConstructor +@Component +public class BookConverter { + private final AuthorConverter authorConverter; + + private final GenreConverter genreConverter; + + public String bookToString(Book book) { + return "Id: %d, title: %s, author: {%s}, genres: [%s]".formatted( + book.getId(), + book.getTitle(), + authorConverter.authorToString(book.getAuthor()), + genreConverter.genreToString(book.getGenre())); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/GenreConverter.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/GenreConverter.java new file mode 100644 index 00000000..92d500ca --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/converters/GenreConverter.java @@ -0,0 +1,11 @@ +package ru.otus.hw.converters; + +import org.springframework.stereotype.Component; +import ru.otus.hw.models.Genre; + +@Component +public class GenreConverter { + public String genreToString(Genre genre) { + return "Id: %d, Name: %s".formatted(genre.getId(), genre.getName()); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java new file mode 100644 index 00000000..eb27d491 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/exceptions/EntityNotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.hw.exceptions; + +public class EntityNotFoundException extends RuntimeException { + public EntityNotFoundException(String message) { + super(message); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Author.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Author.java new file mode 100644 index 00000000..7db6dbbe --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Author.java @@ -0,0 +1,14 @@ +package ru.otus.hw.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Author { + private long id; + + private String fullName; +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Book.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Book.java new file mode 100644 index 00000000..e5625435 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Book.java @@ -0,0 +1,18 @@ +package ru.otus.hw.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Book { + private long id; + + private String title; + + private Author author; + + private Genre genre; +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Genre.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Genre.java new file mode 100644 index 00000000..e59ddab3 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/models/Genre.java @@ -0,0 +1,14 @@ +package ru.otus.hw.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Genre { + private long id; + + private String name; +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java new file mode 100644 index 00000000..743de402 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepository.java @@ -0,0 +1,12 @@ +package ru.otus.hw.repositories; + +import ru.otus.hw.models.Author; + +import java.util.List; +import java.util.Optional; + +public interface AuthorRepository { + List findAll(); + + Optional findById(long id); +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java new file mode 100644 index 00000000..b12c0c2c --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/AuthorRepositoryJdbc.java @@ -0,0 +1,33 @@ +package ru.otus.hw.repositories; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.hw.models.Author; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Repository +public class AuthorRepositoryJdbc implements AuthorRepository { + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Optional findById(long id) { + return Optional.empty(); + } + + private static class AuthorRowMapper implements RowMapper { + + @Override + public Author mapRow(ResultSet rs, int i) throws SQLException { + return null; + } + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepository.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepository.java new file mode 100644 index 00000000..ab507c33 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepository.java @@ -0,0 +1,16 @@ +package ru.otus.hw.repositories; + +import ru.otus.hw.models.Book; + +import java.util.List; +import java.util.Optional; + +public interface BookRepository { + Optional findById(long id); + + List findAll(); + + Book save(Book book); + + void deleteById(long id); +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java new file mode 100644 index 00000000..fb3c70c3 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/BookRepositoryJdbc.java @@ -0,0 +1,62 @@ +package ru.otus.hw.repositories; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.stereotype.Repository; +import ru.otus.hw.models.Book; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Repository +public class BookRepositoryJdbc implements BookRepository { + + @Override + public Optional findById(long id) { + return Optional.empty(); + } + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Book save(Book book) { + if (book.getId() == 0) { + return insert(book); + } + return update(book); + } + + @Override + public void deleteById(long id) { + //... + } + + private Book insert(Book book) { + var keyHolder = new GeneratedKeyHolder(); + + //... + + //noinspection DataFlowIssue + book.setId(keyHolder.getKeyAs(Long.class)); + return book; + } + + private Book update(Book book) { + //... + return book; + } + + private static class BookRowMapper implements RowMapper { + + @Override + public Book mapRow(ResultSet rs, int rowNum) throws SQLException { + return null; + } + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java new file mode 100644 index 00000000..e2bb6df1 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepository.java @@ -0,0 +1,12 @@ +package ru.otus.hw.repositories; + +import ru.otus.hw.models.Genre; + +import java.util.List; +import java.util.Optional; + +public interface GenreRepository { + List findAll(); + + Optional findById(long id); +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java new file mode 100644 index 00000000..075e7f82 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/repositories/GenreRepositoryJdbc.java @@ -0,0 +1,33 @@ +package ru.otus.hw.repositories; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.hw.models.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Repository +public class GenreRepositoryJdbc implements GenreRepository { + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Optional findById(long id) { + return Optional.empty(); + } + + private static class GnreRowMapper implements RowMapper { + + @Override + public Genre mapRow(ResultSet rs, int i) throws SQLException { + return null; + } + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorService.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorService.java new file mode 100644 index 00000000..87e92f8c --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorService.java @@ -0,0 +1,9 @@ +package ru.otus.hw.services; + +import ru.otus.hw.models.Author; + +import java.util.List; + +public interface AuthorService { + List findAll(); +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java new file mode 100644 index 00000000..36740ca1 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/AuthorServiceImpl.java @@ -0,0 +1,19 @@ +package ru.otus.hw.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.hw.models.Author; +import ru.otus.hw.repositories.AuthorRepository; + +import java.util.List; + +@RequiredArgsConstructor +@Service +public class AuthorServiceImpl implements AuthorService { + private final AuthorRepository authorRepository; + + @Override + public List findAll() { + return authorRepository.findAll(); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookService.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookService.java new file mode 100644 index 00000000..f9230908 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookService.java @@ -0,0 +1,18 @@ +package ru.otus.hw.services; + +import ru.otus.hw.models.Book; + +import java.util.List; +import java.util.Optional; + +public interface BookService { + Optional findById(long id); + + List findAll(); + + Book insert(String title, long authorId, long genreId); + + Book update(long id, String title, long authorId, long genreId); + + void deleteById(long id); +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java new file mode 100644 index 00000000..d4627c95 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/BookServiceImpl.java @@ -0,0 +1,56 @@ +package ru.otus.hw.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.hw.exceptions.EntityNotFoundException; +import ru.otus.hw.models.Book; +import ru.otus.hw.repositories.AuthorRepository; +import ru.otus.hw.repositories.BookRepository; +import ru.otus.hw.repositories.GenreRepository; + +import java.util.List; +import java.util.Optional; + +@RequiredArgsConstructor +@Service +public class BookServiceImpl implements BookService { + private final AuthorRepository authorRepository; + + private final GenreRepository genreRepository; + + private final BookRepository bookRepository; + + @Override + public Optional findById(long id) { + return bookRepository.findById(id); + } + + @Override + public List findAll() { + return bookRepository.findAll(); + } + + @Override + public Book insert(String title, long authorId, long genreId) { + return save(0, title, authorId, genreId); + } + + @Override + public Book update(long id, String title, long authorId, long genreId) { + return save(id, title, authorId, genreId); + } + + @Override + public void deleteById(long id) { + bookRepository.deleteById(id); + } + + private Book save(long id, String title, long authorId, long genreId) { + var author = authorRepository.findById(authorId) + .orElseThrow(() -> new EntityNotFoundException("Author with id %d not found".formatted(authorId))); + var genre = genreRepository.findById(genreId) + .orElseThrow(() -> new EntityNotFoundException("Genre with id %d not found".formatted(genreId))); + var book = new Book(id, title, author, genre); + return bookRepository.save(book); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreService.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreService.java new file mode 100644 index 00000000..3fd4170b --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreService.java @@ -0,0 +1,9 @@ +package ru.otus.hw.services; + +import ru.otus.hw.models.Genre; + +import java.util.List; + +public interface GenreService { + List findAll(); +} diff --git a/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java new file mode 100644 index 00000000..8d1f620a --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/java/ru/otus/hw/services/GenreServiceImpl.java @@ -0,0 +1,19 @@ +package ru.otus.hw.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.hw.models.Genre; +import ru.otus.hw.repositories.GenreRepository; + +import java.util.List; + +@RequiredArgsConstructor +@Service +public class GenreServiceImpl implements GenreService { + private final GenreRepository genreRepository; + + @Override + public List findAll() { + return genreRepository.findAll(); + } +} diff --git a/templates/hw05-jdbc-simple-template/src/main/resources/application.yml b/templates/hw05-jdbc-simple-template/src/main/resources/application.yml new file mode 100644 index 00000000..c037758d --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + datasource: + url: jdbc:h2:mem:maindb + sql: + init: + mode: always + data-locations: data.sql + schema-locations: schema.sql \ No newline at end of file diff --git a/templates/hw05-jdbc-simple-template/src/main/resources/data.sql b/templates/hw05-jdbc-simple-template/src/main/resources/data.sql new file mode 100644 index 00000000..13b890e6 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/resources/data.sql @@ -0,0 +1,8 @@ +insert into authors(full_name) +values ('Author_1'), ('Author_2'), ('Author_3'); + +insert into genres(name) +values ('Genre_1'), ('Genre_2'), ('Genre_3'); + +insert into books(title, author_id, genre_id) +values ('BookTitle_1', 1, 1), ('BookTitle_2', 2, 2), ('BookTitle_3', 3, 3); diff --git a/templates/hw05-jdbc-simple-template/src/main/resources/schema.sql b/templates/hw05-jdbc-simple-template/src/main/resources/schema.sql new file mode 100644 index 00000000..d590a44b --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +create table authors ( + id bigserial, + full_name varchar(255), + primary key (id) +); + +create table genres ( + id bigserial, + name varchar(255), + primary key (id) +); + +create table books ( + id bigserial, + title varchar(255), + author_id bigint references authors (id) on delete cascade, + genre_id bigint references genres(id) on delete cascade, + primary key (id) +); \ No newline at end of file diff --git a/templates/hw05-jdbc-simple-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java b/templates/hw05-jdbc-simple-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java new file mode 100644 index 00000000..10e1b640 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/test/java/ru/otus/hw/repositories/BookRepositoryJdbcTest.java @@ -0,0 +1,128 @@ +package ru.otus.hw.repositories; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; +import ru.otus.hw.models.Author; +import ru.otus.hw.models.Book; +import ru.otus.hw.models.Genre; + +import java.util.List; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("Репозиторий на основе Jdbc для работы с книгами ") +@JdbcTest +@Import({BookRepositoryJdbc.class, GenreRepositoryJdbc.class}) +class BookRepositoryJdbcTest { + + @Autowired + private BookRepositoryJdbc repositoryJdbc; + + private List dbAuthors; + + private List dbGenres; + + private List dbBooks; + + @BeforeEach + void setUp() { + dbAuthors = getDbAuthors(); + dbGenres = getDbGenres(); + dbBooks = getDbBooks(dbAuthors, dbGenres); + } + + @DisplayName("должен загружать книгу по id") + @ParameterizedTest + @MethodSource("getDbBooks") + void shouldReturnCorrectBookById(Book expectedBook) { + var actualBook = repositoryJdbc.findById(expectedBook.getId()); + assertThat(actualBook).isPresent() + .get() + .isEqualTo(expectedBook); + } + + @DisplayName("должен загружать список всех книг") + @Test + void shouldReturnCorrectBooksList() { + var actualBooks = repositoryJdbc.findAll(); + var expectedBooks = dbBooks; + + assertThat(actualBooks).containsExactlyElementsOf(expectedBooks); + actualBooks.forEach(System.out::println); + } + + @DisplayName("должен сохранять новую книгу") + @Test + void shouldSaveNewBook() { + var expectedBook = new Book(0, "BookTitle_10500", dbAuthors.get(0), dbGenres.get(0)); + var returnedBook = repositoryJdbc.save(expectedBook); + assertThat(returnedBook).isNotNull() + .matches(book -> book.getId() > 0) + .usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedBook); + + assertThat(repositoryJdbc.findById(returnedBook.getId())) + .isPresent() + .get() + .isEqualTo(returnedBook); + } + + @DisplayName("должен сохранять измененную книгу") + @Test + void shouldSaveUpdatedBook() { + var expectedBook = new Book(1L, "BookTitle_10500", dbAuthors.get(2), dbGenres.get(2)); + + assertThat(repositoryJdbc.findById(expectedBook.getId())) + .isPresent() + .get() + .isNotEqualTo(expectedBook); + + var returnedBook = repositoryJdbc.save(expectedBook); + assertThat(returnedBook).isNotNull() + .matches(book -> book.getId() > 0) + .usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(expectedBook); + + assertThat(repositoryJdbc.findById(returnedBook.getId())) + .isPresent() + .get() + .isEqualTo(returnedBook); + } + + @DisplayName("должен удалять книгу по id ") + @Test + void shouldDeleteBook() { + assertThat(repositoryJdbc.findById(1L)).isPresent(); + repositoryJdbc.deleteById(1L); + assertThat(repositoryJdbc.findById(1L)).isEmpty(); + } + + private static List getDbAuthors() { + return IntStream.range(1, 4).boxed() + .map(id -> new Author(id, "Author_" + id)) + .toList(); + } + + private static List getDbGenres() { + return IntStream.range(1, 4).boxed() + .map(id -> new Genre(id, "Genre_" + id)) + .toList(); + } + + private static List getDbBooks(List dbAuthors, List dbGenres) { + return IntStream.range(1, 4).boxed() + .map(id -> new Book(id, "BookTitle_" + id, dbAuthors.get(id - 1), dbGenres.get(id - 1))) + .toList(); + } + + private static List getDbBooks() { + var dbAuthors = getDbAuthors(); + var dbGenres = getDbGenres(); + return getDbBooks(dbAuthors, dbGenres); + } +} \ No newline at end of file diff --git a/templates/hw05-jdbc-simple-template/src/test/resources/application.yml b/templates/hw05-jdbc-simple-template/src/test/resources/application.yml new file mode 100644 index 00000000..45c16b3d --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/test/resources/application.yml @@ -0,0 +1,8 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + sql: + init: + mode: always + data-locations: data.sql + schema-locations: schema.sql \ No newline at end of file diff --git a/templates/hw05-jdbc-simple-template/src/test/resources/data.sql b/templates/hw05-jdbc-simple-template/src/test/resources/data.sql new file mode 100644 index 00000000..13b890e6 --- /dev/null +++ b/templates/hw05-jdbc-simple-template/src/test/resources/data.sql @@ -0,0 +1,8 @@ +insert into authors(full_name) +values ('Author_1'), ('Author_2'), ('Author_3'); + +insert into genres(name) +values ('Genre_1'), ('Genre_2'), ('Genre_3'); + +insert into books(title, author_id, genre_id) +values ('BookTitle_1', 1, 1), ('BookTitle_2', 2, 2), ('BookTitle_3', 3, 3);