From 2dd30d9beef233892aaad55100ff4b7b87e807fe Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 22 Apr 2019 16:08:03 +0300 Subject: [PATCH 01/30] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +- pom.xml | 164 ++++++++++++++++++ .../java/ru/otus/mkulikov/Application.java | 26 +++ src/main/resources/application.yml | 3 + src/main/resources/banner.txt | 11 ++ 5 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 pom.xml create mode 100644 src/main/java/ru/otus/mkulikov/Application.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/banner.txt diff --git a/README.md b/README.md index e2cfdc7..943beb2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,9 @@ # OtusSpringHW-Library -Домашние задания по Spring для Otus с базами данных. + +Домашнее задание #5: +- Создать приложение хранящее информацию о книгах в библиотеке. +- Использовать Spring JDBC и реляционную базу. +- Опционально использовать настоящую реляционную БД, но можно использовать H2. +- Предусмотреть таблицы авторов, книг и жанров. +- Интерфейс на Spring Shell. +- Покрыть тестами, насколько это возможно. \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4973666 --- /dev/null +++ b/pom.xml @@ -0,0 +1,164 @@ + + + 4.0.0 + + home-work + + ru.otus.mkulikov + home-work + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + + + 8 + ${java.version} + ${java.version} + UTF-8 + + + + + net.sf.opencsv + opencsv + 2.3 + + + + javax.annotation + javax.annotation-api + 1.3.2 + + + + org.projectlombok + lombok + 1.18.4 + provided + + + + + junit + junit + 4.12 + test + + + + org.junit.jupiter + junit-jupiter-api + 5.3.2 + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.3.2 + test + + + + org.junit.platform + junit-platform-launcher + 1.4.1 + test + + + + + org.mockito + mockito-all + 1.10.19 + test + + + + + org.springframework.boot + spring-boot-starter + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + ${encoding} + + + + + org.apache.maven.plugins + maven-resources-plugin + + ${encoding} + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.0 + + + false + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + src/main/resources + + **/*.csv + **/*.properties + **/*.txt + **/*.yml + + false + + + + \ No newline at end of file diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java new file mode 100644 index 0000000..7572a2b --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -0,0 +1,26 @@ +package ru.otus.mkulikov; + +//import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.PropertySource; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 2019-03-14 + * Time: 15:27 + */ + +@SpringBootApplication +@PropertySource("classpath:application.yml") +@EnableConfigurationProperties +public class Application { + + public static void main(String[] args) { + ApplicationContext context = SpringApplication.run(Application.class); +// Console.main(args); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..6e8162e --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + banner: + location: "classpath:banner.txt" diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 0000000..1687640 --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,11 @@ + ___ ___ ___ ___ ___ + /\__\ /\ \ /\__\ /\ \ /\ \ + /:/ / /::\ \ /:/ / /::\ \ /::\ \ + /:/ / /:/\:\ \ /:/ / /:/\:\ \ /:/\ \ \ + /:/ / ___ /:/ \:\ \ /:/ / /::\~\:\ \ _\:\~\ \ \ + /:/__/ /\__\ /:/__/ \:\__\ /:/__/ /:/\:\ \:\__\ /\ \:\ \ \__\ + \:\ \ /:/ / \:\ \ /:/ / \:\ \ \:\~\:\ \/__/ \:\ \:\ \/__/ + \:\ /:/ / \:\ /:/ / \:\ \ \:\ \:\__\ \:\ \:\__\ + \:\/:/ / \:\/:/ / \:\ \ \:\ \/__/ \:\/:/ / + \::/ / \::/ / \:\__\ \:\__\ \::/ / + \/__/ \/__/ \/__/ \/__/ \/__/ \ No newline at end of file From 4533cd4f66e31c0e14839dab9f5bcf3cf5eb778b Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 23 May 2019 16:12:33 +0300 Subject: [PATCH 02/30] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82?= =?UTF-8?q?=D0=BE=D0=B2.=20-=20=D0=9C=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=BA=D0=B8=20=D0=B8=D0=B7=20?= =?UTF-8?q?=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D1=8B=20=D0=BA=D0=BD=D0=B8?= =?UTF-8?q?=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 27 ++++----- .../java/ru/otus/mkulikov/Application.java | 13 ++++- .../java/ru/otus/mkulikov/dao/BookDao.java | 19 +++++++ .../ru/otus/mkulikov/dao/BookDaoJdbc.java | 55 +++++++++++++++++++ .../java/ru/otus/mkulikov/domain/Book.java | 32 +++++++++++ src/main/resources/data.sql | 27 +++++++++ src/main/resources/schema.sql | 23 ++++++++ 7 files changed, 176 insertions(+), 20 deletions(-) create mode 100644 src/main/java/ru/otus/mkulikov/dao/BookDao.java create mode 100644 src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java create mode 100644 src/main/java/ru/otus/mkulikov/domain/Book.java create mode 100644 src/main/resources/data.sql create mode 100644 src/main/resources/schema.sql diff --git a/pom.xml b/pom.xml index 4973666..cde26b6 100644 --- a/pom.xml +++ b/pom.xml @@ -18,9 +18,6 @@ - 8 - ${java.version} - ${java.version} UTF-8 @@ -87,10 +84,10 @@ spring-boot-starter - - - - + + org.springframework.boot + spring-boot-starter-jdbc + org.springframework.boot @@ -105,11 +102,11 @@ - - - - - + + com.h2database + h2 + 1.4.199 + @@ -117,11 +114,6 @@ org.apache.maven.plugins maven-compiler-plugin - - ${java.version} - ${java.version} - ${encoding} - @@ -156,6 +148,7 @@ **/*.properties **/*.txt **/*.yml + **/*.sql false diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index 7572a2b..7b6cb8d 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -1,11 +1,14 @@ package ru.otus.mkulikov; -//import org.h2.tools.Console; +import org.h2.tools.Console; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.PropertySource; +import ru.otus.mkulikov.dao.BookDao; +import ru.otus.mkulikov.domain.Book; + /** * Created by IntelliJ IDEA. @@ -19,8 +22,12 @@ @EnableConfigurationProperties public class Application { - public static void main(String[] args) { + public static void main(String[] args) throws Exception { ApplicationContext context = SpringApplication.run(Application.class); -// Console.main(args); + BookDao dao = context.getBean(BookDao.class); + + Book book = dao.getBookById(1); + + Console.main(args); } } diff --git a/src/main/java/ru/otus/mkulikov/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/dao/BookDao.java new file mode 100644 index 0000000..6fafa79 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/dao/BookDao.java @@ -0,0 +1,19 @@ +package ru.otus.mkulikov.dao; + +import ru.otus.mkulikov.domain.Book; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 13:28 + */ + +public interface BookDao { + + Book getBookById(Integer id); + + List getAllBooks(); +} diff --git a/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java new file mode 100644 index 0000000..2aeffcc --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java @@ -0,0 +1,55 @@ +package ru.otus.mkulikov.dao; + +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.mkulikov.domain.Book; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 13:28 + */ + +@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) +@Repository +public class BookDaoJdbc implements BookDao { + + private final JdbcOperations jdbcOperations; + + public BookDaoJdbc(JdbcOperations jdbcOperations) { + this.jdbcOperations = jdbcOperations; + } + + @Override + public Book getBookById(Integer id) { + return jdbcOperations.queryForObject("select * from Book where id = ? ", new Object[]{id}, new BookMapper()); + } + + @Override + public List getAllBooks() { + return jdbcOperations.query("select * from Book", new BookMapper()); + } + + public static class BookMapper implements RowMapper { + + @Override + public Book mapRow(ResultSet resultSet, int i) throws SQLException { + int id = resultSet.getInt("ID"); + Date add_record_date = resultSet.getDate("ADD_RECORD_DATE"); + String caption = resultSet.getString("CAPTION"); + int author_id = resultSet.getInt("AUTHOR_ID"); + int genre_id = resultSet.getInt("GENRE_ID"); + String comment = resultSet.getString("COMMENT"); + + return new Book(id, add_record_date, caption, author_id, genre_id, comment); + } + } +} + diff --git a/src/main/java/ru/otus/mkulikov/domain/Book.java b/src/main/java/ru/otus/mkulikov/domain/Book.java new file mode 100644 index 0000000..81614de --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/domain/Book.java @@ -0,0 +1,32 @@ +package ru.otus.mkulikov.domain; + +import lombok.Data; + +import java.util.Date; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 13:28 + */ + +@Data +public class Book { + + private final int id; + private final Date add_record_date; + private final String caption; + private final int author_id; + private final int genre_id; + private final String comment; + + public Book(int id, Date add_record_date, String caption, int author_id, int genre_id, String comment) { + this.id = id; + this.add_record_date = add_record_date; + this.caption = caption; + this.author_id = author_id; + this.genre_id = genre_id; + this.comment = comment; + } +} diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..d9af4d1 --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,27 @@ +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (1, 'Surname1', 'FirstName1', 'SecondName1'); + +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (2, 'Surname2', 'FirstName2', 'SecondName2'); + +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (3, 'Surname3', 'FirstName3', 'SecondName3'); + +-------------------------- + +insert into GENRE (ID, NAME) values (1, 'Genre1'); +insert into GENRE (ID, NAME) values (2, 'Genre2'); +insert into GENRE (ID, NAME) values (3, 'Genre3'); + +-------------------------- + +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (1, sysdate, 'book_1', 1, 1, 'comment'); + +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (2, sysdate, 'book_2', 1, 1, 'comment'); + +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (3, sysdate, 'book_3', 1, 1, 'comment'); + +-------------------------- diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000..6771ddc --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,23 @@ +DROP TABLE IF EXISTS BOOK; +CREATE TABLE BOOK( + ID INT PRIMARY KEY, + ADD_RECORD_DATE DATE, + CAPTION VARCHAR(255), + AUTHOR_ID INT, + GENRE_ID INT, + COMMENT VARCHAR(255) +); + +DROP TABLE IF EXISTS AUTHOR; +CREATE TABLE AUTHOR( + ID INT PRIMARY KEY, + SURNAME VARCHAR(100), + FIRST_NAME VARCHAR(100), + SECOND_NAME VARCHAR(100) +); + +DROP TABLE IF EXISTS GENRE; +CREATE TABLE GENRE( + ID INT PRIMARY KEY, + NAME VARCHAR(100), +); \ No newline at end of file From 628b8ae8bd180149fd365d799ee91c1280b9c624 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 23 May 2019 18:19:49 +0300 Subject: [PATCH 03/30] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20dao=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D0=B2.=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20Spring=20Shell.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 ++ .../java/ru/otus/mkulikov/Application.java | 15 ++--- .../java/ru/otus/mkulikov/dao/AuthorDao.java | 20 +++++++ .../ru/otus/mkulikov/dao/AuthorDaoJdbc.java | 38 ++++++++++++ .../java/ru/otus/mkulikov/dao/BookDao.java | 10 +++- .../ru/otus/mkulikov/dao/BookDaoJdbc.java | 19 +++++- .../java/ru/otus/mkulikov/dao/GenreDao.java | 23 ++++++++ .../ru/otus/mkulikov/dao/GenreDaoJdbc.java | 59 +++++++++++++++++++ .../java/ru/otus/mkulikov/model/Author.java | 26 ++++++++ .../otus/mkulikov/{domain => model}/Book.java | 14 ++++- .../java/ru/otus/mkulikov/model/Genre.java | 22 +++++++ .../java/ru/otus/mkulikov/shell/Commands.java | 38 ++++++++++++ 12 files changed, 278 insertions(+), 12 deletions(-) create mode 100644 src/main/java/ru/otus/mkulikov/dao/AuthorDao.java create mode 100644 src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java create mode 100644 src/main/java/ru/otus/mkulikov/dao/GenreDao.java create mode 100644 src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java create mode 100644 src/main/java/ru/otus/mkulikov/model/Author.java rename src/main/java/ru/otus/mkulikov/{domain => model}/Book.java (63%) create mode 100644 src/main/java/ru/otus/mkulikov/model/Genre.java create mode 100644 src/main/java/ru/otus/mkulikov/shell/Commands.java diff --git a/pom.xml b/pom.xml index cde26b6..b77b838 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,12 @@ true + + org.springframework.shell + spring-shell-starter + 2.0.0.RELEASE + + com.h2database diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index 7b6cb8d..137b521 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -7,7 +7,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.PropertySource; import ru.otus.mkulikov.dao.BookDao; -import ru.otus.mkulikov.domain.Book; +import ru.otus.mkulikov.model.Book; /** @@ -23,11 +23,12 @@ public class Application { public static void main(String[] args) throws Exception { - ApplicationContext context = SpringApplication.run(Application.class); - BookDao dao = context.getBean(BookDao.class); - - Book book = dao.getBookById(1); - - Console.main(args); + SpringApplication.run(Application.class); + //ApplicationContext context = SpringApplication.run(Application.class); + //BookDao dao = context.getBean(BookDao.class); + // + //Book book = dao.getById(1); + // + //Console.main(args); } } diff --git a/src/main/java/ru/otus/mkulikov/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/dao/AuthorDao.java new file mode 100644 index 0000000..3adf222 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/dao/AuthorDao.java @@ -0,0 +1,20 @@ +package ru.otus.mkulikov.dao; + +import ru.otus.mkulikov.model.Book; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:06 + */ + +public interface AuthorDao { + + int addObject(Book book); + + void deleteObject(Book book); + + int updateObject(Book book); + +} diff --git a/src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java new file mode 100644 index 0000000..ac5ed2d --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java @@ -0,0 +1,38 @@ +package ru.otus.mkulikov.dao; + +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.stereotype.Repository; +import ru.otus.mkulikov.model.Book; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:06 + */ + +@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) +@Repository +public class AuthorDaoJdbc implements AuthorDao { + + private final JdbcOperations jdbcOperations; + + public AuthorDaoJdbc(JdbcOperations jdbcOperations) { + this.jdbcOperations = jdbcOperations; + } + + @Override + public int addObject(Book book) { + return 0; + } + + @Override + public void deleteObject(Book book) { + + } + + @Override + public int updateObject(Book book) { + return 0; + } +} diff --git a/src/main/java/ru/otus/mkulikov/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/dao/BookDao.java index 6fafa79..4f03017 100644 --- a/src/main/java/ru/otus/mkulikov/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/dao/BookDao.java @@ -1,6 +1,6 @@ package ru.otus.mkulikov.dao; -import ru.otus.mkulikov.domain.Book; +import ru.otus.mkulikov.model.Book; import java.util.List; @@ -13,7 +13,13 @@ public interface BookDao { - Book getBookById(Integer id); + Book getById(int id); List getAllBooks(); + + int addObject(Book book); + + void deleteObject(Book book); + + int updateObject(Book book); } diff --git a/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java index 2aeffcc..7875943 100644 --- a/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java @@ -3,7 +3,7 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; -import ru.otus.mkulikov.domain.Book; +import ru.otus.mkulikov.model.Book; import java.sql.ResultSet; import java.sql.SQLException; @@ -28,7 +28,7 @@ public BookDaoJdbc(JdbcOperations jdbcOperations) { } @Override - public Book getBookById(Integer id) { + public Book getById(int id) { return jdbcOperations.queryForObject("select * from Book where id = ? ", new Object[]{id}, new BookMapper()); } @@ -37,6 +37,21 @@ public List getAllBooks() { return jdbcOperations.query("select * from Book", new BookMapper()); } + @Override + public int addObject(Book book) { + return 0; + } + + @Override + public void deleteObject(Book book) { + + } + + @Override + public int updateObject(Book book) { + return 0; + } + public static class BookMapper implements RowMapper { @Override diff --git a/src/main/java/ru/otus/mkulikov/dao/GenreDao.java b/src/main/java/ru/otus/mkulikov/dao/GenreDao.java new file mode 100644 index 0000000..2d00b50 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/dao/GenreDao.java @@ -0,0 +1,23 @@ +package ru.otus.mkulikov.dao; + +import ru.otus.mkulikov.model.Book; +import ru.otus.mkulikov.model.Genre; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:07 + */ + +public interface GenreDao { + + Genre getById(int id); + + int addObject(Book book); + + void deleteObject(Book book); + + int updateObject(Book book); + +} diff --git a/src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java new file mode 100644 index 0000000..6def4fa --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java @@ -0,0 +1,59 @@ +package ru.otus.mkulikov.dao; + +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.mkulikov.model.Book; +import ru.otus.mkulikov.model.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:07 + */ + +@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) +@Repository +public class GenreDaoJdbc implements GenreDao { + + private final JdbcOperations jdbcOperations; + + public GenreDaoJdbc(JdbcOperations jdbcOperations) { + this.jdbcOperations = jdbcOperations; + } + + @Override + public Genre getById(int id) { + return jdbcOperations.queryForObject("select * from Genre where id = ? ", new Object[]{id}, new GenreMapper()); + } + + @Override + public int addObject(Book book) { + return 0; + } + + @Override + public void deleteObject(Book book) { + + } + + @Override + public int updateObject(Book book) { + return 0; + } + + public static class GenreMapper implements RowMapper { + + @Override + public Genre mapRow(ResultSet resultSet, int i) throws SQLException { + int id = resultSet.getInt("ID"); + String name = resultSet.getString("NAME"); + + return new Genre(id, name); + } + } +} diff --git a/src/main/java/ru/otus/mkulikov/model/Author.java b/src/main/java/ru/otus/mkulikov/model/Author.java new file mode 100644 index 0000000..11412f3 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/model/Author.java @@ -0,0 +1,26 @@ +package ru.otus.mkulikov.model; + +import lombok.Data; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:02 + */ + +@Data +public class Author { + + private final int id; + private final String surname; + private final String first_name; + private final String second_name; + + public Author(int id, String surname, String first_name, String second_name) { + this.id = id; + this.surname = surname; + this.first_name = first_name; + this.second_name = second_name; + } +} diff --git a/src/main/java/ru/otus/mkulikov/domain/Book.java b/src/main/java/ru/otus/mkulikov/model/Book.java similarity index 63% rename from src/main/java/ru/otus/mkulikov/domain/Book.java rename to src/main/java/ru/otus/mkulikov/model/Book.java index 81614de..6b34dc1 100644 --- a/src/main/java/ru/otus/mkulikov/domain/Book.java +++ b/src/main/java/ru/otus/mkulikov/model/Book.java @@ -1,4 +1,4 @@ -package ru.otus.mkulikov.domain; +package ru.otus.mkulikov.model; import lombok.Data; @@ -29,4 +29,16 @@ public Book(int id, Date add_record_date, String caption, int author_id, int gen this.genre_id = genre_id; this.comment = comment; } + + @Override + public String toString() { + return "Book{" + + "id=" + id + + ", add_record_date=" + add_record_date + + ", caption='" + caption + '\'' + + ", author_id=" + author_id + + ", genre_id=" + genre_id + + ", comment='" + comment + '\'' + + '}'; + } } diff --git a/src/main/java/ru/otus/mkulikov/model/Genre.java b/src/main/java/ru/otus/mkulikov/model/Genre.java new file mode 100644 index 0000000..7da3b68 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/model/Genre.java @@ -0,0 +1,22 @@ +package ru.otus.mkulikov.model; + +import lombok.Data; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:04 + */ + +@Data +public class Genre { + + private final int id; + private final String name; + + public Genre(int id, String name) { + this.id = id; + this.name = name; + } +} \ No newline at end of file diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java new file mode 100644 index 0000000..e79cf7f --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -0,0 +1,38 @@ +package ru.otus.mkulikov.shell; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellOption; +import ru.otus.mkulikov.dao.AuthorDao; +import ru.otus.mkulikov.dao.BookDao; +import ru.otus.mkulikov.dao.GenreDao; +import ru.otus.mkulikov.model.Book; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:33 + */ + +@ShellComponent +public class Commands { + + private final AuthorDao authorDao; + private final BookDao bookDao; + private final GenreDao genreDao; + + @Autowired + public Commands(AuthorDao authorDao, BookDao bookDao, GenreDao genreDao) { + this.authorDao = authorDao; + this.bookDao = bookDao; + this.genreDao = genreDao; + } + + @ShellMethod(key = { "getBookById" }, value = "Select book by id.") + public String getBookById(@ShellOption String id) { + Book book = bookDao.getById(Integer.parseInt(id)); + return book.toString(); + } +} From b782bf356edf5253c3ff1774a427cae456bbab3c Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Fri, 24 May 2019 14:37:09 +0300 Subject: [PATCH 04/30] =?UTF-8?q?=D0=A7=D1=82=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B2=D0=B2=D0=BE=D0=B4=D0=B8=D0=BC=D1=8B=D1=85=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/shell/Commands.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java index e79cf7f..31343e4 100644 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -1,5 +1,6 @@ package ru.otus.mkulikov.shell; +import org.jline.reader.LineReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.shell.standard.ShellComponent; import org.springframework.shell.standard.ShellMethod; @@ -23,6 +24,9 @@ public class Commands { private final BookDao bookDao; private final GenreDao genreDao; + @Autowired + private LineReader reader; + @Autowired public Commands(AuthorDao authorDao, BookDao bookDao, GenreDao genreDao) { this.authorDao = authorDao; @@ -30,9 +34,36 @@ public Commands(AuthorDao authorDao, BookDao bookDao, GenreDao genreDao) { this.genreDao = genreDao; } + public String write(String text) { + return this.reader.readLine("\n" + text + " > "); + } + @ShellMethod(key = { "getBookById" }, value = "Select book by id.") public String getBookById(@ShellOption String id) { Book book = bookDao.getById(Integer.parseInt(id)); return book.toString(); } + + @ShellMethod(key = { "setService", "select" }, value = "Choose a Speech to Text Service") + public void setService() { + boolean success = false; + do { + String question = "Please select a service."; + + // Get Input + String input = this.write(question); + if ("1".equals(input)) { + this.write("OK"); + } else { + this.write("NO"); + } + + // Input handling + /* + * do something with input variable + */ + success = true; + + } while (!success); + } } From 56ba6a0c4f1e2d2f850c11ae34e889b197527037 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Fri, 24 May 2019 16:27:52 +0300 Subject: [PATCH 05/30] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B8=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B5=D0=B9?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ru/otus/mkulikov/Application.java | 6 ------ src/main/java/ru/otus/mkulikov/model/Author.java | 10 ++++++++++ src/main/java/ru/otus/mkulikov/model/Book.java | 2 +- src/main/java/ru/otus/mkulikov/model/Genre.java | 8 ++++++++ src/main/java/ru/otus/mkulikov/shell/Commands.java | 11 +++++++++++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index 137b521..d6e34bc 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -6,8 +6,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.PropertySource; -import ru.otus.mkulikov.dao.BookDao; -import ru.otus.mkulikov.model.Book; /** @@ -25,10 +23,6 @@ public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class); //ApplicationContext context = SpringApplication.run(Application.class); - //BookDao dao = context.getBean(BookDao.class); - // - //Book book = dao.getById(1); - // //Console.main(args); } } diff --git a/src/main/java/ru/otus/mkulikov/model/Author.java b/src/main/java/ru/otus/mkulikov/model/Author.java index 11412f3..d316b84 100644 --- a/src/main/java/ru/otus/mkulikov/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/model/Author.java @@ -23,4 +23,14 @@ public Author(int id, String surname, String first_name, String second_name) { this.first_name = first_name; this.second_name = second_name; } + + @Override + public String toString() { + return "Author{" + + "id=" + id + + ", surname='" + surname + '\'' + + ", first_name='" + first_name + '\'' + + ", second_name='" + second_name + '\'' + + "}\n"; + } } diff --git a/src/main/java/ru/otus/mkulikov/model/Book.java b/src/main/java/ru/otus/mkulikov/model/Book.java index 6b34dc1..c3dd013 100644 --- a/src/main/java/ru/otus/mkulikov/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/model/Book.java @@ -39,6 +39,6 @@ public String toString() { ", author_id=" + author_id + ", genre_id=" + genre_id + ", comment='" + comment + '\'' + - '}'; + "}\n"; } } diff --git a/src/main/java/ru/otus/mkulikov/model/Genre.java b/src/main/java/ru/otus/mkulikov/model/Genre.java index 7da3b68..5881406 100644 --- a/src/main/java/ru/otus/mkulikov/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/model/Genre.java @@ -19,4 +19,12 @@ public Genre(int id, String name) { this.id = id; this.name = name; } + + @Override + public String toString() { + return "Genre{" + + "id=" + id + + ", name='" + name + '\'' + + "}\n"; + } } \ No newline at end of file diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java index 31343e4..6a6ca8b 100644 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -10,6 +10,8 @@ import ru.otus.mkulikov.dao.GenreDao; import ru.otus.mkulikov.model.Book; +import java.util.List; + /** * Created by IntelliJ IDEA. * Developer: Maksim Kulikov @@ -35,6 +37,8 @@ public Commands(AuthorDao authorDao, BookDao bookDao, GenreDao genreDao) { } public String write(String text) { + System.out.println("qweqwewqe"); + return this.reader.readLine("\n" + text + " > "); } @@ -44,6 +48,12 @@ public String getBookById(@ShellOption String id) { return book.toString(); } + @ShellMethod(key = { "getBooks" }, value = "Select book by id.") + public String getBooks() { + List allBooks = bookDao.getAllBooks(); + return allBooks.toString(); + } + @ShellMethod(key = { "setService", "select" }, value = "Choose a Speech to Text Service") public void setService() { boolean success = false; @@ -52,6 +62,7 @@ public void setService() { // Get Input String input = this.write(question); + if ("1".equals(input)) { this.write("OK"); } else { From f8f5da19abb7c3ff0a42f7fbe660abba73e92c7a Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 27 May 2019 13:53:53 +0300 Subject: [PATCH 06/30] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20DAO=20=D0=B4=D0=BB=D1=8F=20=D1=82?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=B8=20=D0=B6=D0=B0=D0=BD=D1=80=D0=BE=D0=B2.?= =?UTF-8?q?=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20Shell=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mkulikov/{ => app}/dao/AuthorDao.java | 12 ++- .../otus/mkulikov/app/dao/AuthorDaoJdbc.java | 65 +++++++++++++++ .../otus/mkulikov/{ => app}/dao/BookDao.java | 6 +- .../mkulikov/{ => app}/dao/BookDaoJdbc.java | 14 ++-- .../otus/mkulikov/{ => app}/dao/GenreDao.java | 11 ++- .../mkulikov/{ => app}/dao/GenreDaoJdbc.java | 18 ++-- .../otus/mkulikov/{ => app}/model/Author.java | 2 +- .../otus/mkulikov/{ => app}/model/Book.java | 2 +- .../otus/mkulikov/{ => app}/model/Genre.java | 2 +- .../app/services/BooksManageSevice.java | 29 +++++++ .../app/services/BooksManageSeviceImpl.java | 54 ++++++++++++ .../ru/otus/mkulikov/dao/AuthorDaoJdbc.java | 38 --------- .../java/ru/otus/mkulikov/shell/Commands.java | 83 ++++++++----------- 13 files changed, 221 insertions(+), 115 deletions(-) rename src/main/java/ru/otus/mkulikov/{ => app}/dao/AuthorDao.java (53%) create mode 100644 src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java rename src/main/java/ru/otus/mkulikov/{ => app}/dao/BookDao.java (72%) rename src/main/java/ru/otus/mkulikov/{ => app}/dao/BookDaoJdbc.java (85%) rename src/main/java/ru/otus/mkulikov/{ => app}/dao/GenreDao.java (60%) rename src/main/java/ru/otus/mkulikov/{ => app}/dao/GenreDaoJdbc.java (78%) rename src/main/java/ru/otus/mkulikov/{ => app}/model/Author.java (95%) rename src/main/java/ru/otus/mkulikov/{ => app}/model/Book.java (96%) rename src/main/java/ru/otus/mkulikov/{ => app}/model/Genre.java (92%) create mode 100644 src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java create mode 100644 src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java delete mode 100644 src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java diff --git a/src/main/java/ru/otus/mkulikov/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java similarity index 53% rename from src/main/java/ru/otus/mkulikov/dao/AuthorDao.java rename to src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java index 3adf222..6026c67 100644 --- a/src/main/java/ru/otus/mkulikov/dao/AuthorDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java @@ -1,6 +1,9 @@ -package ru.otus.mkulikov.dao; +package ru.otus.mkulikov.app.dao; -import ru.otus.mkulikov.model.Book; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; + +import java.util.List; /** * Created by IntelliJ IDEA. @@ -11,10 +14,13 @@ public interface AuthorDao { + Author getById(int id); + + List getAllObjects(); + int addObject(Book book); void deleteObject(Book book); int updateObject(Book book); - } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java new file mode 100644 index 0000000..d31b889 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -0,0 +1,65 @@ +package ru.otus.mkulikov.app.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:06 + */ + +@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) +@Repository +@RequiredArgsConstructor +public class AuthorDaoJdbc implements AuthorDao { + + private final JdbcOperations jdbcOperations; + + @Override + public Author getById(int id) { + return jdbcOperations.queryForObject("select * from Author where id = ? ", new Object[]{id}, new AuthorMapper()); + } + + @Override + public List getAllObjects() { + return jdbcOperations.query("select * from Author", new AuthorMapper()); + } + + @Override + public int addObject(Book book) { + return 0; + } + + @Override + public void deleteObject(Book book) { + + } + + @Override + public int updateObject(Book book) { + return 0; + } + + private static class AuthorMapper implements RowMapper { + + @Override + public Author mapRow(ResultSet resultSet, int i) throws SQLException { + int id = resultSet.getInt("ID"); + String surname = resultSet.getString("SURNAME"); + String first_name = resultSet.getString("FIRST_NAME"); + String second_name = resultSet.getString("SECOND_NAME"); + + return new Author(id, surname, first_name, second_name); + } + } +} diff --git a/src/main/java/ru/otus/mkulikov/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java similarity index 72% rename from src/main/java/ru/otus/mkulikov/dao/BookDao.java rename to src/main/java/ru/otus/mkulikov/app/dao/BookDao.java index 4f03017..f73f7e3 100644 --- a/src/main/java/ru/otus/mkulikov/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java @@ -1,6 +1,6 @@ -package ru.otus.mkulikov.dao; +package ru.otus.mkulikov.app.dao; -import ru.otus.mkulikov.model.Book; +import ru.otus.mkulikov.app.model.Book; import java.util.List; @@ -15,7 +15,7 @@ public interface BookDao { Book getById(int id); - List getAllBooks(); + List getAllObjects(); int addObject(Book book); diff --git a/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java similarity index 85% rename from src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java rename to src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 7875943..6c73ab3 100644 --- a/src/main/java/ru/otus/mkulikov/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -1,9 +1,10 @@ -package ru.otus.mkulikov.dao; +package ru.otus.mkulikov.app.dao; +import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; -import ru.otus.mkulikov.model.Book; +import ru.otus.mkulikov.app.model.Book; import java.sql.ResultSet; import java.sql.SQLException; @@ -19,21 +20,18 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository +@RequiredArgsConstructor public class BookDaoJdbc implements BookDao { private final JdbcOperations jdbcOperations; - public BookDaoJdbc(JdbcOperations jdbcOperations) { - this.jdbcOperations = jdbcOperations; - } - @Override public Book getById(int id) { return jdbcOperations.queryForObject("select * from Book where id = ? ", new Object[]{id}, new BookMapper()); } @Override - public List getAllBooks() { + public List getAllObjects() { return jdbcOperations.query("select * from Book", new BookMapper()); } @@ -52,7 +50,7 @@ public int updateObject(Book book) { return 0; } - public static class BookMapper implements RowMapper { + private static class BookMapper implements RowMapper { @Override public Book mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/src/main/java/ru/otus/mkulikov/dao/GenreDao.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java similarity index 60% rename from src/main/java/ru/otus/mkulikov/dao/GenreDao.java rename to src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java index 2d00b50..95828bf 100644 --- a/src/main/java/ru/otus/mkulikov/dao/GenreDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java @@ -1,7 +1,9 @@ -package ru.otus.mkulikov.dao; +package ru.otus.mkulikov.app.dao; -import ru.otus.mkulikov.model.Book; -import ru.otus.mkulikov.model.Genre; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; /** * Created by IntelliJ IDEA. @@ -14,10 +16,11 @@ public interface GenreDao { Genre getById(int id); + List getAllObjects(); + int addObject(Book book); void deleteObject(Book book); int updateObject(Book book); - } diff --git a/src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java similarity index 78% rename from src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java rename to src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java index 6def4fa..154a5f7 100644 --- a/src/main/java/ru/otus/mkulikov/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java @@ -1,13 +1,15 @@ -package ru.otus.mkulikov.dao; +package ru.otus.mkulikov.app.dao; +import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; -import ru.otus.mkulikov.model.Book; -import ru.otus.mkulikov.model.Genre; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -18,19 +20,21 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository +@RequiredArgsConstructor public class GenreDaoJdbc implements GenreDao { private final JdbcOperations jdbcOperations; - public GenreDaoJdbc(JdbcOperations jdbcOperations) { - this.jdbcOperations = jdbcOperations; - } - @Override public Genre getById(int id) { return jdbcOperations.queryForObject("select * from Genre where id = ? ", new Object[]{id}, new GenreMapper()); } + @Override + public List getAllObjects() { + return jdbcOperations.query("select * from Genre", new GenreMapper()); + } + @Override public int addObject(Book book) { return 0; diff --git a/src/main/java/ru/otus/mkulikov/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java similarity index 95% rename from src/main/java/ru/otus/mkulikov/model/Author.java rename to src/main/java/ru/otus/mkulikov/app/model/Author.java index d316b84..f418720 100644 --- a/src/main/java/ru/otus/mkulikov/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -1,4 +1,4 @@ -package ru.otus.mkulikov.model; +package ru.otus.mkulikov.app.model; import lombok.Data; diff --git a/src/main/java/ru/otus/mkulikov/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java similarity index 96% rename from src/main/java/ru/otus/mkulikov/model/Book.java rename to src/main/java/ru/otus/mkulikov/app/model/Book.java index c3dd013..917daeb 100644 --- a/src/main/java/ru/otus/mkulikov/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -1,4 +1,4 @@ -package ru.otus.mkulikov.model; +package ru.otus.mkulikov.app.model; import lombok.Data; diff --git a/src/main/java/ru/otus/mkulikov/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java similarity index 92% rename from src/main/java/ru/otus/mkulikov/model/Genre.java rename to src/main/java/ru/otus/mkulikov/app/model/Genre.java index 5881406..5f507f3 100644 --- a/src/main/java/ru/otus/mkulikov/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -1,4 +1,4 @@ -package ru.otus.mkulikov.model; +package ru.otus.mkulikov.app.model; import lombok.Data; diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java new file mode 100644 index 0000000..c001499 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java @@ -0,0 +1,29 @@ +package ru.otus.mkulikov.app.services; + +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 27.05.2019 + * Time: 13:42 + */ + +public interface BooksManageSevice { + + Book getBookById(int id); + + List getBooks(); + + Author getAuthorById(int id); + + List getAuthors(); + + Genre getGenreById(int id); + + List getGenres(); +} diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java new file mode 100644 index 0000000..02dc424 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java @@ -0,0 +1,54 @@ +package ru.otus.mkulikov.app.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellOption; +import org.springframework.stereotype.Service; +import ru.otus.mkulikov.app.dao.AuthorDao; +import ru.otus.mkulikov.app.dao.BookDao; +import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 27.05.2019 + * Time: 13:42 + */ + +@Service +@RequiredArgsConstructor +public class BooksManageSeviceImpl implements BooksManageSevice { + + private final AuthorDao authorDao; + private final BookDao bookDao; + private final GenreDao genreDao; + + public Book getBookById(int id) { + return bookDao.getById(id); + } + + public List getBooks() { + return bookDao.getAllObjects(); + } + + public Author getAuthorById(int id) { + return authorDao.getById(id); + } + + public List getAuthors() { + return authorDao.getAllObjects(); + } + + public Genre getGenreById(int id) { + return genreDao.getById(id); + } + + public List getGenres() { + return genreDao.getAllObjects(); + } +} diff --git a/src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java deleted file mode 100644 index ac5ed2d..0000000 --- a/src/main/java/ru/otus/mkulikov/dao/AuthorDaoJdbc.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.otus.mkulikov.dao; - -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.stereotype.Repository; -import ru.otus.mkulikov.model.Book; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 23.05.2019 - * Time: 17:06 - */ - -@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) -@Repository -public class AuthorDaoJdbc implements AuthorDao { - - private final JdbcOperations jdbcOperations; - - public AuthorDaoJdbc(JdbcOperations jdbcOperations) { - this.jdbcOperations = jdbcOperations; - } - - @Override - public int addObject(Book book) { - return 0; - } - - @Override - public void deleteObject(Book book) { - - } - - @Override - public int updateObject(Book book) { - return 0; - } -} diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java index 6a6ca8b..9b7b023 100644 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -1,14 +1,16 @@ package ru.otus.mkulikov.shell; -import org.jline.reader.LineReader; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.shell.standard.ShellComponent; import org.springframework.shell.standard.ShellMethod; import org.springframework.shell.standard.ShellOption; -import ru.otus.mkulikov.dao.AuthorDao; -import ru.otus.mkulikov.dao.BookDao; -import ru.otus.mkulikov.dao.GenreDao; -import ru.otus.mkulikov.model.Book; +import ru.otus.mkulikov.app.dao.AuthorDao; +import ru.otus.mkulikov.app.dao.BookDao; +import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; +import ru.otus.mkulikov.app.services.BooksManageSevice; import java.util.List; @@ -20,61 +22,44 @@ */ @ShellComponent +@RequiredArgsConstructor public class Commands { - private final AuthorDao authorDao; - private final BookDao bookDao; - private final GenreDao genreDao; - - @Autowired - private LineReader reader; - - @Autowired - public Commands(AuthorDao authorDao, BookDao bookDao, GenreDao genreDao) { - this.authorDao = authorDao; - this.bookDao = bookDao; - this.genreDao = genreDao; - } - - public String write(String text) { - System.out.println("qweqwewqe"); - - return this.reader.readLine("\n" + text + " > "); - } + private final BooksManageSevice booksManageSevice; @ShellMethod(key = { "getBookById" }, value = "Select book by id.") - public String getBookById(@ShellOption String id) { - Book book = bookDao.getById(Integer.parseInt(id)); + public String getBookById(@ShellOption int id) { + Book book = booksManageSevice.getBookById(id); return book.toString(); } - @ShellMethod(key = { "getBooks" }, value = "Select book by id.") + @ShellMethod(key = { "getBooks" }, value = "Select all books.") public String getBooks() { - List allBooks = bookDao.getAllBooks(); - return allBooks.toString(); + List allObjects = booksManageSevice.getBooks(); + return allObjects.toString(); } - @ShellMethod(key = { "setService", "select" }, value = "Choose a Speech to Text Service") - public void setService() { - boolean success = false; - do { - String question = "Please select a service."; - - // Get Input - String input = this.write(question); + @ShellMethod(key = { "getAuthorById" }, value = "Select author by id.") + public String getAuthorById(@ShellOption int id) { + Author author = booksManageSevice.getAuthorById(id); + return author.toString(); + } - if ("1".equals(input)) { - this.write("OK"); - } else { - this.write("NO"); - } + @ShellMethod(key = { "getAuthors" }, value = "Select all authors.") + public String getAuthors() { + List allObjects = booksManageSevice.getAuthors(); + return allObjects.toString(); + } - // Input handling - /* - * do something with input variable - */ - success = true; + @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") + public String getGenreById(@ShellOption int id) { + Genre genre = booksManageSevice.getGenreById(id); + return genre.toString(); + } - } while (!success); + @ShellMethod(key = { "getGenres" }, value = "Select all genres.") + public String getGenres() { + List allObjects = booksManageSevice.getGenres(); + return allObjects.toString(); } } From 91e179e7b82a430a6f021439ea252a4d6ea00639 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 27 May 2019 17:19:19 +0300 Subject: [PATCH 07/30] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3,=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D1=85=20shell=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/app/dao/AuthorDao.java | 15 ++++++--------- .../ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java | 9 ++++----- .../java/ru/otus/mkulikov/app/dao/BookDao.java | 14 ++++++-------- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 2 +- .../java/ru/otus/mkulikov/app/dao/GenreDao.java | 15 ++++++--------- .../ru/otus/mkulikov/app/dao/GenreDaoJdbc.java | 11 +++++------ .../java/ru/otus/mkulikov/app/model/Author.java | 2 ++ .../java/ru/otus/mkulikov/app/model/Book.java | 2 ++ .../java/ru/otus/mkulikov/app/model/Genre.java | 2 ++ .../mkulikov/app/services/BooksManageSevice.java | 2 ++ .../app/services/BooksManageSeviceImpl.java | 12 +++++++----- .../java/ru/otus/mkulikov/shell/Commands.java | 9 ++++++--- 12 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java index 6026c67..a9b2fa6 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java @@ -1,8 +1,5 @@ package ru.otus.mkulikov.app.dao; -import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; - import java.util.List; /** @@ -12,15 +9,15 @@ * Time: 17:06 */ -public interface AuthorDao { +public interface AuthorDao { - Author getById(int id); + T getById(int id); - List getAllObjects(); + List getAllObjects(); - int addObject(Book book); + int addObject(T t); - void deleteObject(Book book); + void deleteObject(T t); - int updateObject(Book book); + int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java index d31b889..a7e58b7 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -5,7 +5,6 @@ import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; import java.sql.ResultSet; import java.sql.SQLException; @@ -21,7 +20,7 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository @RequiredArgsConstructor -public class AuthorDaoJdbc implements AuthorDao { +public class AuthorDaoJdbc implements AuthorDao { private final JdbcOperations jdbcOperations; @@ -36,17 +35,17 @@ public List getAllObjects() { } @Override - public int addObject(Book book) { + public int addObject(Author book) { return 0; } @Override - public void deleteObject(Book book) { + public void deleteObject(Author book) { } @Override - public int updateObject(Book book) { + public int updateObject(Author book) { return 0; } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java index f73f7e3..f183925 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java @@ -1,7 +1,5 @@ package ru.otus.mkulikov.app.dao; -import ru.otus.mkulikov.app.model.Book; - import java.util.List; /** @@ -11,15 +9,15 @@ * Time: 13:28 */ -public interface BookDao { +public interface BookDao { - Book getById(int id); + T getById(int id); - List getAllObjects(); + List getAllObjects(); - int addObject(Book book); + int addObject(T t); - void deleteObject(Book book); + void deleteObject(T t); - int updateObject(Book book); + int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 6c73ab3..5294b37 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -21,7 +21,7 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository @RequiredArgsConstructor -public class BookDaoJdbc implements BookDao { +public class BookDaoJdbc implements BookDao { private final JdbcOperations jdbcOperations; diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java index 95828bf..1b6d511 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java @@ -1,8 +1,5 @@ package ru.otus.mkulikov.app.dao; -import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Genre; - import java.util.List; /** @@ -12,15 +9,15 @@ * Time: 17:07 */ -public interface GenreDao { +public interface GenreDao { - Genre getById(int id); + T getById(int id); - List getAllObjects(); + List getAllObjects(); - int addObject(Book book); + int addObject(T t); - void deleteObject(Book book); + int deleteObject(int id); - int updateObject(Book book); + int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java index 154a5f7..b34193e 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java @@ -4,7 +4,6 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; -import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Genre; import java.sql.ResultSet; @@ -21,7 +20,7 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository @RequiredArgsConstructor -public class GenreDaoJdbc implements GenreDao { +public class GenreDaoJdbc implements GenreDao { private final JdbcOperations jdbcOperations; @@ -36,17 +35,17 @@ public List getAllObjects() { } @Override - public int addObject(Book book) { + public int addObject(Genre genre) { return 0; } @Override - public void deleteObject(Book book) { - + public int deleteObject(int id) { + return jdbcOperations.update("delete from Genre where id = ? ", new Object[]{id}); } @Override - public int updateObject(Book book) { + public int updateObject(Genre genre) { return 0; } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index f418720..2bba880 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -7,6 +7,8 @@ * Developer: Maksim Kulikov * Date: 23.05.2019 * Time: 17:02 + * + * Сущность таблицы авторов */ @Data diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 917daeb..4d31e82 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -9,6 +9,8 @@ * Developer: Maksim Kulikov * Date: 23.05.2019 * Time: 13:28 + * + * Сущность таблицы книг */ @Data diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 5f507f3..9ba35ce 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -7,6 +7,8 @@ * Developer: Maksim Kulikov * Date: 23.05.2019 * Time: 17:04 + * + * Сущность таблицы жанров */ @Data diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java index c001499..b4bf2b4 100644 --- a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java @@ -26,4 +26,6 @@ public interface BooksManageSevice { Genre getGenreById(int id); List getGenres(); + + int deleteGenre(int id); } diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java index 02dc424..974b517 100644 --- a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java @@ -1,8 +1,6 @@ package ru.otus.mkulikov.app.services; import lombok.RequiredArgsConstructor; -import org.springframework.shell.standard.ShellMethod; -import org.springframework.shell.standard.ShellOption; import org.springframework.stereotype.Service; import ru.otus.mkulikov.app.dao.AuthorDao; import ru.otus.mkulikov.app.dao.BookDao; @@ -24,9 +22,9 @@ @RequiredArgsConstructor public class BooksManageSeviceImpl implements BooksManageSevice { - private final AuthorDao authorDao; - private final BookDao bookDao; - private final GenreDao genreDao; + private final AuthorDao authorDao; + private final BookDao bookDao; + private final GenreDao genreDao; public Book getBookById(int id) { return bookDao.getById(id); @@ -51,4 +49,8 @@ public Genre getGenreById(int id) { public List getGenres() { return genreDao.getAllObjects(); } + + public int deleteGenre(int id) { + return genreDao.deleteObject(id); + } } diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java index 9b7b023..7d5506b 100644 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -4,9 +4,6 @@ import org.springframework.shell.standard.ShellComponent; import org.springframework.shell.standard.ShellMethod; import org.springframework.shell.standard.ShellOption; -import ru.otus.mkulikov.app.dao.AuthorDao; -import ru.otus.mkulikov.app.dao.BookDao; -import ru.otus.mkulikov.app.dao.GenreDao; import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Genre; @@ -62,4 +59,10 @@ public String getGenres() { List allObjects = booksManageSevice.getGenres(); return allObjects.toString(); } + + @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") + public String deleteGenre(@ShellOption int id) { + int count = booksManageSevice.deleteGenre(id); + return "Deleted " + count + " row(s)"; + } } From eaed856a29d059c12ac5329a6bee8f47b63fab46 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 27 May 2019 17:57:09 +0300 Subject: [PATCH 08/30] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/mkulikov/app/dao/GenreDaoJdbc.java | 6 +- .../ru/otus/mkulikov/app/model/Genre.java | 5 ++ .../app/services/BooksManageSevice.java | 4 ++ .../app/services/BooksManageSeviceImpl.java | 8 +++ .../java/ru/otus/mkulikov/shell/Commands.java | 60 +++++++++++++------ src/main/resources/data.sql | 30 +++++----- src/main/resources/schema.sql | 8 +-- 7 files changed, 81 insertions(+), 40 deletions(-) diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java index b34193e..1535ff7 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java @@ -36,17 +36,17 @@ public List getAllObjects() { @Override public int addObject(Genre genre) { - return 0; + return jdbcOperations.update("insert into Genre (name) values (?)", new Object[]{genre.getName()}); } @Override public int deleteObject(int id) { - return jdbcOperations.update("delete from Genre where id = ? ", new Object[]{id}); + return jdbcOperations.update("delete from Genre where id = ? ", new Object[]{id}); } @Override public int updateObject(Genre genre) { - return 0; + return jdbcOperations.update("update Genre set name = ? where id = ? ", new Object[]{genre.getName(), genre.getId()}); } public static class GenreMapper implements RowMapper { diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 9ba35ce..8f8a011 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -22,6 +22,11 @@ public Genre(int id, String name) { this.name = name; } + public Genre(String name) { + this.id = 0; + this.name = name; + } + @Override public String toString() { return "Genre{" + diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java index b4bf2b4..018f904 100644 --- a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java @@ -27,5 +27,9 @@ public interface BooksManageSevice { List getGenres(); + int addGenre(String name); + + int updateGenre(int id, String name); + int deleteGenre(int id); } diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java index 974b517..3b9b036 100644 --- a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java @@ -50,6 +50,14 @@ public List getGenres() { return genreDao.getAllObjects(); } + public int addGenre(String name) { + return genreDao.addObject(new Genre(name)); + } + + public int updateGenre(int id, String name) { + return genreDao.updateObject(new Genre(id, name)); + } + public int deleteGenre(int id) { return genreDao.deleteObject(id); } diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java index 7d5506b..3a77778 100644 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -24,6 +24,44 @@ public class Commands { private final BooksManageSevice booksManageSevice; + /************** + * Жанры + */ + + @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") + public String getGenreById(@ShellOption int id) { + Genre genre = booksManageSevice.getGenreById(id); + return genre.toString(); + } + + @ShellMethod(key = { "getGenres" }, value = "Select all genres.") + public String getGenres() { + List allObjects = booksManageSevice.getGenres(); + return allObjects.toString(); + } + + @ShellMethod(key = { "addGenre" }, value = "Add new genre.") + public String addGenre(@ShellOption String name) { + int count = booksManageSevice.addGenre(name); + return "Add " + count + " row(s)"; + } + + @ShellMethod(key = { "updateGenre" }, value = "Update genre by id.") + public String updateGenre(@ShellOption int id, @ShellOption String name) { + int count = booksManageSevice.updateGenre(id, name); + return "Updated " + count + " row(s)"; + } + + @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") + public String deleteGenre(@ShellOption int id) { + int count = booksManageSevice.deleteGenre(id); + return "Deleted " + count + " row(s)"; + } + + /************** + * Книги + */ + @ShellMethod(key = { "getBookById" }, value = "Select book by id.") public String getBookById(@ShellOption int id) { Book book = booksManageSevice.getBookById(id); @@ -36,6 +74,10 @@ public String getBooks() { return allObjects.toString(); } + /************** + * Авторы + */ + @ShellMethod(key = { "getAuthorById" }, value = "Select author by id.") public String getAuthorById(@ShellOption int id) { Author author = booksManageSevice.getAuthorById(id); @@ -47,22 +89,4 @@ public String getAuthors() { List allObjects = booksManageSevice.getAuthors(); return allObjects.toString(); } - - @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") - public String getGenreById(@ShellOption int id) { - Genre genre = booksManageSevice.getGenreById(id); - return genre.toString(); - } - - @ShellMethod(key = { "getGenres" }, value = "Select all genres.") - public String getGenres() { - List allObjects = booksManageSevice.getGenres(); - return allObjects.toString(); - } - - @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") - public String deleteGenre(@ShellOption int id) { - int count = booksManageSevice.deleteGenre(id); - return "Deleted " + count + " row(s)"; - } } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index d9af4d1..e255fb4 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,27 +1,27 @@ -insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) -values (1, 'Surname1', 'FirstName1', 'SecondName1'); +insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) +values ('Surname1', 'FirstName1', 'SecondName1'); -insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) -values (2, 'Surname2', 'FirstName2', 'SecondName2'); +insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) +values ('Surname2', 'FirstName2', 'SecondName2'); -insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) -values (3, 'Surname3', 'FirstName3', 'SecondName3'); +insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) +values ('Surname3', 'FirstName3', 'SecondName3'); -------------------------- -insert into GENRE (ID, NAME) values (1, 'Genre1'); -insert into GENRE (ID, NAME) values (2, 'Genre2'); -insert into GENRE (ID, NAME) values (3, 'Genre3'); +insert into GENRE (NAME) values ('Genre1'); +insert into GENRE (NAME) values ('Genre2'); +insert into GENRE (NAME) values ('Genre3'); -------------------------- -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (1, sysdate, 'book_1', 1, 1, 'comment'); +insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (sysdate, 'book_1', 1, 1, 'comment'); -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (2, sysdate, 'book_2', 1, 1, 'comment'); +insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (sysdate, 'book_2', 1, 1, 'comment'); -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (3, sysdate, 'book_3', 1, 1, 'comment'); +insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (sysdate, 'book_3', 1, 1, 'comment'); -------------------------- diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 6771ddc..4f8c037 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,6 +1,6 @@ DROP TABLE IF EXISTS BOOK; CREATE TABLE BOOK( - ID INT PRIMARY KEY, + ID INT AUTO_INCREMENT PRIMARY KEY, ADD_RECORD_DATE DATE, CAPTION VARCHAR(255), AUTHOR_ID INT, @@ -10,7 +10,7 @@ CREATE TABLE BOOK( DROP TABLE IF EXISTS AUTHOR; CREATE TABLE AUTHOR( - ID INT PRIMARY KEY, + ID INT AUTO_INCREMENT PRIMARY KEY, SURNAME VARCHAR(100), FIRST_NAME VARCHAR(100), SECOND_NAME VARCHAR(100) @@ -18,6 +18,6 @@ CREATE TABLE AUTHOR( DROP TABLE IF EXISTS GENRE; CREATE TABLE GENRE( - ID INT PRIMARY KEY, - NAME VARCHAR(100), + ID INT AUTO_INCREMENT PRIMARY KEY, + NAME VARCHAR(100), ); \ No newline at end of file From 034a299c6a7125ff600013f71d0bacc8fc6cd747 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Tue, 28 May 2019 11:20:37 +0300 Subject: [PATCH 09/30] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20GenreDaoJdbc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/Application.java | 2 +- .../ru/otus/mkulikov/app/dao/AuthorDao.java | 4 +- .../otus/mkulikov/app/dao/AuthorDaoJdbc.java | 2 +- .../ru/otus/mkulikov/app/dao/BookDao.java | 4 +- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 2 +- .../ru/otus/mkulikov/app/dao/GenreDao.java | 4 +- .../otus/mkulikov/app/dao/GenreDaoJdbc.java | 6 +- .../ru/otus/mkulikov/app/model/Author.java | 7 ++ .../java/ru/otus/mkulikov/app/model/Book.java | 9 ++ .../BooksManageSevice.java | 2 +- .../BooksManageSeviceImpl.java | 8 +- .../java/ru/otus/mkulikov/shell/Commands.java | 2 +- .../java/ru/otus/mkulikov/AppTestConfig.java | 16 +++ .../mkulikov/app/dao/GenreDaoJdbcTest.java | 105 ++++++++++++++++++ src/test/resources/test_data.sql | 27 +++++ src/test/resources/test_schema.sql | 23 ++++ 16 files changed, 210 insertions(+), 13 deletions(-) rename src/main/java/ru/otus/mkulikov/app/{services => service}/BooksManageSevice.java (93%) rename src/main/java/ru/otus/mkulikov/app/{services => service}/BooksManageSeviceImpl.java (88%) create mode 100644 src/test/java/ru/otus/mkulikov/AppTestConfig.java create mode 100644 src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java create mode 100644 src/test/resources/test_data.sql create mode 100644 src/test/resources/test_schema.sql diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index d6e34bc..7760aa8 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -16,7 +16,7 @@ */ @SpringBootApplication -@PropertySource("classpath:application.yml") +//@PropertySource("classpath:application.yml") @EnableConfigurationProperties public class Application { diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java index a9b2fa6..ef336c7 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java @@ -1,5 +1,7 @@ package ru.otus.mkulikov.app.dao; +import ru.otus.mkulikov.app.model.Author; + import java.util.List; /** @@ -9,7 +11,7 @@ * Time: 17:06 */ -public interface AuthorDao { +public interface AuthorDao { T getById(int id); diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java index a7e58b7..6fa4789 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -31,7 +31,7 @@ public Author getById(int id) { @Override public List getAllObjects() { - return jdbcOperations.query("select * from Author", new AuthorMapper()); + return jdbcOperations.query("select * from Author order by id", new AuthorMapper()); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java index f183925..de461de 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java @@ -1,5 +1,7 @@ package ru.otus.mkulikov.app.dao; +import ru.otus.mkulikov.app.model.Book; + import java.util.List; /** @@ -9,7 +11,7 @@ * Time: 13:28 */ -public interface BookDao { +public interface BookDao { T getById(int id); diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 5294b37..1d13930 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -32,7 +32,7 @@ public Book getById(int id) { @Override public List getAllObjects() { - return jdbcOperations.query("select * from Book", new BookMapper()); + return jdbcOperations.query("select * from Book order by id", new BookMapper()); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java index 1b6d511..bffc90d 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java @@ -1,5 +1,7 @@ package ru.otus.mkulikov.app.dao; +import ru.otus.mkulikov.app.model.Genre; + import java.util.List; /** @@ -9,7 +11,7 @@ * Time: 17:07 */ -public interface GenreDao { +public interface GenreDao { T getById(int id); diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java index 1535ff7..2ee2fe5 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java @@ -1,11 +1,15 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import ru.otus.mkulikov.app.model.Genre; +import javax.annotation.PostConstruct; +import javax.sql.DataSource; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @@ -31,7 +35,7 @@ public Genre getById(int id) { @Override public List getAllObjects() { - return jdbcOperations.query("select * from Genre", new GenreMapper()); + return jdbcOperations.query("select * from Genre order by id", new GenreMapper()); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index 2bba880..489268f 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -26,6 +26,13 @@ public Author(int id, String surname, String first_name, String second_name) { this.second_name = second_name; } + public Author(String surname, String first_name, String second_name) { + this.id = 0; + this.surname = surname; + this.first_name = first_name; + this.second_name = second_name; + } + @Override public String toString() { return "Author{" + diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 4d31e82..c90e411 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -32,6 +32,15 @@ public Book(int id, Date add_record_date, String caption, int author_id, int gen this.comment = comment; } + public Book(Date add_record_date, String caption, int author_id, int genre_id, String comment) { + this.id = 0; + this.add_record_date = add_record_date; + this.caption = caption; + this.author_id = author_id; + this.genre_id = genre_id; + this.comment = comment; + } + @Override public String toString() { return "Book{" + diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java similarity index 93% rename from src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java rename to src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java index 018f904..e805c28 100644 --- a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java @@ -1,4 +1,4 @@ -package ru.otus.mkulikov.app.services; +package ru.otus.mkulikov.app.service; import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; diff --git a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java similarity index 88% rename from src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java rename to src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java index 3b9b036..ff57986 100644 --- a/src/main/java/ru/otus/mkulikov/app/services/BooksManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java @@ -1,4 +1,4 @@ -package ru.otus.mkulikov.app.services; +package ru.otus.mkulikov.app.service; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -22,9 +22,9 @@ @RequiredArgsConstructor public class BooksManageSeviceImpl implements BooksManageSevice { - private final AuthorDao authorDao; - private final BookDao bookDao; - private final GenreDao genreDao; + private final AuthorDao authorDao; + private final BookDao bookDao; + private final GenreDao genreDao; public Book getBookById(int id) { return bookDao.getById(id); diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java index 3a77778..a932e76 100644 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ b/src/main/java/ru/otus/mkulikov/shell/Commands.java @@ -7,7 +7,7 @@ import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Genre; -import ru.otus.mkulikov.app.services.BooksManageSevice; +import ru.otus.mkulikov.app.service.BooksManageSevice; import java.util.List; diff --git a/src/test/java/ru/otus/mkulikov/AppTestConfig.java b/src/test/java/ru/otus/mkulikov/AppTestConfig.java new file mode 100644 index 0000000..85f7510 --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/AppTestConfig.java @@ -0,0 +1,16 @@ +package ru.otus.mkulikov; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 28.05.2019 + * Time: 9:47 + */ + +@SpringBootConfiguration +@EnableConfigurationProperties +public class AppTestConfig { +} diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java new file mode 100644 index 0000000..82630d6 --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java @@ -0,0 +1,105 @@ +package ru.otus.mkulikov.app.dao; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 28.05.2019 + * Time: 9:45 + */ + +@DisplayName("Класс GenreDaoJdbc") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class GenreDaoJdbcTest { + + private GenreDaoJdbc genreDaoJdbc; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); + } + + @Test + void getById() { + Genre genre = genreDaoJdbc.getById(1); + + assertAll("genre", + () -> assertNotNull(genre), + () -> assertEquals(1, genre.getId()), + () -> assertEquals("Genre1", genre.getName()) + ); + } + + @Test + void getAllObjects() { + List genres = genreDaoJdbc.getAllObjects(); + + assertAll("genres", + () -> assertNotNull(genres), + () -> assertEquals(3, genres.size()), + () -> assertEquals("Genre1", genres.get(0).getName()), + () -> assertEquals("Genre2", genres.get(1).getName()), + () -> assertEquals("Genre3", genres.get(2).getName()) + ); + } + + @Test + void addObject() { + genreDaoJdbc.addObject(new Genre("Test4")); + + Genre genre = genreDaoJdbc.getById(4); + + assertAll("genre", + () -> assertNotNull(genre), + () -> assertEquals(4, genre.getId()), + () -> assertEquals("Test4", genre.getName()) + ); + } + + @Test + void deleteObject() { + int count = genreDaoJdbc.deleteObject(1); + + assertAll("genre", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { genreDaoJdbc.getById(1); }) + ); + } + + @Test + void updateObject() { + Genre genre1 = genreDaoJdbc.getById(1); + int count = genreDaoJdbc.updateObject(new Genre(1, "UpdatedName")); + Genre genre2 = genreDaoJdbc.getById(1); + + assertAll("genre", + () -> assertEquals(1, count), + () -> assertEquals("Genre1", genre1.getName()), + () -> assertEquals("UpdatedName", genre2.getName()) + ); + } +} \ No newline at end of file diff --git a/src/test/resources/test_data.sql b/src/test/resources/test_data.sql new file mode 100644 index 0000000..e255fb4 --- /dev/null +++ b/src/test/resources/test_data.sql @@ -0,0 +1,27 @@ +insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) +values ('Surname1', 'FirstName1', 'SecondName1'); + +insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) +values ('Surname2', 'FirstName2', 'SecondName2'); + +insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) +values ('Surname3', 'FirstName3', 'SecondName3'); + +-------------------------- + +insert into GENRE (NAME) values ('Genre1'); +insert into GENRE (NAME) values ('Genre2'); +insert into GENRE (NAME) values ('Genre3'); + +-------------------------- + +insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (sysdate, 'book_1', 1, 1, 'comment'); + +insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (sysdate, 'book_2', 1, 1, 'comment'); + +insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) + values (sysdate, 'book_3', 1, 1, 'comment'); + +-------------------------- diff --git a/src/test/resources/test_schema.sql b/src/test/resources/test_schema.sql new file mode 100644 index 0000000..4f8c037 --- /dev/null +++ b/src/test/resources/test_schema.sql @@ -0,0 +1,23 @@ +DROP TABLE IF EXISTS BOOK; +CREATE TABLE BOOK( + ID INT AUTO_INCREMENT PRIMARY KEY, + ADD_RECORD_DATE DATE, + CAPTION VARCHAR(255), + AUTHOR_ID INT, + GENRE_ID INT, + COMMENT VARCHAR(255) +); + +DROP TABLE IF EXISTS AUTHOR; +CREATE TABLE AUTHOR( + ID INT AUTO_INCREMENT PRIMARY KEY, + SURNAME VARCHAR(100), + FIRST_NAME VARCHAR(100), + SECOND_NAME VARCHAR(100) +); + +DROP TABLE IF EXISTS GENRE; +CREATE TABLE GENRE( + ID INT AUTO_INCREMENT PRIMARY KEY, + NAME VARCHAR(100), +); \ No newline at end of file From 0c2804a738fb7d3188d047551dbf298eea2664a4 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Tue, 28 May 2019 14:05:56 +0300 Subject: [PATCH 10/30] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20BookDaoJdbc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/otus/mkulikov/app/dao/AuthorDao.java | 2 +- .../otus/mkulikov/app/dao/AuthorDaoJdbc.java | 10 +- .../ru/otus/mkulikov/app/dao/BookDao.java | 2 +- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 9 +- .../ru/otus/mkulikov/app/model/Author.java | 20 +-- .../java/ru/otus/mkulikov/app/model/Book.java | 35 +++-- .../mkulikov/app/dao/BookDaoJdbcTest.java | 120 ++++++++++++++++++ .../mkulikov/app/dao/GenreDaoJdbcTest.java | 3 +- src/test/resources/test_data.sql | 6 +- 9 files changed, 168 insertions(+), 39 deletions(-) create mode 100644 src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java index ef336c7..dfeba2f 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java @@ -19,7 +19,7 @@ public interface AuthorDao { int addObject(T t); - void deleteObject(T t); + int deleteObject(int id); int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java index 6fa4789..8474f7b 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -40,8 +40,8 @@ public int addObject(Author book) { } @Override - public void deleteObject(Author book) { - + public int deleteObject(int id) { + return 0; } @Override @@ -55,10 +55,10 @@ private static class AuthorMapper implements RowMapper { public Author mapRow(ResultSet resultSet, int i) throws SQLException { int id = resultSet.getInt("ID"); String surname = resultSet.getString("SURNAME"); - String first_name = resultSet.getString("FIRST_NAME"); - String second_name = resultSet.getString("SECOND_NAME"); + String firstName = resultSet.getString("FIRST_NAME"); + String secondName = resultSet.getString("SECOND_NAME"); - return new Author(id, surname, first_name, second_name); + return new Author(id, surname, firstName, secondName); } } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java index de461de..431f064 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java @@ -19,7 +19,7 @@ public interface BookDao { int addObject(T t); - void deleteObject(T t); + int deleteObject(int id); int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 1d13930..533e9b9 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -8,6 +8,7 @@ import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Timestamp; import java.util.Date; import java.util.List; @@ -41,8 +42,8 @@ public int addObject(Book book) { } @Override - public void deleteObject(Book book) { - + public int deleteObject(int id) { + return 0; } @Override @@ -55,13 +56,13 @@ private static class BookMapper implements RowMapper { @Override public Book mapRow(ResultSet resultSet, int i) throws SQLException { int id = resultSet.getInt("ID"); - Date add_record_date = resultSet.getDate("ADD_RECORD_DATE"); + Date addRecordDate = resultSet.getDate("ADD_RECORD_DATE"); String caption = resultSet.getString("CAPTION"); int author_id = resultSet.getInt("AUTHOR_ID"); int genre_id = resultSet.getInt("GENRE_ID"); String comment = resultSet.getString("COMMENT"); - return new Book(id, add_record_date, caption, author_id, genre_id, comment); + return new Book(id, addRecordDate, caption, author_id, genre_id, comment); } } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index 489268f..e81c78a 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -16,21 +16,21 @@ public class Author { private final int id; private final String surname; - private final String first_name; - private final String second_name; + private final String firstName; + private final String secondName; - public Author(int id, String surname, String first_name, String second_name) { + public Author(int id, String surname, String firstName, String secondName) { this.id = id; this.surname = surname; - this.first_name = first_name; - this.second_name = second_name; + this.firstName = firstName; + this.secondName = secondName; } - public Author(String surname, String first_name, String second_name) { + public Author(String surname, String firstName, String secondName) { this.id = 0; this.surname = surname; - this.first_name = first_name; - this.second_name = second_name; + this.firstName = firstName; + this.secondName = secondName; } @Override @@ -38,8 +38,8 @@ public String toString() { return "Author{" + "id=" + id + ", surname='" + surname + '\'' + - ", first_name='" + first_name + '\'' + - ", second_name='" + second_name + '\'' + + ", firstName='" + firstName + '\'' + + ", secondName='" + secondName + '\'' + "}\n"; } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index c90e411..ec890ba 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -2,6 +2,8 @@ import lombok.Data; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Date; /** @@ -17,38 +19,43 @@ public class Book { private final int id; - private final Date add_record_date; + private final Date addRecordDate; private final String caption; - private final int author_id; - private final int genre_id; + private final int authorId; + private final int genreId; private final String comment; - public Book(int id, Date add_record_date, String caption, int author_id, int genre_id, String comment) { + public Book(int id, Date addRecordDate, String caption, int authorId, int genreId, String comment) { this.id = id; - this.add_record_date = add_record_date; + this.addRecordDate = addRecordDate; this.caption = caption; - this.author_id = author_id; - this.genre_id = genre_id; + this.authorId = authorId; + this.genreId = genreId; this.comment = comment; } - public Book(Date add_record_date, String caption, int author_id, int genre_id, String comment) { + public Book(Date addRecordDate, String caption, int authorId, int genreId, String comment) { this.id = 0; - this.add_record_date = add_record_date; + this.addRecordDate = addRecordDate; this.caption = caption; - this.author_id = author_id; - this.genre_id = genre_id; + this.authorId = authorId; + this.genreId = genreId; this.comment = comment; } + public String getAddRecordDateString() { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + return addRecordDate != null ? dateFormat.format(addRecordDate) : null; + } + @Override public String toString() { return "Book{" + "id=" + id + - ", add_record_date=" + add_record_date + + ", addRecordDate=" + addRecordDate + ", caption='" + caption + '\'' + - ", author_id=" + author_id + - ", genre_id=" + genre_id + + ", authorId=" + authorId + + ", genreId=" + genreId + ", comment='" + comment + '\'' + "}\n"; } diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java new file mode 100644 index 0000000..a1de4d9 --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java @@ -0,0 +1,120 @@ +package ru.otus.mkulikov.app.dao; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.model.Book; + +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 28.05.2019 + * Time: 13:16 + */ + +@DisplayName("Класс BookDaoJdbc") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class BookDaoJdbcTest { + + private BookDaoJdbc bookDaoJdbc; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + bookDaoJdbc = new BookDaoJdbc(new JdbcTemplate(db)); + } + + @Test + void getById() { + Book book = bookDaoJdbc.getById(1); + + assertAll("book", + () -> assertNotNull(book), + () -> assertEquals(1, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthorId()), + () -> assertEquals(1, book.getGenreId()), + () -> assertEquals("comment", book.getComment()) + ); + } + + @Test + void getAllObjects() { + List books = bookDaoJdbc.getAllObjects(); + + assertAll("books", + () -> assertNotNull(books), + () -> assertEquals(3, books.size()), + () -> assertEquals("book_1", books.get(0).getCaption()), + () -> assertEquals("book_2", books.get(1).getCaption()), + () -> assertEquals("book_3", books.get(2).getCaption()) + ); + } + + @Test + void addObject() { + int count = bookDaoJdbc.addObject( + new Book(new Date(),"Test_Book",2,3,"Test_Comment") + ); + + Book book = bookDaoJdbc.getById(4); + + assertAll("book", + () -> assertNotNull(book), + () -> assertEquals(1, count), + () -> assertEquals(4, book.getId()), + () -> assertEquals("Test_Book", book.getCaption()), + () -> assertEquals("2", book.getAuthorId()), + () -> assertEquals("3", book.getGenreId()), + () -> assertEquals("Test_Comment", book.getCaption()) + ); + } + + @Test + void deleteObject() { + int count = bookDaoJdbc.deleteObject(1); + + assertAll("book", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { bookDaoJdbc.getById(1); }) + ); + } + + @Test + void updateObject() { + Book book1 = bookDaoJdbc.getById(1); + int count = bookDaoJdbc.updateObject( + new Book(1, new Date(),"Test_Book",2,3,"Test_Comment") + ); + Book book2 = bookDaoJdbc.getById(1); + + assertAll("book", + () -> assertEquals(1, count), + () -> assertEquals("book_1", book1.getCaption()), + () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("Test_Book", book2.getCaption()), + () -> assertEquals("Test_Comment", book2.getComment()) + ); + } +} \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java index 82630d6..c9590e4 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java @@ -69,12 +69,13 @@ void getAllObjects() { @Test void addObject() { - genreDaoJdbc.addObject(new Genre("Test4")); + int count = genreDaoJdbc.addObject(new Genre("Test4")); Genre genre = genreDaoJdbc.getById(4); assertAll("genre", () -> assertNotNull(genre), + () -> assertEquals(1, count), () -> assertEquals(4, genre.getId()), () -> assertEquals("Test4", genre.getName()) ); diff --git a/src/test/resources/test_data.sql b/src/test/resources/test_data.sql index e255fb4..02531b1 100644 --- a/src/test/resources/test_data.sql +++ b/src/test/resources/test_data.sql @@ -16,12 +16,12 @@ insert into GENRE (NAME) values ('Genre3'); -------------------------- insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (sysdate, 'book_1', 1, 1, 'comment'); + values (to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (sysdate, 'book_2', 1, 1, 'comment'); + values (to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (sysdate, 'book_3', 1, 1, 'comment'); + values (to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); -------------------------- From 64febb3c5763d9d1506e7e985c69280ba575b0b1 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Wed, 29 May 2019 11:38:10 +0300 Subject: [PATCH 11/30] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20AuthorDaoJdbc,=20BookDaoJdbc=20=D0=B8=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BA=20=D0=BD=D0=B8=D0=BC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/mkulikov/app/dao/AuthorDaoJdbc.java | 16 ++- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 12 +- .../mkulikov/app/dao/AuthorDaoJdbcTest.java | 116 ++++++++++++++++++ .../mkulikov/app/dao/BookDaoJdbcTest.java | 6 +- 4 files changed, 139 insertions(+), 11 deletions(-) create mode 100644 src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java index 8474f7b..ae64ebd 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -35,18 +35,24 @@ public List getAllObjects() { } @Override - public int addObject(Author book) { - return 0; + public int addObject(Author author) { + return jdbcOperations.update( + "insert into Author (surname, first_name, second_name) values (?,?,?)", + new Object[]{author.getSurname(), author.getFirstName(), author.getSecondName()} + ); } @Override public int deleteObject(int id) { - return 0; + return jdbcOperations.update("delete from Author where id = ? ", new Object[]{id}); } @Override - public int updateObject(Author book) { - return 0; + public int updateObject(Author author) { + return jdbcOperations.update( + "update Author set surname = ?, first_name = ?, second_name = ? where id = ? ", + new Object[]{author.getSurname(), author.getFirstName(), author.getSecondName(), author.getId()} + ); } private static class AuthorMapper implements RowMapper { diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 533e9b9..89a0c16 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -38,17 +38,23 @@ public List getAllObjects() { @Override public int addObject(Book book) { - return 0; + return jdbcOperations.update( + "insert into Book (add_record_date, caption, author_id, genre_id, comment) values (sysdate,?,?,?,?)", + new Object[]{book.getCaption(), book.getAuthorId(), book.getGenreId(), book.getComment()} + ); } @Override public int deleteObject(int id) { - return 0; + return jdbcOperations.update("delete from Book where id = ? ", new Object[]{id}); } @Override public int updateObject(Book book) { - return 0; + return jdbcOperations.update( + "update Book set add_record_date = sysdate, caption = ?, author_id = ?, genre_id = ?, comment = ? where id = ? ", + new Object[]{book.getCaption(), book.getAuthorId(), book.getGenreId(), book.getComment(), book.getId()} + ); } private static class BookMapper implements RowMapper { diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java new file mode 100644 index 0000000..38b0fad --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java @@ -0,0 +1,116 @@ +package ru.otus.mkulikov.app.dao; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.model.Author; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 29.05.2019 + * Time: 10:12 + */ + +@DisplayName("Класс AuthorDaoJdbc") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class AuthorDaoJdbcTest { + + private AuthorDaoJdbc authorDaoJdbc; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); + } + + @Test + void getById() { + Author author = authorDaoJdbc.getById(1); + + assertAll("author", + () -> assertNotNull(author), + () -> assertEquals(1, author.getId()), + () -> assertEquals("Surname1", author.getSurname()), + () -> assertEquals("FirstName1", author.getFirstName()), + () -> assertEquals("SecondName1", author.getSecondName()) + ); + } + + @Test + void getAllObjects() { + List authors = authorDaoJdbc.getAllObjects(); + + assertAll("authors", + () -> assertNotNull(authors), + () -> assertEquals(3, authors.size()), + () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname2", authors.get(1).getSurname()), + () -> assertEquals("Surname3", authors.get(2).getSurname()) + ); + } + + @Test + void addObject() { + Author author = new Author("TestSurname", "TestFirstName", "TestSecondName"); + int count = authorDaoJdbc.addObject(author); + Author author_selected = authorDaoJdbc.getById(4); + + assertAll("author", + () -> assertNotNull(author_selected), + () -> assertEquals(1, count), + () -> assertEquals(4, author_selected.getId()), + () -> assertEquals(author.getSurname(), author_selected.getSurname()), + () -> assertEquals(author.getFirstName(), author_selected.getFirstName()), + () -> assertEquals(author.getSecondName(), author_selected.getSecondName()) + ); + } + + @Test + void deleteObject() { + int count = authorDaoJdbc.deleteObject(1); + + assertAll("author", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { authorDaoJdbc.getById(1); }) + ); + } + + @Test + void updateObject() { + Author author1 = authorDaoJdbc.getById(1); + int count = authorDaoJdbc.updateObject( + new Author(1,"TestSurname", "TestFirstName", "TestSecondName") + ); + Author author2 = authorDaoJdbc.getById(1); + + assertAll("author", + () -> assertEquals(1, count), + () -> assertEquals("Surname1", author1.getSurname()), + () -> assertEquals("FirstName1", author1.getFirstName()), + () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("TestSurname", author2.getSurname()), + () -> assertEquals("TestFirstName", author2.getFirstName()), + () -> assertEquals("TestSecondName", author2.getSecondName()) + ); + } +} \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java index a1de4d9..69958db 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java @@ -85,9 +85,9 @@ void addObject() { () -> assertEquals(1, count), () -> assertEquals(4, book.getId()), () -> assertEquals("Test_Book", book.getCaption()), - () -> assertEquals("2", book.getAuthorId()), - () -> assertEquals("3", book.getGenreId()), - () -> assertEquals("Test_Comment", book.getCaption()) + () -> assertEquals(2, book.getAuthorId()), + () -> assertEquals(3, book.getGenreId()), + () -> assertEquals("Test_Comment", book.getComment()) ); } From 27e65385e4779c18601d294e76a66c1a063ceae0 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Wed, 29 May 2019 12:32:39 +0300 Subject: [PATCH 12/30] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= =?UTF-8?q?,=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE=D0=BD=D0=B0?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/app/model/Book.java | 24 +++++++----- .../app/service/BooksManageSevice.java | 14 ++++++- .../app/service/BooksManageSeviceImpl.java | 39 +++++++++++++++++++ .../mkulikov/app/dao/BookDaoJdbcTest.java | 2 +- .../ru/otus/mkulikov/app/model/BookTest.java | 39 +++++++++++++++++++ 5 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 src/test/java/ru/otus/mkulikov/app/model/BookTest.java diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index ec890ba..e141a0a 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -18,12 +18,12 @@ @Data public class Book { - private final int id; - private final Date addRecordDate; - private final String caption; - private final int authorId; - private final int genreId; - private final String comment; + private int id; + private Date addRecordDate; + private String caption; + private int authorId; + private int genreId; + private String comment; public Book(int id, Date addRecordDate, String caption, int authorId, int genreId, String comment) { this.id = id; @@ -34,9 +34,15 @@ public Book(int id, Date addRecordDate, String caption, int authorId, int genreI this.comment = comment; } - public Book(Date addRecordDate, String caption, int authorId, int genreId, String comment) { - this.id = 0; - this.addRecordDate = addRecordDate; + public Book(int id, String caption, int authorId, int genreId, String comment) { + this.id = id; + this.caption = caption; + this.authorId = authorId; + this.genreId = genreId; + this.comment = comment; + } + + public Book(String caption, int authorId, int genreId, String comment) { this.caption = caption; this.authorId = authorId; this.genreId = genreId; diff --git a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java index e805c28..855111e 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java @@ -25,11 +25,23 @@ public interface BooksManageSevice { Genre getGenreById(int id); - List getGenres(); + List getGenres(); int addGenre(String name); int updateGenre(int id, String name); int deleteGenre(int id); + + int addBook(String caption, int authorId, int genreId, String comment); + + int updateBook(int id, String caption, int authorId, int genreId, String comment); + + int deleteBook(int id); + + int addAuthor(String surname, String firstName, String secondName); + + int updateAuthor(int id, String surname, String firstName, String secondName); + + int deleteAuthor(int id); } diff --git a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java index ff57986..601fc77 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java @@ -26,39 +26,78 @@ public class BooksManageSeviceImpl implements BooksManageSevice { private final BookDao bookDao; private final GenreDao genreDao; + @Override public Book getBookById(int id) { return bookDao.getById(id); } + @Override public List getBooks() { return bookDao.getAllObjects(); } + @Override public Author getAuthorById(int id) { return authorDao.getById(id); } + @Override public List getAuthors() { return authorDao.getAllObjects(); } + @Override public Genre getGenreById(int id) { return genreDao.getById(id); } + @Override public List getGenres() { return genreDao.getAllObjects(); } + @Override public int addGenre(String name) { return genreDao.addObject(new Genre(name)); } + @Override public int updateGenre(int id, String name) { return genreDao.updateObject(new Genre(id, name)); } + @Override public int deleteGenre(int id) { return genreDao.deleteObject(id); } + + @Override + public int addBook(String caption, int authorId, int genreId, String comment) { + return bookDao.addObject(new Book(caption, authorId, genreId, comment)); + } + + @Override + public int updateBook(int id, String caption, int authorId, int genreId, String comment) { + return bookDao.updateObject(new Book(id, caption, authorId, genreId, comment)); + } + + @Override + public int deleteBook(int id) { + return bookDao.deleteObject(id); + } + + @Override + public int addAuthor(String surname, String firstName, String secondName) { + return authorDao.addObject(new Author(surname, firstName, secondName)); + } + + @Override + public int updateAuthor(int id, String surname, String firstName, String secondName) { + return authorDao.updateObject(new Author(id, surname, firstName, secondName)); + } + + @Override + public int deleteAuthor(int id) { + return authorDao.deleteObject(id); + } } diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java index 69958db..f019089 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java @@ -75,7 +75,7 @@ void getAllObjects() { @Test void addObject() { int count = bookDaoJdbc.addObject( - new Book(new Date(),"Test_Book",2,3,"Test_Comment") + new Book("Test_Book",2,3,"Test_Comment") ); Book book = bookDaoJdbc.getById(4); diff --git a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java new file mode 100644 index 0000000..9932b6d --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java @@ -0,0 +1,39 @@ +package ru.otus.mkulikov.app.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 29.05.2019 + * Time: 11:39 + */ + +@DisplayName("Класс Book") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class BookTest { + + @Test + void getAddRecordDateString() { + Date date = new Date(); + Book book = new Book(1, date, "Test_Book", 2, 3, "Test_Comment"); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + + assertAll("book", + () -> assertNotNull(book), + () -> assertEquals(dateFormat.format(date), book.getAddRecordDateString()) + ); + } +} \ No newline at end of file From f23fcd4d4087c3c4d7c6a8695118613c50132829 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Wed, 29 May 2019 15:19:11 +0300 Subject: [PATCH 13/30] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20BooksManageSevice.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/BooksManageSeviceImplTest.java | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java diff --git a/src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java new file mode 100644 index 0000000..a14b73e --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java @@ -0,0 +1,251 @@ +package ru.otus.mkulikov.app.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.dao.AuthorDaoJdbc; +import ru.otus.mkulikov.app.dao.BookDaoJdbc; +import ru.otus.mkulikov.app.dao.GenreDaoJdbc; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 29.05.2019 + * Time: 13:40 + */ + +@DisplayName("Класс BooksManageSevice") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class BooksManageSeviceImplTest { + + private BooksManageSevice booksManageSevice; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + AuthorDaoJdbc authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); + BookDaoJdbc bookDaoJdbc = new BookDaoJdbc(new JdbcTemplate(db)); + GenreDaoJdbc genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); + + booksManageSevice = new BooksManageSeviceImpl(authorDaoJdbc, bookDaoJdbc, genreDaoJdbc); + } + + @Test + void getBookById() { + Book book = booksManageSevice.getBookById(1); + + assertAll("book", + () -> assertNotNull(book), + () -> assertEquals(1, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthorId()), + () -> assertEquals(1, book.getGenreId()), + () -> assertEquals("comment", book.getComment()) + ); + } + + @Test + void getBooks() { + List books = booksManageSevice.getBooks(); + + assertAll("books", + () -> assertNotNull(books), + () -> assertEquals(3, books.size()), + () -> assertEquals("book_1", books.get(0).getCaption()), + () -> assertEquals("book_2", books.get(1).getCaption()), + () -> assertEquals("book_3", books.get(2).getCaption()) + ); + } + + @Test + void getAuthorById() { + Author author = booksManageSevice.getAuthorById(1); + + assertAll("author", + () -> assertNotNull(author), + () -> assertEquals(1, author.getId()), + () -> assertEquals("Surname1", author.getSurname()), + () -> assertEquals("FirstName1", author.getFirstName()), + () -> assertEquals("SecondName1", author.getSecondName()) + ); + } + + @Test + void getAuthors() { + List authors = booksManageSevice.getAuthors(); + + assertAll("authors", + () -> assertNotNull(authors), + () -> assertEquals(3, authors.size()), + () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname2", authors.get(1).getSurname()), + () -> assertEquals("Surname3", authors.get(2).getSurname()) + ); + } + + @Test + void getGenreById() { + Genre genre = booksManageSevice.getGenreById(1); + + assertAll("genre", + () -> assertNotNull(genre), + () -> assertEquals(1, genre.getId()), + () -> assertEquals("Genre1", genre.getName()) + ); + } + + @Test + void getGenres() { + List genres = booksManageSevice.getGenres(); + + assertAll("genres", + () -> assertNotNull(genres), + () -> assertEquals(3, genres.size()), + () -> assertEquals("Genre1", genres.get(0).getName()), + () -> assertEquals("Genre2", genres.get(1).getName()), + () -> assertEquals("Genre3", genres.get(2).getName()) + ); + } + + @Test + void addGenre() { + int count = booksManageSevice.addGenre("Test4"); + Genre genre = booksManageSevice.getGenreById(4); + + assertAll("genre", + () -> assertNotNull(genre), + () -> assertEquals(1, count), + () -> assertEquals(4, genre.getId()), + () -> assertEquals("Test4", genre.getName()) + ); + } + + @Test + void updateGenre() { + Genre genre1 = booksManageSevice.getGenreById(1); + int count = booksManageSevice.updateGenre(1, "UpdatedName"); + Genre genre2 = booksManageSevice.getGenreById(1); + + assertAll("genre", + () -> assertEquals(1, count), + () -> assertEquals("Genre1", genre1.getName()), + () -> assertEquals("UpdatedName", genre2.getName()) + ); + } + + @Test + void deleteGenre() { + int count = booksManageSevice.deleteGenre(1); + + assertAll("genre", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getGenreById(1); }) + ); + } + + @Test + void addBook() { + int count = booksManageSevice.addBook("Test_Book",2,3,"Test_Comment"); + Book book = booksManageSevice.getBookById(4); + + assertAll("book", + () -> assertNotNull(book), + () -> assertEquals(1, count), + () -> assertEquals(4, book.getId()), + () -> assertEquals("Test_Book", book.getCaption()), + () -> assertEquals(2, book.getAuthorId()), + () -> assertEquals(3, book.getGenreId()), + () -> assertEquals("Test_Comment", book.getComment()) + ); + } + + @Test + void updateBook() { + Book book1 = booksManageSevice.getBookById(1); + int count = booksManageSevice.updateBook(1, "Test_Book", 2, 3, "Test_Comment"); + Book book2 = booksManageSevice.getBookById(1); + + assertAll("book", + () -> assertEquals(1, count), + () -> assertEquals("book_1", book1.getCaption()), + () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("Test_Book", book2.getCaption()), + () -> assertEquals("Test_Comment", book2.getComment()) + ); + } + + @Test + void deleteBook() { + int count = booksManageSevice.deleteBook(1); + + assertAll("book", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getBookById(1); }) + ); + } + + @Test + void addAuthor() { + int count = booksManageSevice.addAuthor("TestSurname", "TestFirstName", "TestSecondName"); + Author author_selected = booksManageSevice.getAuthorById(4); + + assertAll("author", + () -> assertNotNull(author_selected), + () -> assertEquals(1, count), + () -> assertEquals(4, author_selected.getId()), + () -> assertEquals("TestSurname", author_selected.getSurname()), + () -> assertEquals("TestFirstName", author_selected.getFirstName()), + () -> assertEquals("TestSecondName", author_selected.getSecondName()) + ); + } + + @Test + void updateAuthor() { + Author author1 = booksManageSevice.getAuthorById(1); + int count = booksManageSevice.updateAuthor(1,"TestSurname", "TestFirstName", "TestSecondName"); + Author author2 = booksManageSevice.getAuthorById(1); + + assertAll("author", + () -> assertEquals(1, count), + () -> assertEquals("Surname1", author1.getSurname()), + () -> assertEquals("FirstName1", author1.getFirstName()), + () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("TestSurname", author2.getSurname()), + () -> assertEquals("TestFirstName", author2.getFirstName()), + () -> assertEquals("TestSecondName", author2.getSecondName()) + ); + } + + @Test + void deleteAuthor() { + int count = booksManageSevice.deleteAuthor(1); + + assertAll("author", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getAuthorById(1); }) + ); + } +} \ No newline at end of file From 486d0a3788b1024dc76e625a13be55d2eded94c8 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 30 May 2019 16:34:48 +0300 Subject: [PATCH 14/30] =?UTF-8?q?-=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE?= =?UTF-8?q?=D0=BD=D0=B0=D0=BB=D0=B0.=20-=20=D0=A0=D0=B0=D0=B7=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=BD=D0=B0=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B8?= =?UTF-8?q?.=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/Application.java | 5 - .../ru/otus/mkulikov/app/model/Author.java | 6 +- .../java/ru/otus/mkulikov/app/model/Book.java | 19 +- .../ru/otus/mkulikov/app/model/Genre.java | 2 - .../app/service/AuthorManageService.java | 25 ++ .../app/service/AuthorManageServiceImpl.java | 47 ++++ .../app/service/BookManageSevice.java | 29 ++ .../app/service/BookManageSeviceImpl.java | 72 +++++ .../app/service/BooksManageSevice.java | 47 ---- .../app/service/BooksManageSeviceImpl.java | 103 ------- .../app/service/GenreManageService.java | 24 ++ .../app/service/GenreManageServiceImpl.java | 47 ++++ .../otus/mkulikov/shell/AuthorCommands.java | 54 ++++ .../ru/otus/mkulikov/shell/BookCommands.java | 66 +++++ .../java/ru/otus/mkulikov/shell/Commands.java | 92 ------- .../ru/otus/mkulikov/shell/GenreCommands.java | 54 ++++ src/main/resources/schema.sql | 12 +- .../ru/otus/mkulikov/app/model/BookTest.java | 9 +- .../service/AuthorManageSeviceImplTest.java | 118 ++++++++ .../app/service/BookManageSeviceImplTest.java | 141 ++++++++++ .../service/BooksManageSeviceImplTest.java | 251 ------------------ .../service/GenreManageSeviceImplTest.java | 110 ++++++++ src/test/resources/test_schema.sql | 12 +- 23 files changed, 826 insertions(+), 519 deletions(-) create mode 100644 src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java delete mode 100644 src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java delete mode 100644 src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java create mode 100644 src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java create mode 100644 src/main/java/ru/otus/mkulikov/shell/BookCommands.java delete mode 100644 src/main/java/ru/otus/mkulikov/shell/Commands.java create mode 100644 src/main/java/ru/otus/mkulikov/shell/GenreCommands.java create mode 100644 src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java create mode 100644 src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java delete mode 100644 src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java create mode 100644 src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index 7760aa8..a45b459 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -4,9 +4,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.PropertySource; - /** * Created by IntelliJ IDEA. @@ -16,13 +13,11 @@ */ @SpringBootApplication -//@PropertySource("classpath:application.yml") @EnableConfigurationProperties public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class); - //ApplicationContext context = SpringApplication.run(Application.class); //Console.main(args); } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index e81c78a..d087534 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -7,8 +7,6 @@ * Developer: Maksim Kulikov * Date: 23.05.2019 * Time: 17:02 - * - * Сущность таблицы авторов */ @Data @@ -33,6 +31,10 @@ public Author(String surname, String firstName, String secondName) { this.secondName = secondName; } + public String toFormatedString() { + return getSurname() + " " + getFirstName() + " " + getSecondName(); + } + @Override public String toString() { return "Author{" + diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index e141a0a..7c87c7a 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -5,14 +5,13 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; /** * Created by IntelliJ IDEA. * Developer: Maksim Kulikov * Date: 23.05.2019 * Time: 13:28 - * - * Сущность таблицы книг */ @Data @@ -23,6 +22,8 @@ public class Book { private String caption; private int authorId; private int genreId; + private Author author; + private Genre genre; private String comment; public Book(int id, Date addRecordDate, String caption, int authorId, int genreId, String comment) { @@ -54,6 +55,18 @@ public String getAddRecordDateString() { return addRecordDate != null ? dateFormat.format(addRecordDate) : null; } + public String getAuthorString() { + return (author != null) + ? ", author='" + author.toFormatedString() + '\'' + : ""; + } + + public String getGenreString() { + return (genre != null) + ? ", genre='" + genre.getName() + '\'' + : ""; + } + @Override public String toString() { return "Book{" + @@ -63,6 +76,8 @@ public String toString() { ", authorId=" + authorId + ", genreId=" + genreId + ", comment='" + comment + '\'' + + getAuthorString() + + getGenreString() + "}\n"; } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 8f8a011..2f2d528 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -7,8 +7,6 @@ * Developer: Maksim Kulikov * Date: 23.05.2019 * Time: 17:04 - * - * Сущность таблицы жанров */ @Data diff --git a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java new file mode 100644 index 0000000..b11706d --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java @@ -0,0 +1,25 @@ +package ru.otus.mkulikov.app.service; + +import ru.otus.mkulikov.app.model.Author; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 14:59 + */ + +public interface AuthorManageService { + + T getAuthorById(int id); + + List getAuthors(); + + int addAuthor(String surname, String firstName, String secondName); + + int updateAuthor(int id, String surname, String firstName, String secondName); + + int deleteAuthor(int id); +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java new file mode 100644 index 0000000..9237363 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java @@ -0,0 +1,47 @@ +package ru.otus.mkulikov.app.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.mkulikov.app.dao.AuthorDao; +import ru.otus.mkulikov.app.model.Author; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:53 + */ + +@Service +@RequiredArgsConstructor +public class AuthorManageServiceImpl implements AuthorManageService { + + private final AuthorDao authorDao; + + @Override + public Author getAuthorById(int id) { + return authorDao.getById(id); + } + + @Override + public List getAuthors() { + return authorDao.getAllObjects(); + } + + @Override + public int addAuthor(String surname, String firstName, String secondName) { + return authorDao.addObject(new Author(surname, firstName, secondName)); + } + + @Override + public int updateAuthor(int id, String surname, String firstName, String secondName) { + return authorDao.updateObject(new Author(id, surname, firstName, secondName)); + } + + @Override + public int deleteAuthor(int id) { + return authorDao.deleteObject(id); + } +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java new file mode 100644 index 0000000..552cd31 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java @@ -0,0 +1,29 @@ +package ru.otus.mkulikov.app.service; + +import ru.otus.mkulikov.app.model.Book; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 27.05.2019 + * Time: 13:42 + */ + +public interface BookManageSevice { + + T getBookById(int id); + + T getFullBookById(int id); + + List getBooks(); + + List getFullBooks(); + + int addBook(String caption, int authorId, int genreId, String comment); + + int updateBook(int id, String caption, int authorId, int genreId, String comment); + + int deleteBook(int id); +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java new file mode 100644 index 0000000..b64c332 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java @@ -0,0 +1,72 @@ +package ru.otus.mkulikov.app.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.mkulikov.app.dao.AuthorDao; +import ru.otus.mkulikov.app.dao.BookDao; +import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Book; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 27.05.2019 + * Time: 13:42 + */ + +@Service +@RequiredArgsConstructor +public class BookManageSeviceImpl implements BookManageSevice { + + private final AuthorDao authorDao; + private final BookDao bookDao; + private final GenreDao genreDao; + + @Override + public Book getBookById(int id) { + return bookDao.getById(id); + } + + @Override + public Book getFullBookById(int id) { + Book book = bookDao.getById(id); + return setBookInfo(book); + } + + @Override + public List getBooks() { + return bookDao.getAllObjects(); + } + + @Override + public List getFullBooks() { + List books = bookDao.getAllObjects(); + for (Book book : books) { + setBookInfo(book); + } + return books; + } + + private Book setBookInfo(Book book) { + book.setAuthor(authorDao.getById(book.getAuthorId())); + book.setGenre(genreDao.getById(book.getGenreId())); + return book; + } + + @Override + public int addBook(String caption, int authorId, int genreId, String comment) { + return bookDao.addObject(new Book(caption, authorId, genreId, comment)); + } + + @Override + public int updateBook(int id, String caption, int authorId, int genreId, String comment) { + return bookDao.updateObject(new Book(id, caption, authorId, genreId, comment)); + } + + @Override + public int deleteBook(int id) { + return bookDao.deleteObject(id); + } +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java deleted file mode 100644 index 855111e..0000000 --- a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSevice.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.otus.mkulikov.app.service; - -import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Genre; - -import java.util.List; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 27.05.2019 - * Time: 13:42 - */ - -public interface BooksManageSevice { - - Book getBookById(int id); - - List getBooks(); - - Author getAuthorById(int id); - - List getAuthors(); - - Genre getGenreById(int id); - - List getGenres(); - - int addGenre(String name); - - int updateGenre(int id, String name); - - int deleteGenre(int id); - - int addBook(String caption, int authorId, int genreId, String comment); - - int updateBook(int id, String caption, int authorId, int genreId, String comment); - - int deleteBook(int id); - - int addAuthor(String surname, String firstName, String secondName); - - int updateAuthor(int id, String surname, String firstName, String secondName); - - int deleteAuthor(int id); -} diff --git a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java deleted file mode 100644 index 601fc77..0000000 --- a/src/main/java/ru/otus/mkulikov/app/service/BooksManageSeviceImpl.java +++ /dev/null @@ -1,103 +0,0 @@ -package ru.otus.mkulikov.app.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import ru.otus.mkulikov.app.dao.AuthorDao; -import ru.otus.mkulikov.app.dao.BookDao; -import ru.otus.mkulikov.app.dao.GenreDao; -import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Genre; - -import java.util.List; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 27.05.2019 - * Time: 13:42 - */ - -@Service -@RequiredArgsConstructor -public class BooksManageSeviceImpl implements BooksManageSevice { - - private final AuthorDao authorDao; - private final BookDao bookDao; - private final GenreDao genreDao; - - @Override - public Book getBookById(int id) { - return bookDao.getById(id); - } - - @Override - public List getBooks() { - return bookDao.getAllObjects(); - } - - @Override - public Author getAuthorById(int id) { - return authorDao.getById(id); - } - - @Override - public List getAuthors() { - return authorDao.getAllObjects(); - } - - @Override - public Genre getGenreById(int id) { - return genreDao.getById(id); - } - - @Override - public List getGenres() { - return genreDao.getAllObjects(); - } - - @Override - public int addGenre(String name) { - return genreDao.addObject(new Genre(name)); - } - - @Override - public int updateGenre(int id, String name) { - return genreDao.updateObject(new Genre(id, name)); - } - - @Override - public int deleteGenre(int id) { - return genreDao.deleteObject(id); - } - - @Override - public int addBook(String caption, int authorId, int genreId, String comment) { - return bookDao.addObject(new Book(caption, authorId, genreId, comment)); - } - - @Override - public int updateBook(int id, String caption, int authorId, int genreId, String comment) { - return bookDao.updateObject(new Book(id, caption, authorId, genreId, comment)); - } - - @Override - public int deleteBook(int id) { - return bookDao.deleteObject(id); - } - - @Override - public int addAuthor(String surname, String firstName, String secondName) { - return authorDao.addObject(new Author(surname, firstName, secondName)); - } - - @Override - public int updateAuthor(int id, String surname, String firstName, String secondName) { - return authorDao.updateObject(new Author(id, surname, firstName, secondName)); - } - - @Override - public int deleteAuthor(int id) { - return authorDao.deleteObject(id); - } -} diff --git a/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java b/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java new file mode 100644 index 0000000..b811b8e --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java @@ -0,0 +1,24 @@ +package ru.otus.mkulikov.app.service; + +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:50 + */ +public interface GenreManageService { + + Genre getGenreById(int id); + + List getGenres(); + + int addGenre(String name); + + int updateGenre(int id, String name); + + int deleteGenre(int id); +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java new file mode 100644 index 0000000..f2e21ac --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java @@ -0,0 +1,47 @@ +package ru.otus.mkulikov.app.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:52 + */ + +@Service +@RequiredArgsConstructor +public class GenreManageServiceImpl implements GenreManageService { + + private final GenreDao genreDao; + + @Override + public Genre getGenreById(int id) { + return genreDao.getById(id); + } + + @Override + public List getGenres() { + return genreDao.getAllObjects(); + } + + @Override + public int addGenre(String name) { + return genreDao.addObject(new Genre(name)); + } + + @Override + public int updateGenre(int id, String name) { + return genreDao.updateObject(new Genre(id, name)); + } + + @Override + public int deleteGenre(int id) { + return genreDao.deleteObject(id); + } +} diff --git a/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java b/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java new file mode 100644 index 0000000..550b846 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java @@ -0,0 +1,54 @@ +package ru.otus.mkulikov.shell; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellOption; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.service.AuthorManageService; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 14:46 + */ + +@ShellComponent +@RequiredArgsConstructor +public class AuthorCommands { + + private final AuthorManageService authorManageService; + + @ShellMethod(key = { "getAuthorById" }, value = "Select author by id.") + public String getAuthorById(@ShellOption int id) { + Author author = authorManageService.getAuthorById(id); + return author.toString(); + } + + @ShellMethod(key = { "getAuthors" }, value = "Select all authors.") + public String getAuthors() { + List allObjects = authorManageService.getAuthors(); + return allObjects.toString(); + } + + @ShellMethod(key = { "addAuthor" }, value = "Add new author.") + public String addAuthor(@ShellOption String surname, @ShellOption String firstName, @ShellOption String secondName) { + int count = authorManageService.addAuthor(surname, firstName, secondName); + return "Add " + count + " row(s)"; + } + + @ShellMethod(key = { "updateAuthor" }, value = "Update author by id.") + public String updateAuthor(@ShellOption int id, @ShellOption String surname, @ShellOption String firstName, @ShellOption String secondName) { + int count = authorManageService.updateAuthor(id, surname, firstName, secondName); + return "Updated " + count + " row(s)"; + } + + @ShellMethod(key = { "deleteAuthor" }, value = "Delete author by id.") + public String deleteAuthor(@ShellOption int id) { + int count = authorManageService.deleteAuthor(id); + return "Deleted " + count + " row(s)"; + } +} diff --git a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java new file mode 100644 index 0000000..aa70aaa --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java @@ -0,0 +1,66 @@ +package ru.otus.mkulikov.shell; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellOption; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.service.BookManageSevice; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:33 + */ + +@ShellComponent +@RequiredArgsConstructor +public class BookCommands { + + private final BookManageSevice bookManageSevice; + + @ShellMethod(key = { "getBookById" }, value = "Select book by id.") + public String getBookById(@ShellOption int id) { + Book book = bookManageSevice.getBookById(id); + return book.toString(); + } + + @ShellMethod(key = { "getFullBookById" }, value = "Select book by id.") + public String getFullBookById(@ShellOption int id) { + Book book = bookManageSevice.getFullBookById(id); + return book.toString(); + } + + @ShellMethod(key = { "getBooks" }, value = "Select all books.") + public String getBooks() { + List allObjects = bookManageSevice.getBooks(); + return allObjects.toString(); + } + + @ShellMethod(key = { "getFullBooks" }, value = "Select all books.") + public String getFullBooks() { + List allObjects = bookManageSevice.getFullBooks(); + return allObjects.toString(); + } + + @ShellMethod(key = { "addBook" }, value = "Add new book.") + public String addBook(@ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { + int count = bookManageSevice.addBook(caption, authorId, genreId, comment); + return "Add " + count + " row(s)"; + } + + @ShellMethod(key = { "updateBook" }, value = "Update book by id.") + public String updateBook(@ShellOption int id, @ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { + int count = bookManageSevice.updateBook(id, caption, authorId, genreId, comment); + return "Updated " + count + " row(s)"; + } + + @ShellMethod(key = { "deleteBook" }, value = "Delete book by id.") + public String deleteBook(@ShellOption int id) { + int count = bookManageSevice.deleteBook(id); + return "Deleted " + count + " row(s)"; + } +} diff --git a/src/main/java/ru/otus/mkulikov/shell/Commands.java b/src/main/java/ru/otus/mkulikov/shell/Commands.java deleted file mode 100644 index a932e76..0000000 --- a/src/main/java/ru/otus/mkulikov/shell/Commands.java +++ /dev/null @@ -1,92 +0,0 @@ -package ru.otus.mkulikov.shell; - -import lombok.RequiredArgsConstructor; -import org.springframework.shell.standard.ShellComponent; -import org.springframework.shell.standard.ShellMethod; -import org.springframework.shell.standard.ShellOption; -import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Genre; -import ru.otus.mkulikov.app.service.BooksManageSevice; - -import java.util.List; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 23.05.2019 - * Time: 17:33 - */ - -@ShellComponent -@RequiredArgsConstructor -public class Commands { - - private final BooksManageSevice booksManageSevice; - - /************** - * Жанры - */ - - @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") - public String getGenreById(@ShellOption int id) { - Genre genre = booksManageSevice.getGenreById(id); - return genre.toString(); - } - - @ShellMethod(key = { "getGenres" }, value = "Select all genres.") - public String getGenres() { - List allObjects = booksManageSevice.getGenres(); - return allObjects.toString(); - } - - @ShellMethod(key = { "addGenre" }, value = "Add new genre.") - public String addGenre(@ShellOption String name) { - int count = booksManageSevice.addGenre(name); - return "Add " + count + " row(s)"; - } - - @ShellMethod(key = { "updateGenre" }, value = "Update genre by id.") - public String updateGenre(@ShellOption int id, @ShellOption String name) { - int count = booksManageSevice.updateGenre(id, name); - return "Updated " + count + " row(s)"; - } - - @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") - public String deleteGenre(@ShellOption int id) { - int count = booksManageSevice.deleteGenre(id); - return "Deleted " + count + " row(s)"; - } - - /************** - * Книги - */ - - @ShellMethod(key = { "getBookById" }, value = "Select book by id.") - public String getBookById(@ShellOption int id) { - Book book = booksManageSevice.getBookById(id); - return book.toString(); - } - - @ShellMethod(key = { "getBooks" }, value = "Select all books.") - public String getBooks() { - List allObjects = booksManageSevice.getBooks(); - return allObjects.toString(); - } - - /************** - * Авторы - */ - - @ShellMethod(key = { "getAuthorById" }, value = "Select author by id.") - public String getAuthorById(@ShellOption int id) { - Author author = booksManageSevice.getAuthorById(id); - return author.toString(); - } - - @ShellMethod(key = { "getAuthors" }, value = "Select all authors.") - public String getAuthors() { - List allObjects = booksManageSevice.getAuthors(); - return allObjects.toString(); - } -} diff --git a/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java b/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java new file mode 100644 index 0000000..2e6a3ac --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java @@ -0,0 +1,54 @@ +package ru.otus.mkulikov.shell; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellOption; +import ru.otus.mkulikov.app.model.Genre; +import ru.otus.mkulikov.app.service.GenreManageService; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 14:47 + */ + +@ShellComponent +@RequiredArgsConstructor +public class GenreCommands { + + private final GenreManageService genreManageService; + + @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") + public String getGenreById(@ShellOption int id) { + Genre genre = genreManageService.getGenreById(id); + return genre.toString(); + } + + @ShellMethod(key = { "getGenres" }, value = "Select all genres.") + public String getGenres() { + List allObjects = genreManageService.getGenres(); + return allObjects.toString(); + } + + @ShellMethod(key = { "addGenre" }, value = "Add new genre.") + public String addGenre(@ShellOption String name) { + int count = genreManageService.addGenre(name); + return "Add " + count + " row(s)"; + } + + @ShellMethod(key = { "updateGenre" }, value = "Update genre by id.") + public String updateGenre(@ShellOption int id, @ShellOption String name) { + int count = genreManageService.updateGenre(id, name); + return "Updated " + count + " row(s)"; + } + + @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") + public String deleteGenre(@ShellOption int id) { + int count = genreManageService.deleteGenre(id); + return "Deleted " + count + " row(s)"; + } +} diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 4f8c037..d0b2b33 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -2,22 +2,22 @@ DROP TABLE IF EXISTS BOOK; CREATE TABLE BOOK( ID INT AUTO_INCREMENT PRIMARY KEY, ADD_RECORD_DATE DATE, - CAPTION VARCHAR(255), - AUTHOR_ID INT, - GENRE_ID INT, + CAPTION VARCHAR(255) not null, + AUTHOR_ID INT not null, + GENRE_ID INT not null, COMMENT VARCHAR(255) ); DROP TABLE IF EXISTS AUTHOR; CREATE TABLE AUTHOR( ID INT AUTO_INCREMENT PRIMARY KEY, - SURNAME VARCHAR(100), - FIRST_NAME VARCHAR(100), + SURNAME VARCHAR(100) not null, + FIRST_NAME VARCHAR(100) not null, SECOND_NAME VARCHAR(100) ); DROP TABLE IF EXISTS GENRE; CREATE TABLE GENRE( ID INT AUTO_INCREMENT PRIMARY KEY, - NAME VARCHAR(100), + NAME VARCHAR(100) not null ); \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java index 9932b6d..b05b6fe 100644 --- a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java +++ b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java @@ -27,13 +27,16 @@ class BookTest { @Test void getAddRecordDateString() { - Date date = new Date(); - Book book = new Book(1, date, "Test_Book", 2, 3, "Test_Comment"); + Book book = getNewBook(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); assertAll("book", () -> assertNotNull(book), - () -> assertEquals(dateFormat.format(date), book.getAddRecordDateString()) + () -> assertEquals(dateFormat.format(new Date()), book.getAddRecordDateString()) ); } + + private Book getNewBook() { + return new Book(1, new Date(), "Test_Book", 2, 3, "Test_Comment"); + } } \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java new file mode 100644 index 0000000..23b4286 --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -0,0 +1,118 @@ +package ru.otus.mkulikov.app.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.dao.AuthorDaoJdbc; +import ru.otus.mkulikov.app.model.Author; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:59 + */ + +@DisplayName("Класс AuthorManageSevice") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class AuthorManageSeviceImplTest { + + private AuthorManageService authorManageService; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + AuthorDaoJdbc authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); + authorManageService = new AuthorManageServiceImpl(authorDaoJdbc); + } + + @Test + void getAuthorById() { + Author author = authorManageService.getAuthorById(1); + + assertAll("author", + () -> assertNotNull(author), + () -> assertEquals(1, author.getId()), + () -> assertEquals("Surname1", author.getSurname()), + () -> assertEquals("FirstName1", author.getFirstName()), + () -> assertEquals("SecondName1", author.getSecondName()) + ); + } + + @Test + void getAuthors() { + List authors = authorManageService.getAuthors(); + + assertAll("authors", + () -> assertNotNull(authors), + () -> assertEquals(3, authors.size()), + () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname2", authors.get(1).getSurname()), + () -> assertEquals("Surname3", authors.get(2).getSurname()) + ); + } + + @Test + void addAuthor() { + int count = authorManageService.addAuthor("TestSurname", "TestFirstName", "TestSecondName"); + Author author_selected = authorManageService.getAuthorById(4); + + assertAll("author", + () -> assertNotNull(author_selected), + () -> assertEquals(1, count), + () -> assertEquals(4, author_selected.getId()), + () -> assertEquals("TestSurname", author_selected.getSurname()), + () -> assertEquals("TestFirstName", author_selected.getFirstName()), + () -> assertEquals("TestSecondName", author_selected.getSecondName()) + ); + } + + @Test + void updateAuthor() { + Author author1 = authorManageService.getAuthorById(1); + int count = authorManageService.updateAuthor(1,"TestSurname", "TestFirstName", "TestSecondName"); + Author author2 = authorManageService.getAuthorById(1); + + assertAll("author", + () -> assertEquals(1, count), + () -> assertEquals("Surname1", author1.getSurname()), + () -> assertEquals("FirstName1", author1.getFirstName()), + () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("TestSurname", author2.getSurname()), + () -> assertEquals("TestFirstName", author2.getFirstName()), + () -> assertEquals("TestSecondName", author2.getSecondName()) + ); + } + + @Test + void deleteAuthor() { + int count = authorManageService.deleteAuthor(1); + + assertAll("author", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { authorManageService.getAuthorById(1); }) + ); + } +} diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java new file mode 100644 index 0000000..2b9928c --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -0,0 +1,141 @@ +package ru.otus.mkulikov.app.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.dao.AuthorDaoJdbc; +import ru.otus.mkulikov.app.dao.BookDaoJdbc; +import ru.otus.mkulikov.app.dao.GenreDaoJdbc; +import ru.otus.mkulikov.app.model.Book; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 29.05.2019 + * Time: 13:40 + */ + +@DisplayName("Класс BookManageSevice") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class BookManageSeviceImplTest { + + private BookManageSevice booksManageSevice; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + AuthorDaoJdbc authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); + BookDaoJdbc bookDaoJdbc = new BookDaoJdbc(new JdbcTemplate(db)); + GenreDaoJdbc genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); + + booksManageSevice = new BookManageSeviceImpl(authorDaoJdbc, bookDaoJdbc, genreDaoJdbc); + } + + @Test + void getBookById() { + Book book = booksManageSevice.getBookById(1); + + assertAll("book", + () -> assertNotNull(book), + () -> assertNull(book.getAuthor()), + () -> assertNull(book.getGenre()), + () -> assertEquals(1, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthorId()), + () -> assertEquals(1, book.getGenreId()), + () -> assertEquals("comment", book.getComment()) + ); + } + + @Test + void getFullBookById() { + Book book = booksManageSevice.getFullBookById(1); + + assertAll("book", + () -> assertNotNull(book), + () -> assertNotNull(book.getAuthor()), + () -> assertNotNull(book.getGenre()), + () -> assertEquals(1, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthorId()), + () -> assertEquals(1, book.getGenreId()), + () -> assertEquals("comment", book.getComment()) + ); + } + + @Test + void getBooks() { + List books = booksManageSevice.getBooks(); + + assertAll("books", + () -> assertNotNull(books), + () -> assertEquals(3, books.size()), + () -> assertEquals("book_1", books.get(0).getCaption()), + () -> assertEquals("book_2", books.get(1).getCaption()), + () -> assertEquals("book_3", books.get(2).getCaption()) + ); + } + + @Test + void addBook() { + int count = booksManageSevice.addBook("Test_Book",2,3,"Test_Comment"); + Book book = booksManageSevice.getBookById(4); + + assertAll("book", + () -> assertNotNull(book), + () -> assertEquals(1, count), + () -> assertEquals(4, book.getId()), + () -> assertEquals("Test_Book", book.getCaption()), + () -> assertEquals(2, book.getAuthorId()), + () -> assertEquals(3, book.getGenreId()), + () -> assertEquals("Test_Comment", book.getComment()) + ); + } + + @Test + void updateBook() { + Book book1 = booksManageSevice.getBookById(1); + int count = booksManageSevice.updateBook(1, "Test_Book", 2, 3, "Test_Comment"); + Book book2 = booksManageSevice.getBookById(1); + + assertAll("book", + () -> assertEquals(1, count), + () -> assertEquals("book_1", book1.getCaption()), + () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("Test_Book", book2.getCaption()), + () -> assertEquals("Test_Comment", book2.getComment()) + ); + } + + @Test + void deleteBook() { + int count = booksManageSevice.deleteBook(1); + + assertAll("book", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getBookById(1); }) + ); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java deleted file mode 100644 index a14b73e..0000000 --- a/src/test/java/ru/otus/mkulikov/app/service/BooksManageSeviceImplTest.java +++ /dev/null @@ -1,251 +0,0 @@ -package ru.otus.mkulikov.app.service; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; -import ru.otus.mkulikov.app.dao.AuthorDaoJdbc; -import ru.otus.mkulikov.app.dao.BookDaoJdbc; -import ru.otus.mkulikov.app.dao.GenreDaoJdbc; -import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Genre; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 29.05.2019 - * Time: 13:40 - */ - -@DisplayName("Класс BooksManageSevice") -@RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) -class BooksManageSeviceImplTest { - - private BooksManageSevice booksManageSevice; - - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - - AuthorDaoJdbc authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); - BookDaoJdbc bookDaoJdbc = new BookDaoJdbc(new JdbcTemplate(db)); - GenreDaoJdbc genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); - - booksManageSevice = new BooksManageSeviceImpl(authorDaoJdbc, bookDaoJdbc, genreDaoJdbc); - } - - @Test - void getBookById() { - Book book = booksManageSevice.getBookById(1); - - assertAll("book", - () -> assertNotNull(book), - () -> assertEquals(1, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), - () -> assertEquals("book_1", book.getCaption()), - () -> assertEquals(1, book.getAuthorId()), - () -> assertEquals(1, book.getGenreId()), - () -> assertEquals("comment", book.getComment()) - ); - } - - @Test - void getBooks() { - List books = booksManageSevice.getBooks(); - - assertAll("books", - () -> assertNotNull(books), - () -> assertEquals(3, books.size()), - () -> assertEquals("book_1", books.get(0).getCaption()), - () -> assertEquals("book_2", books.get(1).getCaption()), - () -> assertEquals("book_3", books.get(2).getCaption()) - ); - } - - @Test - void getAuthorById() { - Author author = booksManageSevice.getAuthorById(1); - - assertAll("author", - () -> assertNotNull(author), - () -> assertEquals(1, author.getId()), - () -> assertEquals("Surname1", author.getSurname()), - () -> assertEquals("FirstName1", author.getFirstName()), - () -> assertEquals("SecondName1", author.getSecondName()) - ); - } - - @Test - void getAuthors() { - List authors = booksManageSevice.getAuthors(); - - assertAll("authors", - () -> assertNotNull(authors), - () -> assertEquals(3, authors.size()), - () -> assertEquals("Surname1", authors.get(0).getSurname()), - () -> assertEquals("Surname2", authors.get(1).getSurname()), - () -> assertEquals("Surname3", authors.get(2).getSurname()) - ); - } - - @Test - void getGenreById() { - Genre genre = booksManageSevice.getGenreById(1); - - assertAll("genre", - () -> assertNotNull(genre), - () -> assertEquals(1, genre.getId()), - () -> assertEquals("Genre1", genre.getName()) - ); - } - - @Test - void getGenres() { - List genres = booksManageSevice.getGenres(); - - assertAll("genres", - () -> assertNotNull(genres), - () -> assertEquals(3, genres.size()), - () -> assertEquals("Genre1", genres.get(0).getName()), - () -> assertEquals("Genre2", genres.get(1).getName()), - () -> assertEquals("Genre3", genres.get(2).getName()) - ); - } - - @Test - void addGenre() { - int count = booksManageSevice.addGenre("Test4"); - Genre genre = booksManageSevice.getGenreById(4); - - assertAll("genre", - () -> assertNotNull(genre), - () -> assertEquals(1, count), - () -> assertEquals(4, genre.getId()), - () -> assertEquals("Test4", genre.getName()) - ); - } - - @Test - void updateGenre() { - Genre genre1 = booksManageSevice.getGenreById(1); - int count = booksManageSevice.updateGenre(1, "UpdatedName"); - Genre genre2 = booksManageSevice.getGenreById(1); - - assertAll("genre", - () -> assertEquals(1, count), - () -> assertEquals("Genre1", genre1.getName()), - () -> assertEquals("UpdatedName", genre2.getName()) - ); - } - - @Test - void deleteGenre() { - int count = booksManageSevice.deleteGenre(1); - - assertAll("genre", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getGenreById(1); }) - ); - } - - @Test - void addBook() { - int count = booksManageSevice.addBook("Test_Book",2,3,"Test_Comment"); - Book book = booksManageSevice.getBookById(4); - - assertAll("book", - () -> assertNotNull(book), - () -> assertEquals(1, count), - () -> assertEquals(4, book.getId()), - () -> assertEquals("Test_Book", book.getCaption()), - () -> assertEquals(2, book.getAuthorId()), - () -> assertEquals(3, book.getGenreId()), - () -> assertEquals("Test_Comment", book.getComment()) - ); - } - - @Test - void updateBook() { - Book book1 = booksManageSevice.getBookById(1); - int count = booksManageSevice.updateBook(1, "Test_Book", 2, 3, "Test_Comment"); - Book book2 = booksManageSevice.getBookById(1); - - assertAll("book", - () -> assertEquals(1, count), - () -> assertEquals("book_1", book1.getCaption()), - () -> assertEquals("comment", book1.getComment()), - () -> assertEquals("Test_Book", book2.getCaption()), - () -> assertEquals("Test_Comment", book2.getComment()) - ); - } - - @Test - void deleteBook() { - int count = booksManageSevice.deleteBook(1); - - assertAll("book", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getBookById(1); }) - ); - } - - @Test - void addAuthor() { - int count = booksManageSevice.addAuthor("TestSurname", "TestFirstName", "TestSecondName"); - Author author_selected = booksManageSevice.getAuthorById(4); - - assertAll("author", - () -> assertNotNull(author_selected), - () -> assertEquals(1, count), - () -> assertEquals(4, author_selected.getId()), - () -> assertEquals("TestSurname", author_selected.getSurname()), - () -> assertEquals("TestFirstName", author_selected.getFirstName()), - () -> assertEquals("TestSecondName", author_selected.getSecondName()) - ); - } - - @Test - void updateAuthor() { - Author author1 = booksManageSevice.getAuthorById(1); - int count = booksManageSevice.updateAuthor(1,"TestSurname", "TestFirstName", "TestSecondName"); - Author author2 = booksManageSevice.getAuthorById(1); - - assertAll("author", - () -> assertEquals(1, count), - () -> assertEquals("Surname1", author1.getSurname()), - () -> assertEquals("FirstName1", author1.getFirstName()), - () -> assertEquals("SecondName1", author1.getSecondName()), - () -> assertEquals("TestSurname", author2.getSurname()), - () -> assertEquals("TestFirstName", author2.getFirstName()), - () -> assertEquals("TestSecondName", author2.getSecondName()) - ); - } - - @Test - void deleteAuthor() { - int count = booksManageSevice.deleteAuthor(1); - - assertAll("author", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getAuthorById(1); }) - ); - } -} \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java new file mode 100644 index 0000000..d8b48ab --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -0,0 +1,110 @@ +package ru.otus.mkulikov.app.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.dao.GenreDaoJdbc; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:56 + */ + +@DisplayName("Класс GenreManageSevice") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppTestConfig.class) +class GenreManageSeviceImplTest { + + private GenreManageService genreManageService; + + @BeforeEach + public void setup() { + EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("test_schema.sql") + .addScript("test_data.sql") + .build(); + + GenreDaoJdbc genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); + genreManageService = new GenreManageServiceImpl(genreDaoJdbc); + } + + @Test + void getGenreById() { + Genre genre = genreManageService.getGenreById(1); + + assertAll("genre", + () -> assertNotNull(genre), + () -> assertEquals(1, genre.getId()), + () -> assertEquals("Genre1", genre.getName()) + ); + } + + @Test + void getGenres() { + List genres = genreManageService.getGenres(); + + assertAll("genres", + () -> assertNotNull(genres), + () -> assertEquals(3, genres.size()), + () -> assertEquals("Genre1", genres.get(0).getName()), + () -> assertEquals("Genre2", genres.get(1).getName()), + () -> assertEquals("Genre3", genres.get(2).getName()) + ); + } + + @Test + void addGenre() { + int count = genreManageService.addGenre("Test4"); + Genre genre = genreManageService.getGenreById(4); + + assertAll("genre", + () -> assertNotNull(genre), + () -> assertEquals(1, count), + () -> assertEquals(4, genre.getId()), + () -> assertEquals("Test4", genre.getName()) + ); + } + + @Test + void updateGenre() { + Genre genre1 = genreManageService.getGenreById(1); + int count = genreManageService.updateGenre(1, "UpdatedName"); + Genre genre2 = genreManageService.getGenreById(1); + + assertAll("genre", + () -> assertEquals(1, count), + () -> assertEquals("Genre1", genre1.getName()), + () -> assertEquals("UpdatedName", genre2.getName()) + ); + } + + @Test + void deleteGenre() { + int count = genreManageService.deleteGenre(1); + + assertAll("genre", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { genreManageService.getGenreById(1); }) + ); + } +} diff --git a/src/test/resources/test_schema.sql b/src/test/resources/test_schema.sql index 4f8c037..d0b2b33 100644 --- a/src/test/resources/test_schema.sql +++ b/src/test/resources/test_schema.sql @@ -2,22 +2,22 @@ DROP TABLE IF EXISTS BOOK; CREATE TABLE BOOK( ID INT AUTO_INCREMENT PRIMARY KEY, ADD_RECORD_DATE DATE, - CAPTION VARCHAR(255), - AUTHOR_ID INT, - GENRE_ID INT, + CAPTION VARCHAR(255) not null, + AUTHOR_ID INT not null, + GENRE_ID INT not null, COMMENT VARCHAR(255) ); DROP TABLE IF EXISTS AUTHOR; CREATE TABLE AUTHOR( ID INT AUTO_INCREMENT PRIMARY KEY, - SURNAME VARCHAR(100), - FIRST_NAME VARCHAR(100), + SURNAME VARCHAR(100) not null, + FIRST_NAME VARCHAR(100) not null, SECOND_NAME VARCHAR(100) ); DROP TABLE IF EXISTS GENRE; CREATE TABLE GENRE( ID INT AUTO_INCREMENT PRIMARY KEY, - NAME VARCHAR(100), + NAME VARCHAR(100) not null ); \ No newline at end of file From ff74ea4e72ee35dc6c28f1b7ff918e5ab7db54d9 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Fri, 31 May 2019 16:30:54 +0300 Subject: [PATCH 15/30] =?UTF-8?q?-=20JdbcOperations=20=D0=B7=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=20=D0=BD=D0=B0=20NamedParameterJdbcOpe?= =?UTF-8?q?rations.=20-=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D1=8B?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D1=8B=20=D0=BA=D0=BD?= =?UTF-8?q?=D0=B8=D0=B3.=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B8=D1=85?= =?UTF-8?q?=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D1=8B=20=D0=BA=D0=BD=D0=B8?= =?UTF-8?q?=D0=B3.=20-=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20Boo?= =?UTF-8?q?k.=20-=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=82=D0=B8=D0=BF=D0=B0=20id.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/Application.java | 1 + .../ru/otus/mkulikov/app/dao/AuthorDao.java | 4 +- .../otus/mkulikov/app/dao/AuthorDaoJdbc.java | 37 +++-- .../ru/otus/mkulikov/app/dao/BookDao.java | 4 +- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 103 +++++++++---- .../ru/otus/mkulikov/app/dao/GenreDao.java | 4 +- .../otus/mkulikov/app/dao/GenreDaoJdbc.java | 35 +++-- .../ru/otus/mkulikov/app/model/Author.java | 6 +- .../java/ru/otus/mkulikov/app/model/Book.java | 25 ++-- .../ru/otus/mkulikov/app/model/Genre.java | 6 +- .../app/service/AuthorManageService.java | 6 +- .../app/service/AuthorManageServiceImpl.java | 6 +- .../app/service/BookManageSevice.java | 8 +- .../app/service/BookManageSeviceImpl.java | 36 +++-- .../app/service/GenreManageService.java | 6 +- .../app/service/GenreManageServiceImpl.java | 6 +- .../otus/mkulikov/shell/AuthorCommands.java | 6 +- .../ru/otus/mkulikov/shell/BookCommands.java | 8 +- .../ru/otus/mkulikov/shell/GenreCommands.java | 6 +- src/main/resources/application.yml | 8 ++ src/main/resources/data.sql | 6 +- src/main/resources/schema.sql | 31 ++-- .../java/ru/otus/mkulikov/AppTestConfig.java | 43 ++++++ .../mkulikov/app/dao/AuthorDaoJdbcTest.java | 104 +++++++------- .../mkulikov/app/dao/BookDaoJdbcTest.java | 121 ++++++++-------- .../mkulikov/app/dao/GenreDaoJdbcTest.java | 81 +++++------ .../ru/otus/mkulikov/app/model/BookTest.java | 15 +- .../service/AuthorManageSeviceImplTest.java | 97 ++++++------- .../app/service/BookManageSeviceImplTest.java | 135 +++++++++--------- .../service/GenreManageSeviceImplTest.java | 79 +++++----- src/test/resources/test_data.sql | 27 ---- src/test/resources/test_schema.sql | 23 --- 32 files changed, 565 insertions(+), 518 deletions(-) delete mode 100644 src/test/resources/test_data.sql delete mode 100644 src/test/resources/test_schema.sql diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index a45b459..70a6c6d 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.PropertySource; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java index dfeba2f..099b02b 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java @@ -13,13 +13,13 @@ public interface AuthorDao { - T getById(int id); + T getById(long id); List getAllObjects(); int addObject(T t); - int deleteObject(int id); + int deleteObject(long id); int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java index ae64ebd..8f23571 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -1,14 +1,17 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; -import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.stereotype.Repository; import ru.otus.mkulikov.app.model.Author; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Created by IntelliJ IDEA. @@ -22,40 +25,46 @@ @RequiredArgsConstructor public class AuthorDaoJdbc implements AuthorDao { - private final JdbcOperations jdbcOperations; + private final NamedParameterJdbcOperations namedParameterJdbcOperations; @Override - public Author getById(int id) { - return jdbcOperations.queryForObject("select * from Author where id = ? ", new Object[]{id}, new AuthorMapper()); + public Author getById(long id) { + Map paramMap = new HashMap(); + paramMap.put("id", id); + + return namedParameterJdbcOperations.queryForObject("select * from Author where id = :id ", paramMap, new AuthorMapper()); } @Override public List getAllObjects() { - return jdbcOperations.query("select * from Author order by id", new AuthorMapper()); + return namedParameterJdbcOperations.query("select * from Author order by id", new AuthorMapper()); } @Override public int addObject(Author author) { - return jdbcOperations.update( - "insert into Author (surname, first_name, second_name) values (?,?,?)", - new Object[]{author.getSurname(), author.getFirstName(), author.getSecondName()} + return namedParameterJdbcOperations.update( + "insert into Author (surname, first_name, second_name) values (:surname, :firstName, :secondName)", + new BeanPropertySqlParameterSource(author) ); } @Override - public int deleteObject(int id) { - return jdbcOperations.update("delete from Author where id = ? ", new Object[]{id}); + public int deleteObject(long id) { + Map paramMap = new HashMap(); + paramMap.put("id", id); + + return namedParameterJdbcOperations.update("delete from Author where id = :id ", paramMap); } @Override public int updateObject(Author author) { - return jdbcOperations.update( - "update Author set surname = ?, first_name = ?, second_name = ? where id = ? ", - new Object[]{author.getSurname(), author.getFirstName(), author.getSecondName(), author.getId()} + return namedParameterJdbcOperations.update( + "update Author set surname = :surname, first_name = :firstName, second_name = :secondName where id = :id ", + new BeanPropertySqlParameterSource(author) ); } - private static class AuthorMapper implements RowMapper { + public static class AuthorMapper implements RowMapper { @Override public Author mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java index 431f064..3e2faa1 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java @@ -13,13 +13,13 @@ public interface BookDao { - T getById(int id); + T getById(long id); List getAllObjects(); int addObject(T t); - int deleteObject(int id); + int deleteObject(long id); int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 89a0c16..2ab1c2a 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -1,16 +1,20 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; -import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.stereotype.Repository; +import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Timestamp; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Created by IntelliJ IDEA. @@ -24,51 +28,100 @@ @RequiredArgsConstructor public class BookDaoJdbc implements BookDao { - private final JdbcOperations jdbcOperations; + private final NamedParameterJdbcOperations namedParameterJdbcOperations; + + private final String BOOK_SELECT = + "select b.*, a.surname, a.first_name, a.second_name, g.name " + + "from Book b " + + "inner join Author a on a.id = b.author_id " + + "inner join Genre g on g.id = b.genre_id " + + "where id = :id "; + + private final String BOOK_SELECT_ALL = + "select b.*, a.surname, a.first_name, a.second_name, g.name " + + "from Book b " + + "inner join Author a on a.id = b.author_id " + + "inner join Genre g on g.id = b.genre_id " + + "order by b.id "; + + private final String BOOK_UPDATE = + "update Book " + + "set add_record_date = sysdate, caption = :caption, author_id = :author_id, genre_id = :genre_id, comment = :comment " + + "where id = :id "; + + private final String BOOK_INSERT = + "insert into Book (add_record_date, caption, author_id, genre_id, comment) " + + " values (sysdate, :caption, :author_id, :genre_id, :comment)"; + + private final String BOOK_DELETE = "delete from Book where id = :id "; @Override - public Book getById(int id) { - return jdbcOperations.queryForObject("select * from Book where id = ? ", new Object[]{id}, new BookMapper()); + public Book getById(long id) { + Map paramMap = new HashMap(); + paramMap.put("id", id); + + List books = namedParameterJdbcOperations.query(BOOK_SELECT, paramMap, new BookMapper()); + return (books != null) ? books.get(0) : null; } @Override public List getAllObjects() { - return jdbcOperations.query("select * from Book order by id", new BookMapper()); + return namedParameterJdbcOperations.query(BOOK_SELECT_ALL, new BookMapper()); } @Override public int addObject(Book book) { - return jdbcOperations.update( - "insert into Book (add_record_date, caption, author_id, genre_id, comment) values (sysdate,?,?,?,?)", - new Object[]{book.getCaption(), book.getAuthorId(), book.getGenreId(), book.getComment()} - ); + Map paramMap = new HashMap(); + paramMap.put("caption", book.getCaption()); + paramMap.put("author_id", book.getAuthor().getId()); + paramMap.put("genre_id", book.getGenre().getId()); + paramMap.put("comment", book.getComment()); + + return namedParameterJdbcOperations.update(BOOK_INSERT, paramMap); } @Override - public int deleteObject(int id) { - return jdbcOperations.update("delete from Book where id = ? ", new Object[]{id}); + public int deleteObject(long id) { + Map paramMap = new HashMap(); + paramMap.put("id", id); + + return namedParameterJdbcOperations.update(BOOK_DELETE, paramMap); } @Override public int updateObject(Book book) { - return jdbcOperations.update( - "update Book set add_record_date = sysdate, caption = ?, author_id = ?, genre_id = ?, comment = ? where id = ? ", - new Object[]{book.getCaption(), book.getAuthorId(), book.getGenreId(), book.getComment(), book.getId()} - ); + Map paramMap = new HashMap(); + paramMap.put("caption", book.getCaption()); + paramMap.put("author_id", book.getAuthor().getId()); + paramMap.put("genre_id", book.getGenre().getId()); + paramMap.put("comment", book.getComment()); + paramMap.put("id", book.getId()); + + return namedParameterJdbcOperations.update(BOOK_UPDATE, paramMap); } - private static class BookMapper implements RowMapper { + public static class BookMapper implements RowMapper { @Override public Book mapRow(ResultSet resultSet, int i) throws SQLException { - int id = resultSet.getInt("ID"); - Date addRecordDate = resultSet.getDate("ADD_RECORD_DATE"); - String caption = resultSet.getString("CAPTION"); - int author_id = resultSet.getInt("AUTHOR_ID"); - int genre_id = resultSet.getInt("GENRE_ID"); - String comment = resultSet.getString("COMMENT"); - - return new Book(id, addRecordDate, caption, author_id, genre_id, comment); + int id = resultSet.getInt("id"); + Date addRecordDate = resultSet.getDate("add_record_date"); + String caption = resultSet.getString("caption"); + String comment = resultSet.getString("comment"); + + Author author = new Author( + resultSet.getLong("author_id"), + resultSet.getString("surname"), + resultSet.getString("first_name"), + resultSet.getString("second_name") + ); + + Genre genre = new Genre( + resultSet.getLong("genre_id"), + resultSet.getString("name") + ); + + return new Book(id, addRecordDate, caption, author, genre, comment); } } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java index bffc90d..348b84d 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java @@ -13,13 +13,13 @@ public interface GenreDao { - T getById(int id); + T getById(long id); List getAllObjects(); int addObject(T t); - int deleteObject(int id); + int deleteObject(long id); int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java index 2ee2fe5..627c1e5 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java @@ -1,18 +1,17 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.stereotype.Repository; import ru.otus.mkulikov.app.model.Genre; -import javax.annotation.PostConstruct; -import javax.sql.DataSource; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Created by IntelliJ IDEA. @@ -26,31 +25,41 @@ @RequiredArgsConstructor public class GenreDaoJdbc implements GenreDao { - private final JdbcOperations jdbcOperations; + private final NamedParameterJdbcOperations namedParameterJdbcOperations; @Override - public Genre getById(int id) { - return jdbcOperations.queryForObject("select * from Genre where id = ? ", new Object[]{id}, new GenreMapper()); + public Genre getById(long id) { + Map paramMap = new HashMap(); + paramMap.put("id", id); + + return namedParameterJdbcOperations.queryForObject("select * from Genre where id = :id ", paramMap, new GenreMapper()); } @Override public List getAllObjects() { - return jdbcOperations.query("select * from Genre order by id", new GenreMapper()); + return namedParameterJdbcOperations.query("select * from Genre order by id", new GenreMapper()); } @Override public int addObject(Genre genre) { - return jdbcOperations.update("insert into Genre (name) values (?)", new Object[]{genre.getName()}); + return namedParameterJdbcOperations.update( + "insert into Genre (name) values (:name)", + new BeanPropertySqlParameterSource(genre)); } @Override - public int deleteObject(int id) { - return jdbcOperations.update("delete from Genre where id = ? ", new Object[]{id}); + public int deleteObject(long id) { + Map paramMap = new HashMap(); + paramMap.put("id", id); + + return namedParameterJdbcOperations.update("delete from Genre where id = :id ", paramMap); } @Override public int updateObject(Genre genre) { - return jdbcOperations.update("update Genre set name = ? where id = ? ", new Object[]{genre.getName(), genre.getId()}); + return namedParameterJdbcOperations.update( + "update Genre set name = :name where id = :id ", + new BeanPropertySqlParameterSource(genre)); } public static class GenreMapper implements RowMapper { diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index d087534..d3bd662 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -12,12 +12,12 @@ @Data public class Author { - private final int id; + private final long id; private final String surname; private final String firstName; private final String secondName; - public Author(int id, String surname, String firstName, String secondName) { + public Author(long id, String surname, String firstName, String secondName) { this.id = id; this.surname = surname; this.firstName = firstName; @@ -25,7 +25,7 @@ public Author(int id, String surname, String firstName, String secondName) { } public Author(String surname, String firstName, String secondName) { - this.id = 0; + this.id = 0L; this.surname = surname; this.firstName = firstName; this.secondName = secondName; diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 7c87c7a..a70181d 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -5,7 +5,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; /** * Created by IntelliJ IDEA. @@ -17,36 +16,34 @@ @Data public class Book { - private int id; + private long id; private Date addRecordDate; private String caption; - private int authorId; - private int genreId; private Author author; private Genre genre; private String comment; - public Book(int id, Date addRecordDate, String caption, int authorId, int genreId, String comment) { + public Book(long id, Date addRecordDate, String caption, Author author, Genre genre, String comment) { this.id = id; this.addRecordDate = addRecordDate; + this.author = author; + this.genre = genre; this.caption = caption; - this.authorId = authorId; - this.genreId = genreId; this.comment = comment; } - public Book(int id, String caption, int authorId, int genreId, String comment) { + public Book(long id, String caption, Author author, Genre genre, String comment) { this.id = id; this.caption = caption; - this.authorId = authorId; - this.genreId = genreId; + this.author = author; + this.genre = genre; this.comment = comment; } - public Book(String caption, int authorId, int genreId, String comment) { + public Book(String caption, Author author, Genre genre, String comment) { this.caption = caption; - this.authorId = authorId; - this.genreId = genreId; + this.author = author; + this.genre = genre; this.comment = comment; } @@ -73,8 +70,6 @@ public String toString() { "id=" + id + ", addRecordDate=" + addRecordDate + ", caption='" + caption + '\'' + - ", authorId=" + authorId + - ", genreId=" + genreId + ", comment='" + comment + '\'' + getAuthorString() + getGenreString() + diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 2f2d528..5dff2a6 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -12,16 +12,16 @@ @Data public class Genre { - private final int id; + private final long id; private final String name; - public Genre(int id, String name) { + public Genre(long id, String name) { this.id = id; this.name = name; } public Genre(String name) { - this.id = 0; + this.id = 0L; this.name = name; } diff --git a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java index b11706d..2ebc5f1 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java +++ b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageService.java @@ -13,13 +13,13 @@ public interface AuthorManageService { - T getAuthorById(int id); + T getAuthorById(long id); List getAuthors(); int addAuthor(String surname, String firstName, String secondName); - int updateAuthor(int id, String surname, String firstName, String secondName); + int updateAuthor(long id, String surname, String firstName, String secondName); - int deleteAuthor(int id); + int deleteAuthor(long id); } diff --git a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java index 9237363..63632f9 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java @@ -21,7 +21,7 @@ public class AuthorManageServiceImpl implements AuthorManageService { private final AuthorDao authorDao; @Override - public Author getAuthorById(int id) { + public Author getAuthorById(long id) { return authorDao.getById(id); } @@ -36,12 +36,12 @@ public int addAuthor(String surname, String firstName, String secondName) { } @Override - public int updateAuthor(int id, String surname, String firstName, String secondName) { + public int updateAuthor(long id, String surname, String firstName, String secondName) { return authorDao.updateObject(new Author(id, surname, firstName, secondName)); } @Override - public int deleteAuthor(int id) { + public int deleteAuthor(long id) { return authorDao.deleteObject(id); } } diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java index 552cd31..4dab791 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java @@ -13,9 +13,9 @@ public interface BookManageSevice { - T getBookById(int id); + T getBookById(long id); - T getFullBookById(int id); + T getFullBookById(long id); List getBooks(); @@ -23,7 +23,7 @@ public interface BookManageSevice { int addBook(String caption, int authorId, int genreId, String comment); - int updateBook(int id, String caption, int authorId, int genreId, String comment); + int updateBook(long id, String caption, int authorId, int genreId, String comment); - int deleteBook(int id); + int deleteBook(long id); } diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java index b64c332..f73beca 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java @@ -5,7 +5,9 @@ import ru.otus.mkulikov.app.dao.AuthorDao; import ru.otus.mkulikov.app.dao.BookDao; import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -20,19 +22,18 @@ @RequiredArgsConstructor public class BookManageSeviceImpl implements BookManageSevice { - private final AuthorDao authorDao; private final BookDao bookDao; + private final AuthorDao authorDao; private final GenreDao genreDao; @Override - public Book getBookById(int id) { + public Book getBookById(long id) { return bookDao.getById(id); } @Override - public Book getFullBookById(int id) { - Book book = bookDao.getById(id); - return setBookInfo(book); + public Book getFullBookById(long id) { + return bookDao.getById(id); } @Override @@ -42,31 +43,28 @@ public List getBooks() { @Override public List getFullBooks() { - List books = bookDao.getAllObjects(); - for (Book book : books) { - setBookInfo(book); - } - return books; + return bookDao.getAllObjects(); } - private Book setBookInfo(Book book) { - book.setAuthor(authorDao.getById(book.getAuthorId())); - book.setGenre(genreDao.getById(book.getGenreId())); - return book; - } @Override public int addBook(String caption, int authorId, int genreId, String comment) { - return bookDao.addObject(new Book(caption, authorId, genreId, comment)); + Author author = authorDao.getById(authorId); + Genre genre = genreDao.getById(genreId); + + return bookDao.addObject(new Book(caption, author, genre, comment)); } @Override - public int updateBook(int id, String caption, int authorId, int genreId, String comment) { - return bookDao.updateObject(new Book(id, caption, authorId, genreId, comment)); + public int updateBook(long id, String caption, int authorId, int genreId, String comment) { + Author author = authorDao.getById(authorId); + Genre genre = genreDao.getById(genreId); + + return bookDao.updateObject(new Book(id, caption, author, genre, comment)); } @Override - public int deleteBook(int id) { + public int deleteBook(long id) { return bookDao.deleteObject(id); } } diff --git a/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java b/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java index b811b8e..d2f62af 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java +++ b/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java @@ -12,13 +12,13 @@ */ public interface GenreManageService { - Genre getGenreById(int id); + Genre getGenreById(long id); List getGenres(); int addGenre(String name); - int updateGenre(int id, String name); + int updateGenre(long id, String name); - int deleteGenre(int id); + int deleteGenre(long id); } diff --git a/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java index f2e21ac..f0b56a6 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java @@ -21,7 +21,7 @@ public class GenreManageServiceImpl implements GenreManageService { private final GenreDao genreDao; @Override - public Genre getGenreById(int id) { + public Genre getGenreById(long id) { return genreDao.getById(id); } @@ -36,12 +36,12 @@ public int addGenre(String name) { } @Override - public int updateGenre(int id, String name) { + public int updateGenre(long id, String name) { return genreDao.updateObject(new Genre(id, name)); } @Override - public int deleteGenre(int id) { + public int deleteGenre(long id) { return genreDao.deleteObject(id); } } diff --git a/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java b/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java index 550b846..6fac36a 100644 --- a/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java @@ -23,7 +23,7 @@ public class AuthorCommands { private final AuthorManageService authorManageService; @ShellMethod(key = { "getAuthorById" }, value = "Select author by id.") - public String getAuthorById(@ShellOption int id) { + public String getAuthorById(@ShellOption long id) { Author author = authorManageService.getAuthorById(id); return author.toString(); } @@ -41,13 +41,13 @@ public String addAuthor(@ShellOption String surname, @ShellOption String firstNa } @ShellMethod(key = { "updateAuthor" }, value = "Update author by id.") - public String updateAuthor(@ShellOption int id, @ShellOption String surname, @ShellOption String firstName, @ShellOption String secondName) { + public String updateAuthor(@ShellOption long id, @ShellOption String surname, @ShellOption String firstName, @ShellOption String secondName) { int count = authorManageService.updateAuthor(id, surname, firstName, secondName); return "Updated " + count + " row(s)"; } @ShellMethod(key = { "deleteAuthor" }, value = "Delete author by id.") - public String deleteAuthor(@ShellOption int id) { + public String deleteAuthor(@ShellOption long id) { int count = authorManageService.deleteAuthor(id); return "Deleted " + count + " row(s)"; } diff --git a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java index aa70aaa..a8a998e 100644 --- a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java @@ -23,13 +23,13 @@ public class BookCommands { private final BookManageSevice bookManageSevice; @ShellMethod(key = { "getBookById" }, value = "Select book by id.") - public String getBookById(@ShellOption int id) { + public String getBookById(@ShellOption long id) { Book book = bookManageSevice.getBookById(id); return book.toString(); } @ShellMethod(key = { "getFullBookById" }, value = "Select book by id.") - public String getFullBookById(@ShellOption int id) { + public String getFullBookById(@ShellOption long id) { Book book = bookManageSevice.getFullBookById(id); return book.toString(); } @@ -53,13 +53,13 @@ public String addBook(@ShellOption String caption, @ShellOption int authorId, @S } @ShellMethod(key = { "updateBook" }, value = "Update book by id.") - public String updateBook(@ShellOption int id, @ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { + public String updateBook(@ShellOption long id, @ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { int count = bookManageSevice.updateBook(id, caption, authorId, genreId, comment); return "Updated " + count + " row(s)"; } @ShellMethod(key = { "deleteBook" }, value = "Delete book by id.") - public String deleteBook(@ShellOption int id) { + public String deleteBook(@ShellOption long id) { int count = bookManageSevice.deleteBook(id); return "Deleted " + count + " row(s)"; } diff --git a/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java b/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java index 2e6a3ac..e0959bf 100644 --- a/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java @@ -23,7 +23,7 @@ public class GenreCommands { private final GenreManageService genreManageService; @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") - public String getGenreById(@ShellOption int id) { + public String getGenreById(@ShellOption long id) { Genre genre = genreManageService.getGenreById(id); return genre.toString(); } @@ -41,13 +41,13 @@ public String addGenre(@ShellOption String name) { } @ShellMethod(key = { "updateGenre" }, value = "Update genre by id.") - public String updateGenre(@ShellOption int id, @ShellOption String name) { + public String updateGenre(@ShellOption long id, @ShellOption String name) { int count = genreManageService.updateGenre(id, name); return "Updated " + count + " row(s)"; } @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") - public String deleteGenre(@ShellOption int id) { + public String deleteGenre(@ShellOption long id) { int count = genreManageService.deleteGenre(id); return "Deleted " + count + " row(s)"; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6e8162e..4252b7d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,11 @@ spring: + datasource: + data: "classpath:data.sql" + schema: "classpath:schema.sql" + username: "SA" + password: "" + driver-class-name: "org.h2.Driver" + url: "jdbc:h2:mem:test" + banner: location: "classpath:banner.txt" diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index e255fb4..1372099 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -16,12 +16,12 @@ insert into GENRE (NAME) values ('Genre3'); -------------------------- insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (sysdate, 'book_1', 1, 1, 'comment'); +values (to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (sysdate, 'book_2', 1, 1, 'comment'); +values (to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (sysdate, 'book_3', 1, 1, 'comment'); +values (to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); -------------------------- diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index d0b2b33..c18e8d2 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,23 +1,28 @@ DROP TABLE IF EXISTS BOOK; -CREATE TABLE BOOK( - ID INT AUTO_INCREMENT PRIMARY KEY, - ADD_RECORD_DATE DATE, - CAPTION VARCHAR(255) not null, - AUTHOR_ID INT not null, - GENRE_ID INT not null, - COMMENT VARCHAR(255) -); - DROP TABLE IF EXISTS AUTHOR; +DROP TABLE IF EXISTS GENRE; + CREATE TABLE AUTHOR( - ID INT AUTO_INCREMENT PRIMARY KEY, + ID NUMBER(22,0) AUTO_INCREMENT PRIMARY KEY, SURNAME VARCHAR(100) not null, FIRST_NAME VARCHAR(100) not null, SECOND_NAME VARCHAR(100) ); -DROP TABLE IF EXISTS GENRE; CREATE TABLE GENRE( - ID INT AUTO_INCREMENT PRIMARY KEY, + ID NUMBER(22,0) AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100) not null -); \ No newline at end of file +); + +CREATE TABLE BOOK( + ID NUMBER(22,0) AUTO_INCREMENT PRIMARY KEY, + ADD_RECORD_DATE DATE, + CAPTION VARCHAR(255) not null, + AUTHOR_ID INT not null, + GENRE_ID INT not null, + COMMENT VARCHAR(255), + + foreign key (AUTHOR_ID) references AUTHOR(ID), + foreign key (GENRE_ID) references GENRE(ID) +); + diff --git a/src/test/java/ru/otus/mkulikov/AppTestConfig.java b/src/test/java/ru/otus/mkulikov/AppTestConfig.java index 85f7510..376bdc6 100644 --- a/src/test/java/ru/otus/mkulikov/AppTestConfig.java +++ b/src/test/java/ru/otus/mkulikov/AppTestConfig.java @@ -1,7 +1,19 @@ package ru.otus.mkulikov; import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.PropertySource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import ru.otus.mkulikov.app.dao.BookDaoJdbc; + +import javax.sql.DataSource; /** * Created by IntelliJ IDEA. @@ -11,6 +23,37 @@ */ @SpringBootConfiguration +@ComponentScan("ru.otus.mkulikov.app") +@PropertySource({"classpath:application.yml"}) @EnableConfigurationProperties public class AppTestConfig { + + @Bean + public NamedParameterJdbcOperations getNamedParameterJdbcOperations(DataSource dataSource) { + return new NamedParameterJdbcTemplate(dataSource); + } + + //@Bean + //public DataSource getDataSource() { + // DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); + // dataSourceBuilder.driverClassName("org.h2.Driver"); + // dataSourceBuilder.url("jdbc:h2:mem:test"); + // dataSourceBuilder.username("SA"); + // dataSourceBuilder.password(""); + // return dataSourceBuilder.build(); + //} + + @Bean + @Primary + @ConfigurationProperties("application.yml") + public DataSourceProperties getDatasourceProperties() { + return new DataSourceProperties(); + } + + @Bean + //@ConfigurationProperties("datasource.oracle") + public DataSource getDatasource() { + return getDatasourceProperties().initializeDataSourceBuilder() + .build(); + } } diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java index 38b0fad..145835b 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java @@ -4,9 +4,13 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; @@ -16,7 +20,10 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * Created by IntelliJ IDEA. @@ -30,29 +37,20 @@ @SpringBootTest(classes = AppTestConfig.class) class AuthorDaoJdbcTest { + @Autowired private AuthorDaoJdbc authorDaoJdbc; - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - - authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); - } - @Test void getById() { - Author author = authorDaoJdbc.getById(1); - - assertAll("author", - () -> assertNotNull(author), - () -> assertEquals(1, author.getId()), - () -> assertEquals("Surname1", author.getSurname()), - () -> assertEquals("FirstName1", author.getFirstName()), - () -> assertEquals("SecondName1", author.getSecondName()) + Author author = authorDaoJdbc.getById(1L); + + assertAll( + "author", + () -> assertNotNull(author), + () -> assertEquals(1L, author.getId()), + () -> assertEquals("Surname1", author.getSurname()), + () -> assertEquals("FirstName1", author.getFirstName()), + () -> assertEquals("SecondName1", author.getSecondName()) ); } @@ -60,12 +58,13 @@ void getById() { void getAllObjects() { List authors = authorDaoJdbc.getAllObjects(); - assertAll("authors", - () -> assertNotNull(authors), - () -> assertEquals(3, authors.size()), - () -> assertEquals("Surname1", authors.get(0).getSurname()), - () -> assertEquals("Surname2", authors.get(1).getSurname()), - () -> assertEquals("Surname3", authors.get(2).getSurname()) + assertAll( + "authors", + () -> assertNotNull(authors), + () -> assertEquals(3, authors.size()), + () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname2", authors.get(1).getSurname()), + () -> assertEquals("Surname3", authors.get(2).getSurname()) ); } @@ -73,44 +72,41 @@ void getAllObjects() { void addObject() { Author author = new Author("TestSurname", "TestFirstName", "TestSecondName"); int count = authorDaoJdbc.addObject(author); - Author author_selected = authorDaoJdbc.getById(4); - - assertAll("author", - () -> assertNotNull(author_selected), - () -> assertEquals(1, count), - () -> assertEquals(4, author_selected.getId()), - () -> assertEquals(author.getSurname(), author_selected.getSurname()), - () -> assertEquals(author.getFirstName(), author_selected.getFirstName()), - () -> assertEquals(author.getSecondName(), author_selected.getSecondName()) + Author author_selected = authorDaoJdbc.getById(4L); + + assertAll( + "author", + () -> assertNotNull(author_selected), + () -> assertEquals(1, count), + () -> assertEquals(4, author_selected.getId()), + () -> assertEquals(author.getSurname(), author_selected.getSurname()), + () -> assertEquals(author.getFirstName(), author_selected.getFirstName()), + () -> assertEquals(author.getSecondName(), author_selected.getSecondName()) ); } @Test void deleteObject() { - int count = authorDaoJdbc.deleteObject(1); - - assertAll("author", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { authorDaoJdbc.getById(1); }) - ); + assertThrows(DataIntegrityViolationException.class, () -> { authorDaoJdbc.deleteObject(1L); }); } @Test void updateObject() { - Author author1 = authorDaoJdbc.getById(1); + Author author1 = authorDaoJdbc.getById(1L); int count = authorDaoJdbc.updateObject( - new Author(1,"TestSurname", "TestFirstName", "TestSecondName") + new Author(1L, "TestSurname", "TestFirstName", "TestSecondName") ); - Author author2 = authorDaoJdbc.getById(1); - - assertAll("author", - () -> assertEquals(1, count), - () -> assertEquals("Surname1", author1.getSurname()), - () -> assertEquals("FirstName1", author1.getFirstName()), - () -> assertEquals("SecondName1", author1.getSecondName()), - () -> assertEquals("TestSurname", author2.getSurname()), - () -> assertEquals("TestFirstName", author2.getFirstName()), - () -> assertEquals("TestSecondName", author2.getSecondName()) + Author author2 = authorDaoJdbc.getById(1L); + + assertAll( + "author", + () -> assertEquals(1, count), + () -> assertEquals("Surname1", author1.getSurname()), + () -> assertEquals("FirstName1", author1.getFirstName()), + () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("TestSurname", author2.getSurname()), + () -> assertEquals("TestFirstName", author2.getFirstName()), + () -> assertEquals("TestSecondName", author2.getSecondName()) ); } } \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java index f019089..d48684b 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java @@ -4,20 +4,29 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Genre; import java.util.Date; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * Created by IntelliJ IDEA. @@ -31,31 +40,22 @@ @SpringBootTest(classes = AppTestConfig.class) class BookDaoJdbcTest { + @Autowired private BookDaoJdbc bookDaoJdbc; - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - - bookDaoJdbc = new BookDaoJdbc(new JdbcTemplate(db)); - } - @Test void getById() { - Book book = bookDaoJdbc.getById(1); - - assertAll("book", - () -> assertNotNull(book), - () -> assertEquals(1, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), - () -> assertEquals("book_1", book.getCaption()), - () -> assertEquals(1, book.getAuthorId()), - () -> assertEquals(1, book.getGenreId()), - () -> assertEquals("comment", book.getComment()) + Book book = bookDaoJdbc.getById(1L); + + assertAll( + "book", + () -> assertNotNull(book), + () -> assertEquals(1L, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthor().getId()), + () -> assertEquals(1, book.getGenre().getId()), + () -> assertEquals("comment", book.getComment()) ); } @@ -63,58 +63,63 @@ void getById() { void getAllObjects() { List books = bookDaoJdbc.getAllObjects(); - assertAll("books", - () -> assertNotNull(books), - () -> assertEquals(3, books.size()), - () -> assertEquals("book_1", books.get(0).getCaption()), - () -> assertEquals("book_2", books.get(1).getCaption()), - () -> assertEquals("book_3", books.get(2).getCaption()) + assertAll( + "books", + () -> assertNotNull(books), + () -> assertEquals(3, books.size()), + () -> assertEquals("book_1", books.get(0).getCaption()), + () -> assertEquals("book_2", books.get(1).getCaption()), + () -> assertEquals("book_3", books.get(2).getCaption()) ); } @Test void addObject() { - int count = bookDaoJdbc.addObject( - new Book("Test_Book",2,3,"Test_Comment") - ); - - Book book = bookDaoJdbc.getById(4); - - assertAll("book", - () -> assertNotNull(book), - () -> assertEquals(1, count), - () -> assertEquals(4, book.getId()), - () -> assertEquals("Test_Book", book.getCaption()), - () -> assertEquals(2, book.getAuthorId()), - () -> assertEquals(3, book.getGenreId()), - () -> assertEquals("Test_Comment", book.getComment()) + int count = bookDaoJdbc.addObject(getNewBook()); + Book book = bookDaoJdbc.getById(4L); + + assertAll( + "book", + () -> assertNotNull(book), + () -> assertEquals(1, count), + () -> assertEquals(4L, book.getId()), + () -> assertEquals("Test_Book", book.getCaption()), + () -> assertEquals(1, book.getAuthor().getId()), + () -> assertEquals(1, book.getGenre().getId()), + () -> assertEquals("Test_Comment", book.getComment()) ); } @Test void deleteObject() { - int count = bookDaoJdbc.deleteObject(1); + int count = bookDaoJdbc.deleteObject(1L); - assertAll("book", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { bookDaoJdbc.getById(1); }) + assertAll( + "book", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { bookDaoJdbc.getById(1L); }) ); } @Test void updateObject() { - Book book1 = bookDaoJdbc.getById(1); - int count = bookDaoJdbc.updateObject( - new Book(1, new Date(),"Test_Book",2,3,"Test_Comment") - ); - Book book2 = bookDaoJdbc.getById(1); - - assertAll("book", - () -> assertEquals(1, count), - () -> assertEquals("book_1", book1.getCaption()), - () -> assertEquals("comment", book1.getComment()), - () -> assertEquals("Test_Book", book2.getCaption()), - () -> assertEquals("Test_Comment", book2.getComment()) + Book book1 = bookDaoJdbc.getById(1L); + int count = bookDaoJdbc.updateObject(getNewBook()); + Book book2 = bookDaoJdbc.getById(1L); + + assertAll( + "book", + () -> assertEquals(1, count), + () -> assertEquals("book_1", book1.getCaption()), + () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("Test_Book", book2.getCaption()), + () -> assertEquals("Test_Comment", book2.getComment()) ); } + + private Book getNewBook() { + Author author = new Author(1L, "TestSurname", "TestFirstName", "TestSecondName"); + Genre genre = new Genre(1L, "Test4"); + return new Book(1L, new Date(), "Test_Book", author, genre, "Test_Comment"); + } } \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java index c9590e4..9dc952c 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java @@ -4,8 +4,9 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; @@ -16,7 +17,10 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * Created by IntelliJ IDEA. @@ -30,27 +34,18 @@ @SpringBootTest(classes = AppTestConfig.class) class GenreDaoJdbcTest { + @Autowired private GenreDaoJdbc genreDaoJdbc; - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - - genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); - } - @Test void getById() { - Genre genre = genreDaoJdbc.getById(1); + Genre genre = genreDaoJdbc.getById(1L); - assertAll("genre", - () -> assertNotNull(genre), - () -> assertEquals(1, genre.getId()), - () -> assertEquals("Genre1", genre.getName()) + assertAll( + "genre", + () -> assertNotNull(genre), + () -> assertEquals(1L, genre.getId()), + () -> assertEquals("Genre1", genre.getName()) ); } @@ -58,12 +53,13 @@ void getById() { void getAllObjects() { List genres = genreDaoJdbc.getAllObjects(); - assertAll("genres", - () -> assertNotNull(genres), - () -> assertEquals(3, genres.size()), - () -> assertEquals("Genre1", genres.get(0).getName()), - () -> assertEquals("Genre2", genres.get(1).getName()), - () -> assertEquals("Genre3", genres.get(2).getName()) + assertAll( + "genres", + () -> assertNotNull(genres), + () -> assertEquals(3, genres.size()), + () -> assertEquals("Genre1", genres.get(0).getName()), + () -> assertEquals("Genre2", genres.get(1).getName()), + () -> assertEquals("Genre3", genres.get(2).getName()) ); } @@ -71,36 +67,33 @@ void getAllObjects() { void addObject() { int count = genreDaoJdbc.addObject(new Genre("Test4")); - Genre genre = genreDaoJdbc.getById(4); + Genre genre = genreDaoJdbc.getById(4L); - assertAll("genre", - () -> assertNotNull(genre), - () -> assertEquals(1, count), - () -> assertEquals(4, genre.getId()), - () -> assertEquals("Test4", genre.getName()) + assertAll( + "genre", + () -> assertNotNull(genre), + () -> assertEquals(1, count), + () -> assertEquals(4L, genre.getId()), + () -> assertEquals("Test4", genre.getName()) ); } @Test void deleteObject() { - int count = genreDaoJdbc.deleteObject(1); - - assertAll("genre", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { genreDaoJdbc.getById(1); }) - ); + assertThrows(DataIntegrityViolationException.class, () -> { genreDaoJdbc.deleteObject(1L); }); } @Test void updateObject() { - Genre genre1 = genreDaoJdbc.getById(1); - int count = genreDaoJdbc.updateObject(new Genre(1, "UpdatedName")); - Genre genre2 = genreDaoJdbc.getById(1); - - assertAll("genre", - () -> assertEquals(1, count), - () -> assertEquals("Genre1", genre1.getName()), - () -> assertEquals("UpdatedName", genre2.getName()) + Genre genre1 = genreDaoJdbc.getById(1L); + int count = genreDaoJdbc.updateObject(new Genre(1L, "UpdatedName")); + Genre genre2 = genreDaoJdbc.getById(1L); + + assertAll( + "genre", + () -> assertEquals(1, count), + () -> assertEquals("Genre1", genre1.getName()), + () -> assertEquals("UpdatedName", genre2.getName()) ); } } \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java index b05b6fe..9fc482c 100644 --- a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java +++ b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java @@ -11,7 +11,9 @@ import java.text.SimpleDateFormat; import java.util.Date; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; /** * Created by IntelliJ IDEA. @@ -30,13 +32,16 @@ void getAddRecordDateString() { Book book = getNewBook(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - assertAll("book", - () -> assertNotNull(book), - () -> assertEquals(dateFormat.format(new Date()), book.getAddRecordDateString()) + assertAll( + "book", + () -> assertNotNull(book), + () -> assertEquals(dateFormat.format(new Date()), book.getAddRecordDateString()) ); } private Book getNewBook() { - return new Book(1, new Date(), "Test_Book", 2, 3, "Test_Comment"); + Author author = new Author(1L, "TestSurname", "TestFirstName", "TestSecondName"); + Genre genre = new Genre("Test4"); + return new Book(1L, new Date(), "Test_Book", author, genre, "Test_Comment"); } } \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java index 23b4286..52f8606 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -4,8 +4,9 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; @@ -34,30 +35,22 @@ @SpringBootTest(classes = AppTestConfig.class) class AuthorManageSeviceImplTest { - private AuthorManageService authorManageService; - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - AuthorDaoJdbc authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); - authorManageService = new AuthorManageServiceImpl(authorDaoJdbc); - } + @Autowired + private AuthorManageService authorManageService; @Test void getAuthorById() { - Author author = authorManageService.getAuthorById(1); - - assertAll("author", - () -> assertNotNull(author), - () -> assertEquals(1, author.getId()), - () -> assertEquals("Surname1", author.getSurname()), - () -> assertEquals("FirstName1", author.getFirstName()), - () -> assertEquals("SecondName1", author.getSecondName()) + Author author = authorManageService.getAuthorById(1L); + + assertAll( + "author", + () -> assertNotNull(author), + () -> assertEquals(1L, author.getId()), + () -> assertEquals("Surname1", author.getSurname()), + () -> assertEquals("FirstName1", author.getFirstName()), + () -> assertEquals("SecondName1", author.getSecondName()) ); } @@ -65,54 +58,52 @@ void getAuthorById() { void getAuthors() { List authors = authorManageService.getAuthors(); - assertAll("authors", - () -> assertNotNull(authors), - () -> assertEquals(3, authors.size()), - () -> assertEquals("Surname1", authors.get(0).getSurname()), - () -> assertEquals("Surname2", authors.get(1).getSurname()), - () -> assertEquals("Surname3", authors.get(2).getSurname()) + assertAll( + "authors", + () -> assertNotNull(authors), + () -> assertEquals(3, authors.size()), + () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname2", authors.get(1).getSurname()), + () -> assertEquals("Surname3", authors.get(2).getSurname()) ); } @Test void addAuthor() { int count = authorManageService.addAuthor("TestSurname", "TestFirstName", "TestSecondName"); - Author author_selected = authorManageService.getAuthorById(4); - - assertAll("author", - () -> assertNotNull(author_selected), - () -> assertEquals(1, count), - () -> assertEquals(4, author_selected.getId()), - () -> assertEquals("TestSurname", author_selected.getSurname()), - () -> assertEquals("TestFirstName", author_selected.getFirstName()), - () -> assertEquals("TestSecondName", author_selected.getSecondName()) + Author author_selected = authorManageService.getAuthorById(4L); + + assertAll( + "author", + () -> assertNotNull(author_selected), + () -> assertEquals(1, count), + () -> assertEquals(4L, author_selected.getId()), + () -> assertEquals("TestSurname", author_selected.getSurname()), + () -> assertEquals("TestFirstName", author_selected.getFirstName()), + () -> assertEquals("TestSecondName", author_selected.getSecondName()) ); } @Test void updateAuthor() { - Author author1 = authorManageService.getAuthorById(1); - int count = authorManageService.updateAuthor(1,"TestSurname", "TestFirstName", "TestSecondName"); - Author author2 = authorManageService.getAuthorById(1); - - assertAll("author", - () -> assertEquals(1, count), - () -> assertEquals("Surname1", author1.getSurname()), - () -> assertEquals("FirstName1", author1.getFirstName()), - () -> assertEquals("SecondName1", author1.getSecondName()), - () -> assertEquals("TestSurname", author2.getSurname()), - () -> assertEquals("TestFirstName", author2.getFirstName()), - () -> assertEquals("TestSecondName", author2.getSecondName()) + Author author1 = authorManageService.getAuthorById(1L); + int count = authorManageService.updateAuthor(1L, "TestSurname", "TestFirstName", "TestSecondName"); + Author author2 = authorManageService.getAuthorById(1L); + + assertAll( + "author", + () -> assertEquals(1, count), + () -> assertEquals("Surname1", author1.getSurname()), + () -> assertEquals("FirstName1", author1.getFirstName()), + () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("TestSurname", author2.getSurname()), + () -> assertEquals("TestFirstName", author2.getFirstName()), + () -> assertEquals("TestSecondName", author2.getSecondName()) ); } @Test void deleteAuthor() { - int count = authorManageService.deleteAuthor(1); - - assertAll("author", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { authorManageService.getAuthorById(1); }) - ); + assertThrows(DataIntegrityViolationException.class, () -> { authorManageService.deleteAuthor(1L); }); } } diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index 2b9928c..a568230 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -19,7 +20,11 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * Created by IntelliJ IDEA. @@ -33,37 +38,24 @@ @SpringBootTest(classes = AppTestConfig.class) class BookManageSeviceImplTest { + @Autowired private BookManageSevice booksManageSevice; - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - - AuthorDaoJdbc authorDaoJdbc = new AuthorDaoJdbc(new JdbcTemplate(db)); - BookDaoJdbc bookDaoJdbc = new BookDaoJdbc(new JdbcTemplate(db)); - GenreDaoJdbc genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); - - booksManageSevice = new BookManageSeviceImpl(authorDaoJdbc, bookDaoJdbc, genreDaoJdbc); - } - @Test void getBookById() { - Book book = booksManageSevice.getBookById(1); - - assertAll("book", - () -> assertNotNull(book), - () -> assertNull(book.getAuthor()), - () -> assertNull(book.getGenre()), - () -> assertEquals(1, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), - () -> assertEquals("book_1", book.getCaption()), - () -> assertEquals(1, book.getAuthorId()), - () -> assertEquals(1, book.getGenreId()), - () -> assertEquals("comment", book.getComment()) + Book book = booksManageSevice.getBookById(1L); + + assertAll( + "book", + () -> assertNotNull(book), + () -> assertNull(book.getAuthor()), + () -> assertNull(book.getGenre()), + () -> assertEquals(1L, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthor().getId()), + () -> assertEquals(1, book.getGenre().getId()), + () -> assertEquals("comment", book.getComment()) ); } @@ -71,16 +63,17 @@ void getBookById() { void getFullBookById() { Book book = booksManageSevice.getFullBookById(1); - assertAll("book", - () -> assertNotNull(book), - () -> assertNotNull(book.getAuthor()), - () -> assertNotNull(book.getGenre()), - () -> assertEquals(1, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), - () -> assertEquals("book_1", book.getCaption()), - () -> assertEquals(1, book.getAuthorId()), - () -> assertEquals(1, book.getGenreId()), - () -> assertEquals("comment", book.getComment()) + assertAll( + "book", + () -> assertNotNull(book), + () -> assertNotNull(book.getAuthor()), + () -> assertNotNull(book.getGenre()), + () -> assertEquals(1L, book.getId()), + () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("book_1", book.getCaption()), + () -> assertEquals(1, book.getAuthor().getId()), + () -> assertEquals(1, book.getGenre().getId()), + () -> assertEquals("comment", book.getComment()) ); } @@ -88,53 +81,57 @@ void getFullBookById() { void getBooks() { List books = booksManageSevice.getBooks(); - assertAll("books", - () -> assertNotNull(books), - () -> assertEquals(3, books.size()), - () -> assertEquals("book_1", books.get(0).getCaption()), - () -> assertEquals("book_2", books.get(1).getCaption()), - () -> assertEquals("book_3", books.get(2).getCaption()) + assertAll( + "books", + () -> assertNotNull(books), + () -> assertEquals(3, books.size()), + () -> assertEquals("book_1", books.get(0).getCaption()), + () -> assertEquals("book_2", books.get(1).getCaption()), + () -> assertEquals("book_3", books.get(2).getCaption()) ); } @Test void addBook() { - int count = booksManageSevice.addBook("Test_Book",2,3,"Test_Comment"); - Book book = booksManageSevice.getBookById(4); - - assertAll("book", - () -> assertNotNull(book), - () -> assertEquals(1, count), - () -> assertEquals(4, book.getId()), - () -> assertEquals("Test_Book", book.getCaption()), - () -> assertEquals(2, book.getAuthorId()), - () -> assertEquals(3, book.getGenreId()), - () -> assertEquals("Test_Comment", book.getComment()) + int count = booksManageSevice.addBook("Test_Book", 2, 3, "Test_Comment"); + Book book = booksManageSevice.getBookById(4L); + + assertAll( + "book", + () -> assertNotNull(book), + () -> assertEquals(1, count), + () -> assertEquals(4L, book.getId()), + () -> assertEquals("Test_Book", book.getCaption()), + () -> assertEquals(2, book.getAuthor().getId()), + () -> assertEquals(3, book.getGenre().getId()), + () -> assertEquals("Test_Comment", book.getComment()) ); } @Test void updateBook() { - Book book1 = booksManageSevice.getBookById(1); - int count = booksManageSevice.updateBook(1, "Test_Book", 2, 3, "Test_Comment"); - Book book2 = booksManageSevice.getBookById(1); - - assertAll("book", - () -> assertEquals(1, count), - () -> assertEquals("book_1", book1.getCaption()), - () -> assertEquals("comment", book1.getComment()), - () -> assertEquals("Test_Book", book2.getCaption()), - () -> assertEquals("Test_Comment", book2.getComment()) + Book book1 = booksManageSevice.getBookById(1L); + int count = booksManageSevice.updateBook(1L, "Test_Book", 2, 3, "Test_Comment"); + Book book2 = booksManageSevice.getBookById(1L); + + assertAll( + "book", + () -> assertEquals(1, count), + () -> assertEquals("book_1", book1.getCaption()), + () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("Test_Book", book2.getCaption()), + () -> assertEquals("Test_Comment", book2.getComment()) ); } @Test void deleteBook() { - int count = booksManageSevice.deleteBook(1); + int count = booksManageSevice.deleteBook(1L); - assertAll("book", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getBookById(1); }) + assertAll( + "book", + () -> assertEquals(1, count), + () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getBookById(1L); }) ); } diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java index d8b48ab..7fe9582 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -4,8 +4,9 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; @@ -34,28 +35,18 @@ @SpringBootTest(classes = AppTestConfig.class) class GenreManageSeviceImplTest { + @Autowired private GenreManageService genreManageService; - @BeforeEach - public void setup() { - EmbeddedDatabase db = new EmbeddedDatabaseBuilder() - .setType(EmbeddedDatabaseType.H2) - .addScript("test_schema.sql") - .addScript("test_data.sql") - .build(); - - GenreDaoJdbc genreDaoJdbc = new GenreDaoJdbc(new JdbcTemplate(db)); - genreManageService = new GenreManageServiceImpl(genreDaoJdbc); - } - @Test void getGenreById() { - Genre genre = genreManageService.getGenreById(1); + Genre genre = genreManageService.getGenreById(1L); - assertAll("genre", - () -> assertNotNull(genre), - () -> assertEquals(1, genre.getId()), - () -> assertEquals("Genre1", genre.getName()) + assertAll( + "genre", + () -> assertNotNull(genre), + () -> assertEquals(1L, genre.getId()), + () -> assertEquals("Genre1", genre.getName()) ); } @@ -63,48 +54,46 @@ void getGenreById() { void getGenres() { List genres = genreManageService.getGenres(); - assertAll("genres", - () -> assertNotNull(genres), - () -> assertEquals(3, genres.size()), - () -> assertEquals("Genre1", genres.get(0).getName()), - () -> assertEquals("Genre2", genres.get(1).getName()), - () -> assertEquals("Genre3", genres.get(2).getName()) + assertAll( + "genres", + () -> assertNotNull(genres), + () -> assertEquals(3, genres.size()), + () -> assertEquals("Genre1", genres.get(0).getName()), + () -> assertEquals("Genre2", genres.get(1).getName()), + () -> assertEquals("Genre3", genres.get(2).getName()) ); } @Test void addGenre() { int count = genreManageService.addGenre("Test4"); - Genre genre = genreManageService.getGenreById(4); - - assertAll("genre", - () -> assertNotNull(genre), - () -> assertEquals(1, count), - () -> assertEquals(4, genre.getId()), - () -> assertEquals("Test4", genre.getName()) + Genre genre = genreManageService.getGenreById(4L); + + assertAll( + "genre", + () -> assertNotNull(genre), + () -> assertEquals(1, count), + () -> assertEquals(4L, genre.getId()), + () -> assertEquals("Test4", genre.getName()) ); } @Test void updateGenre() { - Genre genre1 = genreManageService.getGenreById(1); - int count = genreManageService.updateGenre(1, "UpdatedName"); - Genre genre2 = genreManageService.getGenreById(1); - - assertAll("genre", - () -> assertEquals(1, count), - () -> assertEquals("Genre1", genre1.getName()), - () -> assertEquals("UpdatedName", genre2.getName()) + Genre genre1 = genreManageService.getGenreById(1L); + int count = genreManageService.updateGenre(1L, "UpdatedName"); + Genre genre2 = genreManageService.getGenreById(1L); + + assertAll( + "genre", + () -> assertEquals(1, count), + () -> assertEquals("Genre1", genre1.getName()), + () -> assertEquals("UpdatedName", genre2.getName()) ); } @Test void deleteGenre() { - int count = genreManageService.deleteGenre(1); - - assertAll("genre", - () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { genreManageService.getGenreById(1); }) - ); + assertThrows(DataIntegrityViolationException.class, () -> { genreManageService.deleteGenre(1L); }); } } diff --git a/src/test/resources/test_data.sql b/src/test/resources/test_data.sql deleted file mode 100644 index 02531b1..0000000 --- a/src/test/resources/test_data.sql +++ /dev/null @@ -1,27 +0,0 @@ -insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) -values ('Surname1', 'FirstName1', 'SecondName1'); - -insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) -values ('Surname2', 'FirstName2', 'SecondName2'); - -insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) -values ('Surname3', 'FirstName3', 'SecondName3'); - --------------------------- - -insert into GENRE (NAME) values ('Genre1'); -insert into GENRE (NAME) values ('Genre2'); -insert into GENRE (NAME) values ('Genre3'); - --------------------------- - -insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); - -insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); - -insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) - values (to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); - --------------------------- diff --git a/src/test/resources/test_schema.sql b/src/test/resources/test_schema.sql deleted file mode 100644 index d0b2b33..0000000 --- a/src/test/resources/test_schema.sql +++ /dev/null @@ -1,23 +0,0 @@ -DROP TABLE IF EXISTS BOOK; -CREATE TABLE BOOK( - ID INT AUTO_INCREMENT PRIMARY KEY, - ADD_RECORD_DATE DATE, - CAPTION VARCHAR(255) not null, - AUTHOR_ID INT not null, - GENRE_ID INT not null, - COMMENT VARCHAR(255) -); - -DROP TABLE IF EXISTS AUTHOR; -CREATE TABLE AUTHOR( - ID INT AUTO_INCREMENT PRIMARY KEY, - SURNAME VARCHAR(100) not null, - FIRST_NAME VARCHAR(100) not null, - SECOND_NAME VARCHAR(100) -); - -DROP TABLE IF EXISTS GENRE; -CREATE TABLE GENRE( - ID INT AUTO_INCREMENT PRIMARY KEY, - NAME VARCHAR(100) not null -); \ No newline at end of file From b019b1b177560cbe33a9227a6a389598316a9bdd Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Wed, 5 Jun 2019 16:19:41 +0300 Subject: [PATCH 16/30] =?UTF-8?q?-=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B.=20-=20=D0=98?= =?UTF-8?q?=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20@JdbcTest.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 +++- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 3 +- .../java/ru/otus/mkulikov/app/model/Book.java | 21 +------ .../ru/otus/mkulikov/app/utils/DateUtil.java | 22 +++++++ src/main/resources/application.yml | 12 ++-- .../java/ru/otus/mkulikov/AppTestConfig.java | 59 ------------------- .../mkulikov/app/dao/AuthorDaoJdbcTest.java | 17 ++---- .../mkulikov/app/dao/BookDaoJdbcTest.java | 23 +++----- .../mkulikov/app/dao/GenreDaoJdbcTest.java | 14 ++--- .../ru/otus/mkulikov/app/model/BookTest.java | 7 +-- .../service/AuthorManageSeviceImplTest.java | 15 ++--- .../app/service/BookManageSeviceImplTest.java | 28 ++++----- .../service/GenreManageSeviceImplTest.java | 13 ++-- 13 files changed, 80 insertions(+), 167 deletions(-) create mode 100644 src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java delete mode 100644 src/test/java/ru/otus/mkulikov/AppTestConfig.java diff --git a/README.md b/README.md index 943beb2..d6228fc 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,15 @@ - Опционально использовать настоящую реляционную БД, но можно использовать H2. - Предусмотреть таблицы авторов, книг и жанров. - Интерфейс на Spring Shell. -- Покрыть тестами, насколько это возможно. \ No newline at end of file +- Покрыть тестами, насколько это возможно. + +### 19-05-31 Доработки: +- JdbcOperations заменен на NamedParameterJdbcOperations. +- Изменены запросы книг. +- Добавление внешних ключей для таблицы книг. +- Изменение сущности Book. +- Изменение типа id. + +### 19-06-05 Доработки: +- Изменены тесты. +- Использование @JdbcTest. diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java index 2ab1c2a..cd3f532 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java @@ -1,7 +1,6 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.stereotype.Repository; @@ -35,7 +34,7 @@ public class BookDaoJdbc implements BookDao { + "from Book b " + "inner join Author a on a.id = b.author_id " + "inner join Genre g on g.id = b.genre_id " - + "where id = :id "; + + "where b.id = :id "; private final String BOOK_SELECT_ALL = "select b.*, a.surname, a.first_name, a.second_name, g.name " diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index a70181d..0127892 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -47,23 +47,6 @@ public Book(String caption, Author author, Genre genre, String comment) { this.comment = comment; } - public String getAddRecordDateString() { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - return addRecordDate != null ? dateFormat.format(addRecordDate) : null; - } - - public String getAuthorString() { - return (author != null) - ? ", author='" + author.toFormatedString() + '\'' - : ""; - } - - public String getGenreString() { - return (genre != null) - ? ", genre='" + genre.getName() + '\'' - : ""; - } - @Override public String toString() { return "Book{" + @@ -71,8 +54,8 @@ public String toString() { ", addRecordDate=" + addRecordDate + ", caption='" + caption + '\'' + ", comment='" + comment + '\'' + - getAuthorString() + - getGenreString() + + ", author=" + author + + ", genre=" + genre + "}\n"; } } diff --git a/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java b/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java new file mode 100644 index 0000000..2507a0a --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java @@ -0,0 +1,22 @@ +package ru.otus.mkulikov.app.utils; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 05.06.2019 + * Time: 11:33 + */ + +public class DateUtil { + + private final static String DATE_FORMAT = "yyyy-MM-dd"; + + public static String dateToString(Date date) { + DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); + return date != null ? dateFormat.format(date) : null; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4252b7d..3436172 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,11 +1,7 @@ spring: - datasource: - data: "classpath:data.sql" - schema: "classpath:schema.sql" - username: "SA" - password: "" - driver-class-name: "org.h2.Driver" - url: "jdbc:h2:mem:test" - banner: location: "classpath:banner.txt" + + + + diff --git a/src/test/java/ru/otus/mkulikov/AppTestConfig.java b/src/test/java/ru/otus/mkulikov/AppTestConfig.java deleted file mode 100644 index 376bdc6..0000000 --- a/src/test/java/ru/otus/mkulikov/AppTestConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -package ru.otus.mkulikov; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.PropertySource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import ru.otus.mkulikov.app.dao.BookDaoJdbc; - -import javax.sql.DataSource; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 28.05.2019 - * Time: 9:47 - */ - -@SpringBootConfiguration -@ComponentScan("ru.otus.mkulikov.app") -@PropertySource({"classpath:application.yml"}) -@EnableConfigurationProperties -public class AppTestConfig { - - @Bean - public NamedParameterJdbcOperations getNamedParameterJdbcOperations(DataSource dataSource) { - return new NamedParameterJdbcTemplate(dataSource); - } - - //@Bean - //public DataSource getDataSource() { - // DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); - // dataSourceBuilder.driverClassName("org.h2.Driver"); - // dataSourceBuilder.url("jdbc:h2:mem:test"); - // dataSourceBuilder.username("SA"); - // dataSourceBuilder.password(""); - // return dataSourceBuilder.build(); - //} - - @Bean - @Primary - @ConfigurationProperties("application.yml") - public DataSourceProperties getDatasourceProperties() { - return new DataSourceProperties(); - } - - @Bean - //@ConfigurationProperties("datasource.oracle") - public DataSource getDatasource() { - return getDatasourceProperties().initializeDataSourceBuilder() - .build(); - } -} diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java index 145835b..ba4bed6 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java @@ -1,21 +1,13 @@ package ru.otus.mkulikov.app.dao; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; import ru.otus.mkulikov.app.model.Author; import java.util.List; @@ -34,11 +26,12 @@ @DisplayName("Класс AuthorDaoJdbc") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +@JdbcTest +@Import(AuthorDaoJdbc.class) class AuthorDaoJdbcTest { @Autowired - private AuthorDaoJdbc authorDaoJdbc; + private AuthorDao authorDaoJdbc; @Test void getById() { diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java index d48684b..908c10a 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java @@ -1,24 +1,16 @@ package ru.otus.mkulikov.app.dao; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Genre; +import ru.otus.mkulikov.app.utils.DateUtil; import java.util.Date; import java.util.List; @@ -37,11 +29,12 @@ @DisplayName("Класс BookDaoJdbc") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +@JdbcTest +@Import(BookDaoJdbc.class) class BookDaoJdbcTest { @Autowired - private BookDaoJdbc bookDaoJdbc; + private BookDao bookDaoJdbc; @Test void getById() { @@ -51,7 +44,7 @@ void getById() { "book", () -> assertNotNull(book), () -> assertEquals(1L, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("2019-01-01", DateUtil.dateToString(book.getAddRecordDate())), () -> assertEquals("book_1", book.getCaption()), () -> assertEquals(1, book.getAuthor().getId()), () -> assertEquals(1, book.getGenre().getId()), @@ -97,7 +90,7 @@ void deleteObject() { assertAll( "book", () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { bookDaoJdbc.getById(1L); }) + () -> assertThrows(IndexOutOfBoundsException.class, () -> { bookDaoJdbc.getById(1L); }) ); } diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java index 9dc952c..47791a4 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java @@ -1,18 +1,13 @@ package ru.otus.mkulikov.app.dao; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -31,11 +26,12 @@ @DisplayName("Класс GenreDaoJdbc") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +@JdbcTest +@Import(GenreDaoJdbc.class) class GenreDaoJdbcTest { @Autowired - private GenreDaoJdbc genreDaoJdbc; + private GenreDao genreDaoJdbc; @Test void getById() { diff --git a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java index 9fc482c..293ef8c 100644 --- a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java +++ b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java @@ -3,9 +3,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; +import ru.otus.mkulikov.app.utils.DateUtil; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -24,7 +23,7 @@ @DisplayName("Класс Book") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +//@SpringBootTest(classes = AppTestConfig.class) class BookTest { @Test @@ -35,7 +34,7 @@ void getAddRecordDateString() { assertAll( "book", () -> assertNotNull(book), - () -> assertEquals(dateFormat.format(new Date()), book.getAddRecordDateString()) + () -> assertEquals(dateFormat.format(new Date()), DateUtil.dateToString(book.getAddRecordDate())) ); } diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java index 52f8606..93ca519 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -1,19 +1,13 @@ package ru.otus.mkulikov.app.service; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; -import ru.otus.mkulikov.app.dao.AuthorDaoJdbc; import ru.otus.mkulikov.app.model.Author; import java.util.List; @@ -32,11 +26,10 @@ @DisplayName("Класс AuthorManageSevice") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +@JdbcTest +@ComponentScan("ru.otus.mkulikov.app") class AuthorManageSeviceImplTest { - - @Autowired private AuthorManageService authorManageService; diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index a568230..e7db9bc 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -1,29 +1,20 @@ package ru.otus.mkulikov.app.service; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; -import ru.otus.mkulikov.app.dao.AuthorDaoJdbc; -import ru.otus.mkulikov.app.dao.BookDaoJdbc; -import ru.otus.mkulikov.app.dao.GenreDaoJdbc; import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.utils.DateUtil; import java.util.List; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; /** @@ -35,7 +26,8 @@ @DisplayName("Класс BookManageSevice") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +@JdbcTest +@ComponentScan("ru.otus.mkulikov.app") class BookManageSeviceImplTest { @Autowired @@ -48,10 +40,10 @@ void getBookById() { assertAll( "book", () -> assertNotNull(book), - () -> assertNull(book.getAuthor()), - () -> assertNull(book.getGenre()), + () -> assertNotNull(book.getAuthor()), + () -> assertNotNull(book.getGenre()), () -> assertEquals(1L, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("2019-01-01", DateUtil.dateToString(book.getAddRecordDate())), () -> assertEquals("book_1", book.getCaption()), () -> assertEquals(1, book.getAuthor().getId()), () -> assertEquals(1, book.getGenre().getId()), @@ -69,7 +61,7 @@ void getFullBookById() { () -> assertNotNull(book.getAuthor()), () -> assertNotNull(book.getGenre()), () -> assertEquals(1L, book.getId()), - () -> assertEquals("2019-01-01", book.getAddRecordDateString()), + () -> assertEquals("2019-01-01", DateUtil.dateToString(book.getAddRecordDate())), () -> assertEquals("book_1", book.getCaption()), () -> assertEquals(1, book.getAuthor().getId()), () -> assertEquals(1, book.getGenre().getId()), @@ -131,7 +123,7 @@ void deleteBook() { assertAll( "book", () -> assertEquals(1, count), - () -> assertThrows(EmptyResultDataAccessException.class, () -> { booksManageSevice.getBookById(1L); }) + () -> assertThrows(IndexOutOfBoundsException.class, () -> { booksManageSevice.getBookById(1L); }) ); } diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java index 7fe9582..57a833b 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -1,19 +1,13 @@ package ru.otus.mkulikov.app.service; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.test.context.junit4.SpringRunner; -import ru.otus.mkulikov.AppTestConfig; -import ru.otus.mkulikov.app.dao.GenreDaoJdbc; import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -32,7 +26,8 @@ @DisplayName("Класс GenreManageSevice") @RunWith(SpringRunner.class) -@SpringBootTest(classes = AppTestConfig.class) +@JdbcTest +@ComponentScan("ru.otus.mkulikov.app") class GenreManageSeviceImplTest { @Autowired From 45999774aba7d9e16b357c81822f73a0d37ce677 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 6 Jun 2019 09:47:00 +0300 Subject: [PATCH 17/30] =?UTF-8?q?=D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index d6228fc..aff31e5 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,7 @@ # OtusSpringHW-Library -Домашнее задание #5: -- Создать приложение хранящее информацию о книгах в библиотеке. -- Использовать Spring JDBC и реляционную базу. -- Опционально использовать настоящую реляционную БД, но можно использовать H2. -- Предусмотреть таблицы авторов, книг и жанров. -- Интерфейс на Spring Shell. -- Покрыть тестами, насколько это возможно. - -### 19-05-31 Доработки: -- JdbcOperations заменен на NamedParameterJdbcOperations. -- Изменены запросы книг. -- Добавление внешних ключей для таблицы книг. -- Изменение сущности Book. -- Изменение типа id. - -### 19-06-05 Доработки: -- Изменены тесты. -- Использование @JdbcTest. +Домашнее задание #6: +- Переписать приложение для хранения книг на ORM. +- Использовать JPA, Hibernate только в качестве JPA-провайдера. +- Добавить комментарии к книгам, и высокоуровневые сервисы, оставляющие комментарии к книгам. +- Покрыть DAO тестами используя H2 базу данных и соответствующий H2 Hibernate-диалект. From 0ed6680820e7bfc8554cf57bedb799417f6b79ea Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 13 Jun 2019 17:30:08 +0300 Subject: [PATCH 18/30] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D0=B1=D0=B4=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20jpa.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 13 ++-- .../otus/mkulikov/app/dao/AuthorDaoJdbc.java | 61 ++++++++----------- .../otus/mkulikov/app/dao/GenreDaoJdbc.java | 54 +++++++--------- .../ru/otus/mkulikov/app/model/Author.java | 36 +++++++++-- .../java/ru/otus/mkulikov/app/model/Book.java | 35 ++++++++++- .../ru/otus/mkulikov/app/model/Genre.java | 30 ++++++++- src/main/resources/application.yml | 4 +- src/main/resources/data.sql | 30 ++++----- src/main/resources/schema.sql | 13 ++-- .../mkulikov/app/dao/AuthorDaoJdbcTest.java | 10 ++- 10 files changed, 181 insertions(+), 105 deletions(-) diff --git a/pom.xml b/pom.xml index b77b838..f1fbb76 100644 --- a/pom.xml +++ b/pom.xml @@ -84,10 +84,10 @@ spring-boot-starter - - org.springframework.boot - spring-boot-starter-jdbc - + + + + org.springframework.boot @@ -101,6 +101,11 @@ true + + org.springframework.boot + spring-boot-starter-data-jpa + + org.springframework.shell spring-shell-starter diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java index 8f23571..b3d9409 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java @@ -1,17 +1,14 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import ru.otus.mkulikov.app.model.Author; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + import java.util.List; -import java.util.Map; /** * Created by IntelliJ IDEA. @@ -22,58 +19,48 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository +@Transactional @RequiredArgsConstructor public class AuthorDaoJdbc implements AuthorDao { - private final NamedParameterJdbcOperations namedParameterJdbcOperations; + @PersistenceContext + private EntityManager em; @Override public Author getById(long id) { - Map paramMap = new HashMap(); - paramMap.put("id", id); + List list = em.createQuery("select a from Author a where a.id = :id", Author.class) + .setParameter("id", id) + .getResultList(); - return namedParameterJdbcOperations.queryForObject("select * from Author where id = :id ", paramMap, new AuthorMapper()); + return (list != null && !list.isEmpty()) ? list.get(0) : null; } @Override public List getAllObjects() { - return namedParameterJdbcOperations.query("select * from Author order by id", new AuthorMapper()); + return em.createQuery("select a from Author a order by a.id", Author.class) + .getResultList(); } @Override public int addObject(Author author) { - return namedParameterJdbcOperations.update( - "insert into Author (surname, first_name, second_name) values (:surname, :firstName, :secondName)", - new BeanPropertySqlParameterSource(author) - ); + em.persist(author); + return 1; } @Override public int deleteObject(long id) { - Map paramMap = new HashMap(); - paramMap.put("id", id); - - return namedParameterJdbcOperations.update("delete from Author where id = :id ", paramMap); + return em.createQuery("delete from Author a where a.id = :id ") + .setParameter("id", id) + .executeUpdate(); } @Override public int updateObject(Author author) { - return namedParameterJdbcOperations.update( - "update Author set surname = :surname, first_name = :firstName, second_name = :secondName where id = :id ", - new BeanPropertySqlParameterSource(author) - ); - } - - public static class AuthorMapper implements RowMapper { - - @Override - public Author mapRow(ResultSet resultSet, int i) throws SQLException { - int id = resultSet.getInt("ID"); - String surname = resultSet.getString("SURNAME"); - String firstName = resultSet.getString("FIRST_NAME"); - String secondName = resultSet.getString("SECOND_NAME"); - - return new Author(id, surname, firstName, secondName); - } + return em.createQuery("update Author a set a.surname = :surname, a.first_name = :firstName, a.second_name = :secondName where a.id = :id ") + .setParameter("surname", author.getSurname()) + .setParameter("firstName", author.getFirstName()) + .setParameter("secondName", author.getSecondName()) + .setParameter("id", author.getId()) + .executeUpdate(); } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java index 627c1e5..0ace048 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java @@ -1,17 +1,13 @@ package ru.otus.mkulikov.app.dao; import lombok.RequiredArgsConstructor; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import ru.otus.mkulikov.app.model.Genre; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import java.util.List; -import java.util.Map; /** * Created by IntelliJ IDEA. @@ -22,54 +18,46 @@ @SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) @Repository +@Transactional @RequiredArgsConstructor public class GenreDaoJdbc implements GenreDao { - private final NamedParameterJdbcOperations namedParameterJdbcOperations; + @PersistenceContext + private EntityManager em; @Override public Genre getById(long id) { - Map paramMap = new HashMap(); - paramMap.put("id", id); + List list = em.createQuery("select g from Genre g where g.id = :id ", Genre.class) + .setParameter("id", id) + .getResultList(); - return namedParameterJdbcOperations.queryForObject("select * from Genre where id = :id ", paramMap, new GenreMapper()); + return (list != null && !list.isEmpty()) ? list.get(0) : null; } @Override public List getAllObjects() { - return namedParameterJdbcOperations.query("select * from Genre order by id", new GenreMapper()); + return em.createQuery("select g from Genre g order by g.id", Genre.class) + .getResultList(); } @Override public int addObject(Genre genre) { - return namedParameterJdbcOperations.update( - "insert into Genre (name) values (:name)", - new BeanPropertySqlParameterSource(genre)); + em.persist(genre); + return 1; } @Override public int deleteObject(long id) { - Map paramMap = new HashMap(); - paramMap.put("id", id); - - return namedParameterJdbcOperations.update("delete from Genre where id = :id ", paramMap); + return em.createQuery("delete from Genre g where g.id = :id ") + .setParameter("id", id) + .executeUpdate(); } @Override public int updateObject(Genre genre) { - return namedParameterJdbcOperations.update( - "update Genre set name = :name where id = :id ", - new BeanPropertySqlParameterSource(genre)); - } - - public static class GenreMapper implements RowMapper { - - @Override - public Genre mapRow(ResultSet resultSet, int i) throws SQLException { - int id = resultSet.getInt("ID"); - String name = resultSet.getString("NAME"); - - return new Genre(id, name); - } + return em.createQuery("update Genre g set g.name = :name where g.id = :id ") + .setParameter("name", genre.getName()) + .setParameter("id", genre.getId()) + .executeUpdate(); } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index d3bd662..a8de914 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -2,6 +2,18 @@ import lombok.Data; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import java.math.BigInteger; + /** * Created by IntelliJ IDEA. * Developer: Maksim Kulikov @@ -10,12 +22,28 @@ */ @Data +@Entity +@Table(name = "AUTHOR") public class Author { - private final long id; - private final String surname; - private final String firstName; - private final String secondName; + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sq_author") + @SequenceGenerator(name = "sq_author", sequenceName = "sq_author", allocationSize = 1) + @Column(name = "ID") + private long id; + @Column(name = "SURNAME") + private String surname; + @Column(name = "FIRST_NAME") + private String firstName; + @Column(name = "SECOND_NAME") + private String secondName; + // + //@OneToOne(mappedBy = "author") + //@JoinTable(name="BOOK", joinColumns=@JoinColumn(name="AUTHOR_ID")) + //private Book book; + + public Author() { + } public Author(long id, String surname, String firstName, String secondName) { this.id = id; diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 0127892..b509adb 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -2,8 +2,18 @@ import lombok.Data; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import java.util.Date; /** @@ -14,14 +24,33 @@ */ @Data +@Entity +@Table(name = "BOOK") public class Book { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sq_book") + @SequenceGenerator(name = "sq_book", sequenceName = "sq_book", allocationSize = 1) + @Column(name = "ID") private long id; + @Column(name = "ADD_RECORD_DATE") private Date addRecordDate; + @Column(name = "CAPTION") private String caption; + @Column(name = "COMMENT") + private String comment; + + @OneToOne//(mappedBy = "book") + //@JoinTable(name="AUTHOR", joinColumns=@JoinColumn(name="AUTHOR_ID")) private Author author; + + //@JoinTable(name="GENRE", joinColumns=@JoinColumn(name="GENRE_ID")) + @OneToOne//(mappedBy = "book") private Genre genre; - private String comment; + + + public Book() { + } public Book(long id, Date addRecordDate, String caption, Author author, Genre genre, String comment) { this.id = id; diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 5dff2a6..2d5a5f2 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -2,6 +2,17 @@ import lombok.Data; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + /** * Created by IntelliJ IDEA. * Developer: Maksim Kulikov @@ -10,10 +21,25 @@ */ @Data +@Entity +@Table(name = "GENRE") public class Genre { - private final long id; - private final String name; + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sq_genre") + @SequenceGenerator(name = "sq_genre", sequenceName = "sq_genre", allocationSize = 1) + @Column(name = "ID") + private long id; + + @Column(name = "NAME") + private String name; + + //@OneToOne(mappedBy = "genre") + //private Book book; + + + public Genre() { + } public Genre(long id, String name) { this.id = id; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3436172..1534e00 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,6 +2,8 @@ spring: banner: location: "classpath:banner.txt" - + jpa: + hibernate: + ddl-auto: none diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 1372099..a0fbb68 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,27 +1,27 @@ -insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) -values ('Surname1', 'FirstName1', 'SecondName1'); +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (sq_author.nextval, 'Surname1', 'FirstName1', 'SecondName1'); -insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) -values ('Surname2', 'FirstName2', 'SecondName2'); +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (sq_author.nextval, 'Surname2', 'FirstName2', 'SecondName2'); -insert into AUTHOR (SURNAME, FIRST_NAME, SECOND_NAME) -values ('Surname3', 'FirstName3', 'SecondName3'); +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (sq_author.nextval, 'Surname3', 'FirstName3', 'SecondName3'); -------------------------- -insert into GENRE (NAME) values ('Genre1'); -insert into GENRE (NAME) values ('Genre2'); -insert into GENRE (NAME) values ('Genre3'); +insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre1'); +insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre2'); +insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre3'); -------------------------- -insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); -insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); -insert into BOOK (ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); -------------------------- diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index c18e8d2..538c6ab 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -3,26 +3,29 @@ DROP TABLE IF EXISTS AUTHOR; DROP TABLE IF EXISTS GENRE; CREATE TABLE AUTHOR( - ID NUMBER(22,0) AUTO_INCREMENT PRIMARY KEY, + ID NUMBER(22,0) PRIMARY KEY not null, SURNAME VARCHAR(100) not null, FIRST_NAME VARCHAR(100) not null, SECOND_NAME VARCHAR(100) ); CREATE TABLE GENRE( - ID NUMBER(22,0) AUTO_INCREMENT PRIMARY KEY, + ID NUMBER(22,0) PRIMARY KEY not null, NAME VARCHAR(100) not null ); CREATE TABLE BOOK( - ID NUMBER(22,0) AUTO_INCREMENT PRIMARY KEY, + ID NUMBER(22,0) PRIMARY KEY not null, ADD_RECORD_DATE DATE, CAPTION VARCHAR(255) not null, - AUTHOR_ID INT not null, - GENRE_ID INT not null, + AUTHOR_ID NUMBER(22,0) not null, + GENRE_ID NUMBER(22,0) not null, COMMENT VARCHAR(255), foreign key (AUTHOR_ID) references AUTHOR(ID), foreign key (GENRE_ID) references GENRE(ID) ); +CREATE SEQUENCE sq_author minvalue 1 start with 1 increment by 1; +CREATE SEQUENCE sq_genre minvalue 1 start with 1 increment by 1; +CREATE SEQUENCE sq_book minvalue 1 start with 1 increment by 1; diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java index ba4bed6..30a0e0f 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java @@ -5,11 +5,16 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; import ru.otus.mkulikov.app.model.Author; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import java.util.List; import static org.junit.jupiter.api.Assertions.assertAll; @@ -26,13 +31,16 @@ @DisplayName("Класс AuthorDaoJdbc") @RunWith(SpringRunner.class) -@JdbcTest @Import(AuthorDaoJdbc.class) +@DataJpaTest class AuthorDaoJdbcTest { @Autowired private AuthorDao authorDaoJdbc; + //@PersistenceContext + //private EntityManager manager; + @Test void getById() { Author author = authorDaoJdbc.getById(1L); From a9d5968040b8d097623b82a8beb8571349db302c Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 13 Jun 2019 18:05:33 +0300 Subject: [PATCH 19/30] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{AuthorDaoJdbc.java => AuthorDaoJpa.java} | 4 ++- .../{GenreDaoJdbc.java => GenreDaoJpa.java} | 4 ++- .../ru/otus/mkulikov/app/model/Author.java | 8 ------ .../java/ru/otus/mkulikov/app/model/Book.java | 11 ++------ .../ru/otus/mkulikov/app/model/Genre.java | 7 ----- .../mkulikov/app/dao/AuthorDaoJdbcTest.java | 28 +++++++------------ .../mkulikov/app/dao/GenreDaoJdbcTest.java | 20 ++++++------- 7 files changed, 28 insertions(+), 54 deletions(-) rename src/main/java/ru/otus/mkulikov/app/dao/{AuthorDaoJdbc.java => AuthorDaoJpa.java} (89%) rename src/main/java/ru/otus/mkulikov/app/dao/{GenreDaoJdbc.java => GenreDaoJpa.java} (88%) diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java similarity index 89% rename from src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java rename to src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java index b3d9409..04e3988 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java @@ -21,7 +21,7 @@ @Repository @Transactional @RequiredArgsConstructor -public class AuthorDaoJdbc implements AuthorDao { +public class AuthorDaoJpa implements AuthorDao { @PersistenceContext private EntityManager em; @@ -32,6 +32,8 @@ public Author getById(long id) { .setParameter("id", id) .getResultList(); + // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных + // не хочу ошибку, хочу null return (list != null && !list.isEmpty()) ? list.get(0) : null; } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java similarity index 88% rename from src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java rename to src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java index 0ace048..e7e52fb 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJdbc.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java @@ -20,7 +20,7 @@ @Repository @Transactional @RequiredArgsConstructor -public class GenreDaoJdbc implements GenreDao { +public class GenreDaoJpa implements GenreDao { @PersistenceContext private EntityManager em; @@ -31,6 +31,8 @@ public Genre getById(long id) { .setParameter("id", id) .getResultList(); + // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных + // не хочу ошибку, хочу null return (list != null && !list.isEmpty()) ? list.get(0) : null; } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index a8de914..c3bdcb4 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -7,12 +7,8 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; -import java.math.BigInteger; /** * Created by IntelliJ IDEA. @@ -37,10 +33,6 @@ public class Author { private String firstName; @Column(name = "SECOND_NAME") private String secondName; - // - //@OneToOne(mappedBy = "author") - //@JoinTable(name="BOOK", joinColumns=@JoinColumn(name="AUTHOR_ID")) - //private Book book; public Author() { } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index b509adb..ea3c49b 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -2,15 +2,11 @@ import lombok.Data; -import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; @@ -40,15 +36,12 @@ public class Book { @Column(name = "COMMENT") private String comment; - @OneToOne//(mappedBy = "book") - //@JoinTable(name="AUTHOR", joinColumns=@JoinColumn(name="AUTHOR_ID")) + @OneToOne private Author author; - //@JoinTable(name="GENRE", joinColumns=@JoinColumn(name="GENRE_ID")) - @OneToOne//(mappedBy = "book") + @OneToOne private Genre genre; - public Book() { } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 2d5a5f2..c89efa3 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -7,9 +7,6 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; @@ -34,10 +31,6 @@ public class Genre { @Column(name = "NAME") private String name; - //@OneToOne(mappedBy = "genre") - //private Book book; - - public Genre() { } diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java index 30a0e0f..5971ffe 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java @@ -4,17 +4,12 @@ import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.transaction.annotation.Transactional; import ru.otus.mkulikov.app.model.Author; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; import java.util.List; import static org.junit.jupiter.api.Assertions.assertAll; @@ -31,19 +26,16 @@ @DisplayName("Класс AuthorDaoJdbc") @RunWith(SpringRunner.class) -@Import(AuthorDaoJdbc.class) +@Import(AuthorDaoJpa.class) @DataJpaTest class AuthorDaoJdbcTest { @Autowired - private AuthorDao authorDaoJdbc; - - //@PersistenceContext - //private EntityManager manager; + private AuthorDao authorDaoJpa; @Test void getById() { - Author author = authorDaoJdbc.getById(1L); + Author author = authorDaoJpa.getById(1L); assertAll( "author", @@ -57,7 +49,7 @@ void getById() { @Test void getAllObjects() { - List authors = authorDaoJdbc.getAllObjects(); + List authors = authorDaoJpa.getAllObjects(); assertAll( "authors", @@ -72,8 +64,8 @@ void getAllObjects() { @Test void addObject() { Author author = new Author("TestSurname", "TestFirstName", "TestSecondName"); - int count = authorDaoJdbc.addObject(author); - Author author_selected = authorDaoJdbc.getById(4L); + int count = authorDaoJpa.addObject(author); + Author author_selected = authorDaoJpa.getById(4L); assertAll( "author", @@ -88,16 +80,16 @@ void addObject() { @Test void deleteObject() { - assertThrows(DataIntegrityViolationException.class, () -> { authorDaoJdbc.deleteObject(1L); }); + assertThrows(DataIntegrityViolationException.class, () -> { authorDaoJpa.deleteObject(1L); }); } @Test void updateObject() { - Author author1 = authorDaoJdbc.getById(1L); - int count = authorDaoJdbc.updateObject( + Author author1 = authorDaoJpa.getById(1L); + int count = authorDaoJpa.updateObject( new Author(1L, "TestSurname", "TestFirstName", "TestSecondName") ); - Author author2 = authorDaoJdbc.getById(1L); + Author author2 = authorDaoJpa.getById(1L); assertAll( "author", diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java index 47791a4..c73c2e1 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java @@ -27,15 +27,15 @@ @DisplayName("Класс GenreDaoJdbc") @RunWith(SpringRunner.class) @JdbcTest -@Import(GenreDaoJdbc.class) +@Import(GenreDaoJpa.class) class GenreDaoJdbcTest { @Autowired - private GenreDao genreDaoJdbc; + private GenreDao genreDaoJpa; @Test void getById() { - Genre genre = genreDaoJdbc.getById(1L); + Genre genre = genreDaoJpa.getById(1L); assertAll( "genre", @@ -47,7 +47,7 @@ void getById() { @Test void getAllObjects() { - List genres = genreDaoJdbc.getAllObjects(); + List genres = genreDaoJpa.getAllObjects(); assertAll( "genres", @@ -61,9 +61,9 @@ void getAllObjects() { @Test void addObject() { - int count = genreDaoJdbc.addObject(new Genre("Test4")); + int count = genreDaoJpa.addObject(new Genre("Test4")); - Genre genre = genreDaoJdbc.getById(4L); + Genre genre = genreDaoJpa.getById(4L); assertAll( "genre", @@ -76,14 +76,14 @@ void addObject() { @Test void deleteObject() { - assertThrows(DataIntegrityViolationException.class, () -> { genreDaoJdbc.deleteObject(1L); }); + assertThrows(DataIntegrityViolationException.class, () -> { genreDaoJpa.deleteObject(1L); }); } @Test void updateObject() { - Genre genre1 = genreDaoJdbc.getById(1L); - int count = genreDaoJdbc.updateObject(new Genre(1L, "UpdatedName")); - Genre genre2 = genreDaoJdbc.getById(1L); + Genre genre1 = genreDaoJpa.getById(1L); + int count = genreDaoJpa.updateObject(new Genre(1L, "UpdatedName")); + Genre genre2 = genreDaoJpa.getById(1L); assertAll( "genre", From b228def7bd2a4122d8977a0b36bd519b9156bc21 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Fri, 14 Jun 2019 00:39:44 +0300 Subject: [PATCH 20/30] =?UTF-8?q?-=20=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B1=D0=B4=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20jpa?= =?UTF-8?q?.=20-=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/mkulikov/app/dao/AuthorDaoJpa.java | 5 +- .../ru/otus/mkulikov/app/dao/BookDaoJdbc.java | 127 ------------------ .../ru/otus/mkulikov/app/dao/BookDaoJpa.java | 75 +++++++++++ .../ru/otus/mkulikov/app/dao/GenreDaoJpa.java | 5 +- .../ru/otus/mkulikov/app/model/Author.java | 10 +- .../java/ru/otus/mkulikov/app/model/Book.java | 14 +- .../ru/otus/mkulikov/app/model/Genre.java | 6 +- .../app/service/BookManageSevice.java | 2 - .../app/service/BookManageSeviceImpl.java | 6 - .../otus/mkulikov/shell/AuthorCommands.java | 10 +- .../ru/otus/mkulikov/shell/BookCommands.java | 18 +-- .../ru/otus/mkulikov/shell/GenreCommands.java | 10 +- ...DaoJdbcTest.java => AuthorDaoJpaTest.java} | 11 +- ...okDaoJdbcTest.java => BookDaoJpaTest.java} | 29 ++-- ...eDaoJdbcTest.java => GenreDaoJpaTest.java} | 7 +- .../ru/otus/mkulikov/app/model/BookTest.java | 4 +- .../service/AuthorManageSeviceImplTest.java | 5 +- .../app/service/BookManageSeviceImplTest.java | 5 +- .../service/GenreManageSeviceImplTest.java | 5 +- 19 files changed, 137 insertions(+), 217 deletions(-) delete mode 100644 src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java create mode 100644 src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java rename src/test/java/ru/otus/mkulikov/app/dao/{AuthorDaoJdbcTest.java => AuthorDaoJpaTest.java} (88%) rename src/test/java/ru/otus/mkulikov/app/dao/{BookDaoJdbcTest.java => BookDaoJpaTest.java} (80%) rename src/test/java/ru/otus/mkulikov/app/dao/{GenreDaoJdbcTest.java => GenreDaoJpaTest.java} (90%) diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java index 04e3988..cfb17ba 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java @@ -58,11 +58,14 @@ public int deleteObject(long id) { @Override public int updateObject(Author author) { - return em.createQuery("update Author a set a.surname = :surname, a.first_name = :firstName, a.second_name = :secondName where a.id = :id ") + int count = em.createQuery("update Author a set a.surname = :surname, a.firstName = :firstName, a.secondName = :secondName where a.id = :id ") .setParameter("surname", author.getSurname()) .setParameter("firstName", author.getFirstName()) .setParameter("secondName", author.getSecondName()) .setParameter("id", author.getId()) .executeUpdate(); + + em.clear(); + return count; } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java deleted file mode 100644 index cd3f532..0000000 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJdbc.java +++ /dev/null @@ -1,127 +0,0 @@ -package ru.otus.mkulikov.app.dao; - -import lombok.RequiredArgsConstructor; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; -import org.springframework.stereotype.Repository; -import ru.otus.mkulikov.app.model.Author; -import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Genre; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by IntelliJ IDEA. - * Developer: Maksim Kulikov - * Date: 23.05.2019 - * Time: 13:28 - */ - -@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) -@Repository -@RequiredArgsConstructor -public class BookDaoJdbc implements BookDao { - - private final NamedParameterJdbcOperations namedParameterJdbcOperations; - - private final String BOOK_SELECT = - "select b.*, a.surname, a.first_name, a.second_name, g.name " - + "from Book b " - + "inner join Author a on a.id = b.author_id " - + "inner join Genre g on g.id = b.genre_id " - + "where b.id = :id "; - - private final String BOOK_SELECT_ALL = - "select b.*, a.surname, a.first_name, a.second_name, g.name " - + "from Book b " - + "inner join Author a on a.id = b.author_id " - + "inner join Genre g on g.id = b.genre_id " - + "order by b.id "; - - private final String BOOK_UPDATE = - "update Book " - + "set add_record_date = sysdate, caption = :caption, author_id = :author_id, genre_id = :genre_id, comment = :comment " - + "where id = :id "; - - private final String BOOK_INSERT = - "insert into Book (add_record_date, caption, author_id, genre_id, comment) " - + " values (sysdate, :caption, :author_id, :genre_id, :comment)"; - - private final String BOOK_DELETE = "delete from Book where id = :id "; - - @Override - public Book getById(long id) { - Map paramMap = new HashMap(); - paramMap.put("id", id); - - List books = namedParameterJdbcOperations.query(BOOK_SELECT, paramMap, new BookMapper()); - return (books != null) ? books.get(0) : null; - } - - @Override - public List getAllObjects() { - return namedParameterJdbcOperations.query(BOOK_SELECT_ALL, new BookMapper()); - } - - @Override - public int addObject(Book book) { - Map paramMap = new HashMap(); - paramMap.put("caption", book.getCaption()); - paramMap.put("author_id", book.getAuthor().getId()); - paramMap.put("genre_id", book.getGenre().getId()); - paramMap.put("comment", book.getComment()); - - return namedParameterJdbcOperations.update(BOOK_INSERT, paramMap); - } - - @Override - public int deleteObject(long id) { - Map paramMap = new HashMap(); - paramMap.put("id", id); - - return namedParameterJdbcOperations.update(BOOK_DELETE, paramMap); - } - - @Override - public int updateObject(Book book) { - Map paramMap = new HashMap(); - paramMap.put("caption", book.getCaption()); - paramMap.put("author_id", book.getAuthor().getId()); - paramMap.put("genre_id", book.getGenre().getId()); - paramMap.put("comment", book.getComment()); - paramMap.put("id", book.getId()); - - return namedParameterJdbcOperations.update(BOOK_UPDATE, paramMap); - } - - public static class BookMapper implements RowMapper { - - @Override - public Book mapRow(ResultSet resultSet, int i) throws SQLException { - int id = resultSet.getInt("id"); - Date addRecordDate = resultSet.getDate("add_record_date"); - String caption = resultSet.getString("caption"); - String comment = resultSet.getString("comment"); - - Author author = new Author( - resultSet.getLong("author_id"), - resultSet.getString("surname"), - resultSet.getString("first_name"), - resultSet.getString("second_name") - ); - - Genre genre = new Genre( - resultSet.getLong("genre_id"), - resultSet.getString("name") - ); - - return new Book(id, addRecordDate, caption, author, genre, comment); - } - } -} - diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java new file mode 100644 index 0000000..8fe8ca0 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -0,0 +1,75 @@ +package ru.otus.mkulikov.app.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.mkulikov.app.model.Book; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.Date; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 13:28 + */ + +@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) +@Repository +@Transactional +@RequiredArgsConstructor +public class BookDaoJpa implements BookDao { + + @PersistenceContext + private EntityManager em; + + @Override + public Book getById(long id) { + List books = em.createQuery("select b from Book b where b.id = :id ") + .setParameter("id", id) + .getResultList(); + + return (books != null) ? books.get(0) : null; + } + + @Override + public List getAllObjects() { + return em.createQuery("select b from Book b order by b.id ") + .getResultList(); + } + + @Override + public int addObject(Book book) { + em.persist(book); + return 1; + } + + @Override + public int deleteObject(long id) { + return em.createQuery("delete from Book b where b.id = :id ") + .setParameter("id", id) + .executeUpdate(); + } + + @Override + public int updateObject(Book book) { + int count = em.createQuery( + "update Book b " + + "set b.add_record_date = :add_record_date, b.caption = :caption, b.author_id = :author_id, b.genre_id = :genre_id, b.comment = :comment " + + "where b.id = :id ") + .setParameter("add_record_date", new Date()) + .setParameter("caption", book.getCaption()) + .setParameter("author_id", book.getAuthor().getId()) + .setParameter("genre_id", book.getGenre().getId()) + .setParameter("comment", book.getComment()) + .setParameter("id", book.getId()) + .executeUpdate(); + + em.clear(); + return count; + } +} + diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java index e7e52fb..17331a5 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java @@ -57,9 +57,12 @@ public int deleteObject(long id) { @Override public int updateObject(Genre genre) { - return em.createQuery("update Genre g set g.name = :name where g.id = :id ") + int count = em.createQuery("update Genre g set g.name = :name where g.id = :id ") .setParameter("name", genre.getName()) .setParameter("id", genre.getId()) .executeUpdate(); + + em.clear(); + return count; } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index c3bdcb4..4d0da56 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -58,10 +58,10 @@ public String toFormatedString() { @Override public String toString() { return "Author{" + - "id=" + id + - ", surname='" + surname + '\'' + - ", firstName='" + firstName + '\'' + - ", secondName='" + secondName + '\'' + - "}\n"; + "id=" + id + + ", surname='" + surname + '\'' + + ", firstName='" + firstName + '\'' + + ", secondName='" + secondName + '\'' + + "}\n"; } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index ea3c49b..374d3bc 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -72,12 +72,12 @@ public Book(String caption, Author author, Genre genre, String comment) { @Override public String toString() { return "Book{" + - "id=" + id + - ", addRecordDate=" + addRecordDate + - ", caption='" + caption + '\'' + - ", comment='" + comment + '\'' + - ", author=" + author + - ", genre=" + genre + - "}\n"; + "id=" + id + + ", addRecordDate=" + addRecordDate + + ", caption='" + caption + '\'' + + ", comment='" + comment + '\'' + + ", author=" + author + + ", genre=" + genre + + "}\n"; } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index c89efa3..1e6969e 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -47,8 +47,8 @@ public Genre(String name) { @Override public String toString() { return "Genre{" + - "id=" + id + - ", name='" + name + '\'' + - "}\n"; + "id=" + id + + ", name='" + name + '\'' + + "}\n"; } } \ No newline at end of file diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java index 4dab791..5809dc6 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java @@ -19,8 +19,6 @@ public interface BookManageSevice { List getBooks(); - List getFullBooks(); - int addBook(String caption, int authorId, int genreId, String comment); int updateBook(long id, String caption, int authorId, int genreId, String comment); diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java index f73beca..15c5571 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java @@ -41,12 +41,6 @@ public List getBooks() { return bookDao.getAllObjects(); } - @Override - public List getFullBooks() { - return bookDao.getAllObjects(); - } - - @Override public int addBook(String caption, int authorId, int genreId, String comment) { Author author = authorDao.getById(authorId); diff --git a/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java b/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java index 6fac36a..2ace11e 100644 --- a/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/AuthorCommands.java @@ -22,31 +22,31 @@ public class AuthorCommands { private final AuthorManageService authorManageService; - @ShellMethod(key = { "getAuthorById" }, value = "Select author by id.") + @ShellMethod(key = {"getAuthorById"}, value = "Select author by id.") public String getAuthorById(@ShellOption long id) { Author author = authorManageService.getAuthorById(id); return author.toString(); } - @ShellMethod(key = { "getAuthors" }, value = "Select all authors.") + @ShellMethod(key = {"getAuthors"}, value = "Select all authors.") public String getAuthors() { List allObjects = authorManageService.getAuthors(); return allObjects.toString(); } - @ShellMethod(key = { "addAuthor" }, value = "Add new author.") + @ShellMethod(key = {"addAuthor"}, value = "Add new author.") public String addAuthor(@ShellOption String surname, @ShellOption String firstName, @ShellOption String secondName) { int count = authorManageService.addAuthor(surname, firstName, secondName); return "Add " + count + " row(s)"; } - @ShellMethod(key = { "updateAuthor" }, value = "Update author by id.") + @ShellMethod(key = {"updateAuthor"}, value = "Update author by id.") public String updateAuthor(@ShellOption long id, @ShellOption String surname, @ShellOption String firstName, @ShellOption String secondName) { int count = authorManageService.updateAuthor(id, surname, firstName, secondName); return "Updated " + count + " row(s)"; } - @ShellMethod(key = { "deleteAuthor" }, value = "Delete author by id.") + @ShellMethod(key = {"deleteAuthor"}, value = "Delete author by id.") public String deleteAuthor(@ShellOption long id) { int count = authorManageService.deleteAuthor(id); return "Deleted " + count + " row(s)"; diff --git a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java index a8a998e..e563400 100644 --- a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java @@ -22,43 +22,37 @@ public class BookCommands { private final BookManageSevice bookManageSevice; - @ShellMethod(key = { "getBookById" }, value = "Select book by id.") + @ShellMethod(key = {"getBookById"}, value = "Select book by id.") public String getBookById(@ShellOption long id) { Book book = bookManageSevice.getBookById(id); return book.toString(); } - @ShellMethod(key = { "getFullBookById" }, value = "Select book by id.") + @ShellMethod(key = {"getFullBookById"}, value = "Select book by id.") public String getFullBookById(@ShellOption long id) { Book book = bookManageSevice.getFullBookById(id); return book.toString(); } - @ShellMethod(key = { "getBooks" }, value = "Select all books.") + @ShellMethod(key = {"getBooks"}, value = "Select all books.") public String getBooks() { List allObjects = bookManageSevice.getBooks(); return allObjects.toString(); } - @ShellMethod(key = { "getFullBooks" }, value = "Select all books.") - public String getFullBooks() { - List allObjects = bookManageSevice.getFullBooks(); - return allObjects.toString(); - } - - @ShellMethod(key = { "addBook" }, value = "Add new book.") + @ShellMethod(key = {"addBook"}, value = "Add new book.") public String addBook(@ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { int count = bookManageSevice.addBook(caption, authorId, genreId, comment); return "Add " + count + " row(s)"; } - @ShellMethod(key = { "updateBook" }, value = "Update book by id.") + @ShellMethod(key = {"updateBook"}, value = "Update book by id.") public String updateBook(@ShellOption long id, @ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { int count = bookManageSevice.updateBook(id, caption, authorId, genreId, comment); return "Updated " + count + " row(s)"; } - @ShellMethod(key = { "deleteBook" }, value = "Delete book by id.") + @ShellMethod(key = {"deleteBook"}, value = "Delete book by id.") public String deleteBook(@ShellOption long id) { int count = bookManageSevice.deleteBook(id); return "Deleted " + count + " row(s)"; diff --git a/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java b/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java index e0959bf..eb2344e 100644 --- a/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/GenreCommands.java @@ -22,31 +22,31 @@ public class GenreCommands { private final GenreManageService genreManageService; - @ShellMethod(key = { "getGenreById" }, value = "Select genre by id.") + @ShellMethod(key = {"getGenreById"}, value = "Select genre by id.") public String getGenreById(@ShellOption long id) { Genre genre = genreManageService.getGenreById(id); return genre.toString(); } - @ShellMethod(key = { "getGenres" }, value = "Select all genres.") + @ShellMethod(key = {"getGenres"}, value = "Select all genres.") public String getGenres() { List allObjects = genreManageService.getGenres(); return allObjects.toString(); } - @ShellMethod(key = { "addGenre" }, value = "Add new genre.") + @ShellMethod(key = {"addGenre"}, value = "Add new genre.") public String addGenre(@ShellOption String name) { int count = genreManageService.addGenre(name); return "Add " + count + " row(s)"; } - @ShellMethod(key = { "updateGenre" }, value = "Update genre by id.") + @ShellMethod(key = {"updateGenre"}, value = "Update genre by id.") public String updateGenre(@ShellOption long id, @ShellOption String name) { int count = genreManageService.updateGenre(id, name); return "Updated " + count + " row(s)"; } - @ShellMethod(key = { "deleteGenre" }, value = "Delete genre by id.") + @ShellMethod(key = {"deleteGenre"}, value = "Delete genre by id.") public String deleteGenre(@ShellOption long id) { int count = genreManageService.deleteGenre(id); return "Deleted " + count + " row(s)"; diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java similarity index 88% rename from src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java rename to src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java index 5971ffe..71e26d0 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java @@ -6,16 +6,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Author; +import javax.persistence.PersistenceException; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. @@ -28,7 +25,7 @@ @RunWith(SpringRunner.class) @Import(AuthorDaoJpa.class) @DataJpaTest -class AuthorDaoJdbcTest { +class AuthorDaoJpaTest { @Autowired private AuthorDao authorDaoJpa; @@ -80,7 +77,7 @@ void addObject() { @Test void deleteObject() { - assertThrows(DataIntegrityViolationException.class, () -> { authorDaoJpa.deleteObject(1L); }); + assertThrows(PersistenceException.class, () -> { authorDaoJpa.deleteObject(1L); }); } @Test diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java similarity index 80% rename from src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java rename to src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java index 908c10a..c4fb107 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java @@ -15,10 +15,7 @@ import java.util.Date; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. @@ -30,15 +27,15 @@ @DisplayName("Класс BookDaoJdbc") @RunWith(SpringRunner.class) @JdbcTest -@Import(BookDaoJdbc.class) -class BookDaoJdbcTest { +@Import(BookDaoJpa.class) +class BookDaoJpaTest { @Autowired - private BookDao bookDaoJdbc; + private BookDao bookDaoJpa; @Test void getById() { - Book book = bookDaoJdbc.getById(1L); + Book book = bookDaoJpa.getById(1L); assertAll( "book", @@ -54,7 +51,7 @@ void getById() { @Test void getAllObjects() { - List books = bookDaoJdbc.getAllObjects(); + List books = bookDaoJpa.getAllObjects(); assertAll( "books", @@ -68,8 +65,8 @@ void getAllObjects() { @Test void addObject() { - int count = bookDaoJdbc.addObject(getNewBook()); - Book book = bookDaoJdbc.getById(4L); + int count = bookDaoJpa.addObject(getNewBook()); + Book book = bookDaoJpa.getById(4L); assertAll( "book", @@ -85,20 +82,20 @@ void addObject() { @Test void deleteObject() { - int count = bookDaoJdbc.deleteObject(1L); + int count = bookDaoJpa.deleteObject(1L); assertAll( "book", () -> assertEquals(1, count), - () -> assertThrows(IndexOutOfBoundsException.class, () -> { bookDaoJdbc.getById(1L); }) + () -> assertThrows(IndexOutOfBoundsException.class, () -> { bookDaoJpa.getById(1L); }) ); } @Test void updateObject() { - Book book1 = bookDaoJdbc.getById(1L); - int count = bookDaoJdbc.updateObject(getNewBook()); - Book book2 = bookDaoJdbc.getById(1L); + Book book1 = bookDaoJpa.getById(1L); + int count = bookDaoJpa.updateObject(getNewBook()); + Book book2 = bookDaoJpa.getById(1L); assertAll( "book", diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java similarity index 90% rename from src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java rename to src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java index c73c2e1..f14731a 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJdbcTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java @@ -12,10 +12,7 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. @@ -28,7 +25,7 @@ @RunWith(SpringRunner.class) @JdbcTest @Import(GenreDaoJpa.class) -class GenreDaoJdbcTest { +class GenreDaoJpaTest { @Autowired private GenreDao genreDaoJpa; diff --git a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java index 293ef8c..f70da33 100644 --- a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java +++ b/src/test/java/ru/otus/mkulikov/app/model/BookTest.java @@ -10,9 +10,7 @@ import java.text.SimpleDateFormat; import java.util.Date; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java index 93ca519..c0c8743 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -12,10 +12,7 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index e7db9bc..54ca4e6 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -12,10 +12,7 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java index 57a833b..e938751 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -12,10 +12,7 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; /** * Created by IntelliJ IDEA. From 88398c9d3d48c58103c033fac82ff6f99e5fb411 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Fri, 14 Jun 2019 18:01:48 +0300 Subject: [PATCH 21/30] =?UTF-8?q?=D0=9D=D0=B0=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=B9=D0=BA=D0=B0=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20jpa.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/otus/mkulikov/app/dao/BookDaoJpa.java | 11 +++++++---- src/main/java/ru/otus/mkulikov/app/model/Book.java | 9 +++++++-- src/main/resources/application.yml | 2 +- .../ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java | 4 +++- .../java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java | 8 +++++--- .../ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java | 10 +++++++--- .../app/service/AuthorManageSeviceImplTest.java | 8 ++++++-- .../app/service/BookManageSeviceImplTest.java | 5 ++++- .../app/service/GenreManageSeviceImplTest.java | 8 ++++++-- src/test/resources/test_application.yml | 9 +++++++++ 10 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 src/test/resources/test_application.yml diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java index 8fe8ca0..5d8aaeb 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -37,13 +37,16 @@ public Book getById(long id) { @Override public List getAllObjects() { - return em.createQuery("select b from Book b order by b.id ") + List books = em.createQuery("select b from Book b order by b.id ") .getResultList(); + + return books; } @Override public int addObject(Book book) { em.persist(book); + em.clear(); return 1; } @@ -56,10 +59,10 @@ public int deleteObject(long id) { @Override public int updateObject(Book book) { - int count = em.createQuery( + int count = em.createNativeQuery( "update Book b " - + "set b.add_record_date = :add_record_date, b.caption = :caption, b.author_id = :author_id, b.genre_id = :genre_id, b.comment = :comment " - + "where b.id = :id ") + + "set b.add_record_date = :add_record_date, b.caption = :caption, b.author_id = :author_id, b.genre_id = :genre_id, b.comment = :comment " + + "where b.id = :id ") .setParameter("add_record_date", new Date()) .setParameter("caption", book.getCaption()) .setParameter("author_id", book.getAuthor().getId()) diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 374d3bc..c7bc001 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -2,11 +2,16 @@ import lombok.Data; +import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; @@ -36,10 +41,10 @@ public class Book { @Column(name = "COMMENT") private String comment; - @OneToOne + @ManyToOne private Author author; - @OneToOne + @ManyToOne private Genre genre; public Book() { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1534e00..2a393df 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: banner: - location: "classpath:banner.txt" + location: jpa: hibernate: diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java index 71e26d0..3ae2a15 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Author; @@ -21,10 +22,11 @@ * Time: 10:12 */ -@DisplayName("Класс AuthorDaoJdbc") +@DisplayName("Класс AuthorDaoJpa") @RunWith(SpringRunner.class) @Import(AuthorDaoJpa.class) @DataJpaTest +@TestPropertySource(locations= "classpath:test_application.yml") class AuthorDaoJpaTest { @Autowired diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java index c4fb107..bcba7fd 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java @@ -4,8 +4,9 @@ import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; @@ -24,10 +25,11 @@ * Time: 13:16 */ -@DisplayName("Класс BookDaoJdbc") +@DisplayName("Класс BookDaoJpa") @RunWith(SpringRunner.class) -@JdbcTest @Import(BookDaoJpa.class) +@DataJpaTest +@TestPropertySource(locations= "classpath:test_application.yml") class BookDaoJpaTest { @Autowired diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java index f14731a..cc48de5 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java @@ -5,11 +5,14 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Genre; +import javax.persistence.PersistenceException; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -21,10 +24,11 @@ * Time: 9:45 */ -@DisplayName("Класс GenreDaoJdbc") +@DisplayName("Класс GenreDaoJpa") @RunWith(SpringRunner.class) -@JdbcTest @Import(GenreDaoJpa.class) +@DataJpaTest +@TestPropertySource(locations= "classpath:test_application.yml") class GenreDaoJpaTest { @Autowired @@ -73,7 +77,7 @@ void addObject() { @Test void deleteObject() { - assertThrows(DataIntegrityViolationException.class, () -> { genreDaoJpa.deleteObject(1L); }); + assertThrows(PersistenceException.class, () -> { genreDaoJpa.deleteObject(1L); }); } @Test diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java index c0c8743..bea7318 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -5,11 +5,14 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Author; +import javax.persistence.PersistenceException; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -23,8 +26,9 @@ @DisplayName("Класс AuthorManageSevice") @RunWith(SpringRunner.class) -@JdbcTest @ComponentScan("ru.otus.mkulikov.app") +@DataJpaTest +@TestPropertySource(locations= "classpath:test_application.yml") class AuthorManageSeviceImplTest { @Autowired @@ -94,6 +98,6 @@ void updateAuthor() { @Test void deleteAuthor() { - assertThrows(DataIntegrityViolationException.class, () -> { authorManageService.deleteAuthor(1L); }); + assertThrows(PersistenceException.class, () -> { authorManageService.deleteAuthor(1L); }); } } diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index 54ca4e6..241781e 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -5,7 +5,9 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.utils.DateUtil; @@ -23,8 +25,9 @@ @DisplayName("Класс BookManageSevice") @RunWith(SpringRunner.class) -@JdbcTest @ComponentScan("ru.otus.mkulikov.app") +@DataJpaTest +@TestPropertySource(locations= "classpath:test_application.yml") class BookManageSeviceImplTest { @Autowired diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java index e938751..8aa5fa9 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -5,11 +5,14 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Genre; +import javax.persistence.PersistenceException; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -23,8 +26,9 @@ @DisplayName("Класс GenreManageSevice") @RunWith(SpringRunner.class) -@JdbcTest @ComponentScan("ru.otus.mkulikov.app") +@DataJpaTest +@TestPropertySource(locations= "classpath:test_application.yml") class GenreManageSeviceImplTest { @Autowired @@ -86,6 +90,6 @@ void updateGenre() { @Test void deleteGenre() { - assertThrows(DataIntegrityViolationException.class, () -> { genreManageService.deleteGenre(1L); }); + assertThrows(PersistenceException.class, () -> { genreManageService.deleteGenre(1L); }); } } diff --git a/src/test/resources/test_application.yml b/src/test/resources/test_application.yml new file mode 100644 index 0000000..2a393df --- /dev/null +++ b/src/test/resources/test_application.yml @@ -0,0 +1,9 @@ +spring: + banner: + location: + + jpa: + hibernate: + ddl-auto: none + + From 64470370c5642f8624c4a3a541182008a5d7c132 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 17 Jun 2019 16:36:12 +0300 Subject: [PATCH 22/30] =?UTF-8?q?-=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20dao.=20-=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B0=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/otus/mkulikov/app/dao/BookDaoJpa.java | 1 - .../ru/otus/mkulikov/app/model/Author.java | 1 + .../java/ru/otus/mkulikov/app/model/Book.java | 18 +++++++++++++++-- .../ru/otus/mkulikov/app/model/Genre.java | 2 +- src/main/resources/application.yml | 7 +++++-- src/main/resources/schema.sql | 2 +- .../otus/mkulikov/app/dao/BookDaoJpaTest.java | 20 ++++++++++++++----- src/test/resources/test_application.yml | 7 +++++-- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java index 5d8aaeb..76b1fa9 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -46,7 +46,6 @@ public List getAllObjects() { @Override public int addObject(Book book) { em.persist(book); - em.clear(); return 1; } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index 4d0da56..e5fc804 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -7,6 +7,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index c7bc001..332863e 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -11,6 +11,7 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.MapsId; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; @@ -41,10 +42,17 @@ public class Book { @Column(name = "COMMENT") private String comment; - @ManyToOne + @Column(name = "AUTHOR_ID", updatable = false, insertable = false) + private long author_id; + @Column(name = "GENRE_ID", updatable = false, insertable = false) + private long genre_id; + + @OneToOne(optional=false) + //@JoinColumn(name="ID", referencedColumnName="AUTHOR_ID") private Author author; - @ManyToOne + @OneToOne(optional=false) + //@JoinColumn(name="ID", referencedColumnName="GENRE_ID") private Genre genre; public Book() { @@ -57,6 +65,8 @@ public Book(long id, Date addRecordDate, String caption, Author author, Genre ge this.genre = genre; this.caption = caption; this.comment = comment; + this.author_id = author.getId(); + this.genre_id = genre.getId(); } public Book(long id, String caption, Author author, Genre genre, String comment) { @@ -65,6 +75,8 @@ public Book(long id, String caption, Author author, Genre genre, String comment) this.author = author; this.genre = genre; this.comment = comment; + this.author_id = author.getId(); + this.genre_id = genre.getId(); } public Book(String caption, Author author, Genre genre, String comment) { @@ -72,6 +84,8 @@ public Book(String caption, Author author, Genre genre, String comment) { this.author = author; this.genre = genre; this.comment = comment; + this.author_id = author.getId(); + this.genre_id = genre.getId(); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index 1e6969e..a8153b9 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -7,6 +7,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; @@ -27,7 +28,6 @@ public class Genre { @SequenceGenerator(name = "sq_genre", sequenceName = "sq_genre", allocationSize = 1) @Column(name = "ID") private long id; - @Column(name = "NAME") private String name; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2a393df..515ee34 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,9 +1,12 @@ spring: banner: - location: + location: "classpath:banner.txt" jpa: hibernate: ddl-auto: none - + properties: + hibernate: + show_sql: false + format_sql: false \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 538c6ab..8f77a94 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -16,7 +16,7 @@ CREATE TABLE GENRE( CREATE TABLE BOOK( ID NUMBER(22,0) PRIMARY KEY not null, - ADD_RECORD_DATE DATE, + ADD_RECORD_DATE DATE default sysdate, CAPTION VARCHAR(255) not null, AUTHOR_ID NUMBER(22,0) not null, GENRE_ID NUMBER(22,0) not null, diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java index bcba7fd..75d5fad 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java @@ -27,13 +27,17 @@ @DisplayName("Класс BookDaoJpa") @RunWith(SpringRunner.class) -@Import(BookDaoJpa.class) +@Import({BookDaoJpa.class, AuthorDaoJpa.class, GenreDaoJpa.class}) @DataJpaTest @TestPropertySource(locations= "classpath:test_application.yml") class BookDaoJpaTest { @Autowired private BookDao bookDaoJpa; + @Autowired + private AuthorDao authorDao; + @Autowired + private GenreDao genreDao; @Test void getById() { @@ -96,7 +100,7 @@ void deleteObject() { @Test void updateObject() { Book book1 = bookDaoJpa.getById(1L); - int count = bookDaoJpa.updateObject(getNewBook()); + int count = bookDaoJpa.updateObject(getUpdatedBook()); Book book2 = bookDaoJpa.getById(1L); assertAll( @@ -110,8 +114,14 @@ void updateObject() { } private Book getNewBook() { - Author author = new Author(1L, "TestSurname", "TestFirstName", "TestSecondName"); - Genre genre = new Genre(1L, "Test4"); - return new Book(1L, new Date(), "Test_Book", author, genre, "Test_Comment"); + Author author = authorDao.getById(1); + Genre genre = genreDao.getById(1); + return new Book("Test_Book", author, genre, "Test_Comment"); + } + + private Book getUpdatedBook() { + Author author = authorDao.getById(1); + Genre genre = genreDao.getById(1); + return new Book(1L,"Test_Book", author, genre, "Test_Comment"); } } \ No newline at end of file diff --git a/src/test/resources/test_application.yml b/src/test/resources/test_application.yml index 2a393df..515ee34 100644 --- a/src/test/resources/test_application.yml +++ b/src/test/resources/test_application.yml @@ -1,9 +1,12 @@ spring: banner: - location: + location: "classpath:banner.txt" jpa: hibernate: ddl-auto: none - + properties: + hibernate: + show_sql: false + format_sql: false \ No newline at end of file From f8ca9452d0480a13e9b244bc7b56652be74b7e9b Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 17 Jun 2019 18:01:53 +0300 Subject: [PATCH 23/30] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B8=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B1=D0=B4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 6 +++- src/main/resources/{data.sql => data-h2.sql} | 0 .../resources/{schema.sql => schema-h2.sql} | 0 .../mkulikov/app/dao/AuthorDaoJpaTest.java | 16 +++++----- .../otus/mkulikov/app/dao/BookDaoJpaTest.java | 3 +- .../mkulikov/app/dao/GenreDaoJpaTest.java | 4 +-- .../service/AuthorManageSeviceImplTest.java | 18 +++++------ .../app/service/BookManageSeviceImplTest.java | 3 +- .../service/GenreManageSeviceImplTest.java | 4 +-- .../{test_application.yml => application.yml} | 7 ++++- src/test/resources/data-test.sql | 27 ++++++++++++++++ src/test/resources/schema-test.sql | 31 +++++++++++++++++++ 12 files changed, 89 insertions(+), 30 deletions(-) rename src/main/resources/{data.sql => data-h2.sql} (100%) rename src/main/resources/{schema.sql => schema-h2.sql} (100%) rename src/test/resources/{test_application.yml => application.yml} (62%) create mode 100644 src/test/resources/data-test.sql create mode 100644 src/test/resources/schema-test.sql diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 515ee34..91ca387 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,6 +2,10 @@ spring: banner: location: "classpath:banner.txt" + datasource: + initialization-mode: always + platform: h2 + jpa: hibernate: ddl-auto: none @@ -9,4 +13,4 @@ spring: properties: hibernate: show_sql: false - format_sql: false \ No newline at end of file + format_sql: false diff --git a/src/main/resources/data.sql b/src/main/resources/data-h2.sql similarity index 100% rename from src/main/resources/data.sql rename to src/main/resources/data-h2.sql diff --git a/src/main/resources/schema.sql b/src/main/resources/schema-h2.sql similarity index 100% rename from src/main/resources/schema.sql rename to src/main/resources/schema-h2.sql diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java index 3ae2a15..040c5ec 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java @@ -26,7 +26,7 @@ @RunWith(SpringRunner.class) @Import(AuthorDaoJpa.class) @DataJpaTest -@TestPropertySource(locations= "classpath:test_application.yml") +@TestPropertySource(locations= "classpath:application.yml") class AuthorDaoJpaTest { @Autowired @@ -40,9 +40,9 @@ void getById() { "author", () -> assertNotNull(author), () -> assertEquals(1L, author.getId()), - () -> assertEquals("Surname1", author.getSurname()), - () -> assertEquals("FirstName1", author.getFirstName()), - () -> assertEquals("SecondName1", author.getSecondName()) + () -> assertEquals("Surname", author.getSurname()), + () -> assertEquals("FirstName", author.getFirstName()), + () -> assertEquals("SecondName", author.getSecondName()) ); } @@ -54,7 +54,7 @@ void getAllObjects() { "authors", () -> assertNotNull(authors), () -> assertEquals(3, authors.size()), - () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname", authors.get(0).getSurname()), () -> assertEquals("Surname2", authors.get(1).getSurname()), () -> assertEquals("Surname3", authors.get(2).getSurname()) ); @@ -93,9 +93,9 @@ void updateObject() { assertAll( "author", () -> assertEquals(1, count), - () -> assertEquals("Surname1", author1.getSurname()), - () -> assertEquals("FirstName1", author1.getFirstName()), - () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("Surname", author1.getSurname()), + () -> assertEquals("FirstName", author1.getFirstName()), + () -> assertEquals("SecondName", author1.getSecondName()), () -> assertEquals("TestSurname", author2.getSurname()), () -> assertEquals("TestFirstName", author2.getFirstName()), () -> assertEquals("TestSecondName", author2.getSecondName()) diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java index 75d5fad..4a79cb1 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java @@ -13,7 +13,6 @@ import ru.otus.mkulikov.app.model.Genre; import ru.otus.mkulikov.app.utils.DateUtil; -import java.util.Date; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -29,7 +28,7 @@ @RunWith(SpringRunner.class) @Import({BookDaoJpa.class, AuthorDaoJpa.class, GenreDaoJpa.class}) @DataJpaTest -@TestPropertySource(locations= "classpath:test_application.yml") +@TestPropertySource(locations= "classpath:application.yml") class BookDaoJpaTest { @Autowired diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java index cc48de5..cc939a4 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java @@ -4,10 +4,8 @@ import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Genre; @@ -28,7 +26,7 @@ @RunWith(SpringRunner.class) @Import(GenreDaoJpa.class) @DataJpaTest -@TestPropertySource(locations= "classpath:test_application.yml") +@TestPropertySource(locations= "classpath:application.yml") class GenreDaoJpaTest { @Autowired diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java index bea7318..ff34ac1 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -4,10 +4,8 @@ import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Author; @@ -28,7 +26,7 @@ @RunWith(SpringRunner.class) @ComponentScan("ru.otus.mkulikov.app") @DataJpaTest -@TestPropertySource(locations= "classpath:test_application.yml") +@TestPropertySource(locations= "classpath:application.yml") class AuthorManageSeviceImplTest { @Autowired @@ -42,9 +40,9 @@ void getAuthorById() { "author", () -> assertNotNull(author), () -> assertEquals(1L, author.getId()), - () -> assertEquals("Surname1", author.getSurname()), - () -> assertEquals("FirstName1", author.getFirstName()), - () -> assertEquals("SecondName1", author.getSecondName()) + () -> assertEquals("Surname", author.getSurname()), + () -> assertEquals("FirstName", author.getFirstName()), + () -> assertEquals("SecondName", author.getSecondName()) ); } @@ -56,7 +54,7 @@ void getAuthors() { "authors", () -> assertNotNull(authors), () -> assertEquals(3, authors.size()), - () -> assertEquals("Surname1", authors.get(0).getSurname()), + () -> assertEquals("Surname", authors.get(0).getSurname()), () -> assertEquals("Surname2", authors.get(1).getSurname()), () -> assertEquals("Surname3", authors.get(2).getSurname()) ); @@ -87,9 +85,9 @@ void updateAuthor() { assertAll( "author", () -> assertEquals(1, count), - () -> assertEquals("Surname1", author1.getSurname()), - () -> assertEquals("FirstName1", author1.getFirstName()), - () -> assertEquals("SecondName1", author1.getSecondName()), + () -> assertEquals("Surname", author1.getSurname()), + () -> assertEquals("FirstName", author1.getFirstName()), + () -> assertEquals("SecondName", author1.getSecondName()), () -> assertEquals("TestSurname", author2.getSurname()), () -> assertEquals("TestFirstName", author2.getFirstName()), () -> assertEquals("TestSecondName", author2.getSecondName()) diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index 241781e..2198576 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; @@ -27,7 +26,7 @@ @RunWith(SpringRunner.class) @ComponentScan("ru.otus.mkulikov.app") @DataJpaTest -@TestPropertySource(locations= "classpath:test_application.yml") +@TestPropertySource(locations= "classpath:application.yml") class BookManageSeviceImplTest { @Autowired diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java index 8aa5fa9..784d44c 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -4,10 +4,8 @@ import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import ru.otus.mkulikov.app.model.Genre; @@ -28,7 +26,7 @@ @RunWith(SpringRunner.class) @ComponentScan("ru.otus.mkulikov.app") @DataJpaTest -@TestPropertySource(locations= "classpath:test_application.yml") +@TestPropertySource(locations= "classpath:application.yml") class GenreManageSeviceImplTest { @Autowired diff --git a/src/test/resources/test_application.yml b/src/test/resources/application.yml similarity index 62% rename from src/test/resources/test_application.yml rename to src/test/resources/application.yml index 515ee34..c679d5b 100644 --- a/src/test/resources/test_application.yml +++ b/src/test/resources/application.yml @@ -2,6 +2,10 @@ spring: banner: location: "classpath:banner.txt" + datasource: + initialization-mode: always + platform: test + jpa: hibernate: ddl-auto: none @@ -9,4 +13,5 @@ spring: properties: hibernate: show_sql: false - format_sql: false \ No newline at end of file + format_sql: false + diff --git a/src/test/resources/data-test.sql b/src/test/resources/data-test.sql new file mode 100644 index 0000000..e1ff332 --- /dev/null +++ b/src/test/resources/data-test.sql @@ -0,0 +1,27 @@ +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (sq_author.nextval, 'Surname', 'FirstName', 'SecondName'); + +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (sq_author.nextval, 'Surname2', 'FirstName2', 'SecondName2'); + +insert into AUTHOR (ID, SURNAME, FIRST_NAME, SECOND_NAME) +values (sq_author.nextval, 'Surname3', 'FirstName3', 'SecondName3'); + +-------------------------- + +insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre1'); +insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre2'); +insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre3'); + +-------------------------- + +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); + +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); + +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); + +-------------------------- diff --git a/src/test/resources/schema-test.sql b/src/test/resources/schema-test.sql new file mode 100644 index 0000000..8f77a94 --- /dev/null +++ b/src/test/resources/schema-test.sql @@ -0,0 +1,31 @@ +DROP TABLE IF EXISTS BOOK; +DROP TABLE IF EXISTS AUTHOR; +DROP TABLE IF EXISTS GENRE; + +CREATE TABLE AUTHOR( + ID NUMBER(22,0) PRIMARY KEY not null, + SURNAME VARCHAR(100) not null, + FIRST_NAME VARCHAR(100) not null, + SECOND_NAME VARCHAR(100) +); + +CREATE TABLE GENRE( + ID NUMBER(22,0) PRIMARY KEY not null, + NAME VARCHAR(100) not null +); + +CREATE TABLE BOOK( + ID NUMBER(22,0) PRIMARY KEY not null, + ADD_RECORD_DATE DATE default sysdate, + CAPTION VARCHAR(255) not null, + AUTHOR_ID NUMBER(22,0) not null, + GENRE_ID NUMBER(22,0) not null, + COMMENT VARCHAR(255), + + foreign key (AUTHOR_ID) references AUTHOR(ID), + foreign key (GENRE_ID) references GENRE(ID) +); + +CREATE SEQUENCE sq_author minvalue 1 start with 1 increment by 1; +CREATE SEQUENCE sq_genre minvalue 1 start with 1 increment by 1; +CREATE SEQUENCE sq_book minvalue 1 start with 1 increment by 1; From e2f98fd6b89ea7120e78bf7035dc8a6d12a1240f Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 17 Jun 2019 18:13:48 +0300 Subject: [PATCH 24/30] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.yml | 2 +- src/test/resources/banner-test.txt | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/banner-test.txt diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index c679d5b..e2c030c 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,6 +1,6 @@ spring: banner: - location: "classpath:banner.txt" + location: "classpath:banner-test.txt" datasource: initialization-mode: always diff --git a/src/test/resources/banner-test.txt b/src/test/resources/banner-test.txt new file mode 100644 index 0000000..50a692c --- /dev/null +++ b/src/test/resources/banner-test.txt @@ -0,0 +1,11 @@ + ___ ___ ___ ___ ___ ___ ___ + /\__\ /\ \ /\__\ /\ \ /\ \ ___ / /\ / /\ ___ + /:/ / /::\ \ /:/ / /::\ \ /::\ \ /__/\ / /::\ / /::\ /__/\ + /:/ / /:/\:\ \ /:/ / /:/\:\ \ /:/\ \ \ \ \:\ / /:/\:\ /__/:/\:\ \ \:\ + /:/ / ___ /:/ \:\ \ /:/ / /::\~\:\ \ _\:\~\ \ \ \__\:\ / /::\ \:\ _\_ \:\ \:\ \__\:\ + /:/__/ /\__\ /:/__/ \:\__\ /:/__/ /:/\:\ \:\__\ /\ \:\ \ \__\ *** / /::\ /__/:/\:\ \:\ /__/\ \:\ \:\ / /::\ + \:\ \ /:/ / \:\ \ /:/ / \:\ \ \:\~\:\ \/__/ \:\ \:\ \/__/ / /:/\:\ \ \:\ \:\_\/ \ \:\ \:\_\/ / /:/\:\ + \:\ /:/ / \:\ /:/ / \:\ \ \:\ \:\__\ \:\ \:\__\ / /:/__\/ \ \:\ \:\ \ \:\_\:\ / /:/__\/ + \:\/:/ / \:\/:/ / \:\ \ \:\ \/__/ \:\/:/ / /__/:/ \ \:\_\/ \ \:\/:/ /__/:/ + \::/ / \::/ / \:\__\ \:\__\ \::/ / \__\/ \ \:\ \ \::/ \__\/ + \/__/ \/__/ \/__/ \/__/ \/__/ \__\/ \__\/ From 033c5da5afb53d3f3f236beb7786e3c277058208 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Wed, 19 Jun 2019 00:45:15 +0300 Subject: [PATCH 25/30] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=82=D1=8D=D1=81=D1=82=D0=BE=D0=B2.=20-=20=D0=A1?= =?UTF-8?q?=D0=B2=D1=8F=D0=B7=D0=B8=20OneToOne=20=D0=B8=D0=B7=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=B0=20ManyToOne.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++ .../otus/mkulikov/app/dao/AuthorDaoJpa.java | 1 - .../ru/otus/mkulikov/app/model/Author.java | 13 +------- .../java/ru/otus/mkulikov/app/model/Book.java | 33 +++---------------- .../ru/otus/mkulikov/app/model/Genre.java | 9 +---- .../app/service/BookManageSevice.java | 2 -- .../app/service/BookManageSeviceImpl.java | 5 --- .../ru/otus/mkulikov/shell/BookCommands.java | 6 ---- .../mkulikov/app/dao/AuthorDaoJpaTest.java | 5 +++ .../otus/mkulikov/app/dao/BookDaoJpaTest.java | 5 +++ .../mkulikov/app/dao/GenreDaoJpaTest.java | 5 +++ .../{BookTest.java => DateUtilTest.java} | 6 ++-- .../service/AuthorManageSeviceImplTest.java | 5 +++ .../app/service/BookManageSeviceImplTest.java | 23 +++---------- .../service/GenreManageSeviceImplTest.java | 5 +++ 15 files changed, 43 insertions(+), 84 deletions(-) rename src/test/java/ru/otus/mkulikov/app/model/{BookTest.java => DateUtilTest.java} (91%) diff --git a/README.md b/README.md index aff31e5..40b2856 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,7 @@ - Использовать JPA, Hibernate только в качестве JPA-провайдера. - Добавить комментарии к книгам, и высокоуровневые сервисы, оставляющие комментарии к книгам. - Покрыть DAO тестами используя H2 базу данных и соответствующий H2 Hibernate-диалект. + +### 19-09-19 Доработки: +- Добавлены названия тэстов. +- Связи OneToOne изменены на ManyToOne. diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java index cfb17ba..640852d 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java @@ -7,7 +7,6 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; - import java.util.List; /** diff --git a/src/main/java/ru/otus/mkulikov/app/model/Author.java b/src/main/java/ru/otus/mkulikov/app/model/Author.java index e5fc804..edca570 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Author.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Author.java @@ -2,14 +2,7 @@ import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; +import javax.persistence.*; /** * Created by IntelliJ IDEA. @@ -52,10 +45,6 @@ public Author(String surname, String firstName, String secondName) { this.secondName = secondName; } - public String toFormatedString() { - return getSurname() + " " + getFirstName() + " " + getSecondName(); - } - @Override public String toString() { return "Author{" + diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 332863e..1b7f81b 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -2,20 +2,7 @@ import lombok.Data; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MapsId; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; +import javax.persistence.*; import java.util.Date; /** @@ -42,17 +29,10 @@ public class Book { @Column(name = "COMMENT") private String comment; - @Column(name = "AUTHOR_ID", updatable = false, insertable = false) - private long author_id; - @Column(name = "GENRE_ID", updatable = false, insertable = false) - private long genre_id; - - @OneToOne(optional=false) - //@JoinColumn(name="ID", referencedColumnName="AUTHOR_ID") + @ManyToOne(optional=false) private Author author; - @OneToOne(optional=false) - //@JoinColumn(name="ID", referencedColumnName="GENRE_ID") + @ManyToOne(optional=false) private Genre genre; public Book() { @@ -65,8 +45,6 @@ public Book(long id, Date addRecordDate, String caption, Author author, Genre ge this.genre = genre; this.caption = caption; this.comment = comment; - this.author_id = author.getId(); - this.genre_id = genre.getId(); } public Book(long id, String caption, Author author, Genre genre, String comment) { @@ -75,17 +53,14 @@ public Book(long id, String caption, Author author, Genre genre, String comment) this.author = author; this.genre = genre; this.comment = comment; - this.author_id = author.getId(); - this.genre_id = genre.getId(); } public Book(String caption, Author author, Genre genre, String comment) { + this.id = 0L; this.caption = caption; this.author = author; this.genre = genre; this.comment = comment; - this.author_id = author.getId(); - this.genre_id = genre.getId(); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/model/Genre.java b/src/main/java/ru/otus/mkulikov/app/model/Genre.java index a8153b9..dc37847 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Genre.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Genre.java @@ -2,14 +2,7 @@ import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; +import javax.persistence.*; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java index 5809dc6..535b2dd 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java @@ -15,8 +15,6 @@ public interface BookManageSevice { T getBookById(long id); - T getFullBookById(long id); - List getBooks(); int addBook(String caption, int authorId, int genreId, String comment); diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java index 15c5571..1caf2b0 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java @@ -31,11 +31,6 @@ public Book getBookById(long id) { return bookDao.getById(id); } - @Override - public Book getFullBookById(long id) { - return bookDao.getById(id); - } - @Override public List getBooks() { return bookDao.getAllObjects(); diff --git a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java index e563400..163788d 100644 --- a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java @@ -28,12 +28,6 @@ public String getBookById(@ShellOption long id) { return book.toString(); } - @ShellMethod(key = {"getFullBookById"}, value = "Select book by id.") - public String getFullBookById(@ShellOption long id) { - Book book = bookManageSevice.getFullBookById(id); - return book.toString(); - } - @ShellMethod(key = {"getBooks"}, value = "Select all books.") public String getBooks() { List allObjects = bookManageSevice.getBooks(); diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java index 040c5ec..96ebe9d 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java @@ -33,6 +33,7 @@ class AuthorDaoJpaTest { private AuthorDao authorDaoJpa; @Test + @DisplayName("Получение автора по id") void getById() { Author author = authorDaoJpa.getById(1L); @@ -47,6 +48,7 @@ void getById() { } @Test + @DisplayName("Получение всех авторов") void getAllObjects() { List authors = authorDaoJpa.getAllObjects(); @@ -61,6 +63,7 @@ void getAllObjects() { } @Test + @DisplayName("Добавление автора") void addObject() { Author author = new Author("TestSurname", "TestFirstName", "TestSecondName"); int count = authorDaoJpa.addObject(author); @@ -78,11 +81,13 @@ void addObject() { } @Test + @DisplayName("Удаление автора, который используется в таблице книг") void deleteObject() { assertThrows(PersistenceException.class, () -> { authorDaoJpa.deleteObject(1L); }); } @Test + @DisplayName("Обновление автора") void updateObject() { Author author1 = authorDaoJpa.getById(1L); int count = authorDaoJpa.updateObject( diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java index 4a79cb1..6958758 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java @@ -39,6 +39,7 @@ class BookDaoJpaTest { private GenreDao genreDao; @Test + @DisplayName("Получение книги по id") void getById() { Book book = bookDaoJpa.getById(1L); @@ -55,6 +56,7 @@ void getById() { } @Test + @DisplayName("Получение всех книг") void getAllObjects() { List books = bookDaoJpa.getAllObjects(); @@ -69,6 +71,7 @@ void getAllObjects() { } @Test + @DisplayName("Добавление книги") void addObject() { int count = bookDaoJpa.addObject(getNewBook()); Book book = bookDaoJpa.getById(4L); @@ -86,6 +89,7 @@ void addObject() { } @Test + @DisplayName("Удаление книги по id") void deleteObject() { int count = bookDaoJpa.deleteObject(1L); @@ -97,6 +101,7 @@ void deleteObject() { } @Test + @DisplayName("Обновление книги") void updateObject() { Book book1 = bookDaoJpa.getById(1L); int count = bookDaoJpa.updateObject(getUpdatedBook()); diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java index cc939a4..ab25d87 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java @@ -33,6 +33,7 @@ class GenreDaoJpaTest { private GenreDao genreDaoJpa; @Test + @DisplayName("Получение жанра по id") void getById() { Genre genre = genreDaoJpa.getById(1L); @@ -45,6 +46,7 @@ void getById() { } @Test + @DisplayName("Получение всех жанров") void getAllObjects() { List genres = genreDaoJpa.getAllObjects(); @@ -59,6 +61,7 @@ void getAllObjects() { } @Test + @DisplayName("Добавление жанра") void addObject() { int count = genreDaoJpa.addObject(new Genre("Test4")); @@ -74,11 +77,13 @@ void addObject() { } @Test + @DisplayName("Удаление жанра, который используется в таблице книг") void deleteObject() { assertThrows(PersistenceException.class, () -> { genreDaoJpa.deleteObject(1L); }); } @Test + @DisplayName("Обновление жанра") void updateObject() { Genre genre1 = genreDaoJpa.getById(1L); int count = genreDaoJpa.updateObject(new Genre(1L, "UpdatedName")); diff --git a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java b/src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java similarity index 91% rename from src/test/java/ru/otus/mkulikov/app/model/BookTest.java rename to src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java index f70da33..291acd0 100644 --- a/src/test/java/ru/otus/mkulikov/app/model/BookTest.java +++ b/src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java @@ -19,12 +19,12 @@ * Time: 11:39 */ -@DisplayName("Класс Book") +@DisplayName("Класс DateUtil") @RunWith(SpringRunner.class) -//@SpringBootTest(classes = AppTestConfig.class) -class BookTest { +class DateUtilTest { @Test + @DisplayName("Формат даты 'yyyy-MM-dd'") void getAddRecordDateString() { Book book = getNewBook(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); diff --git a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java index ff34ac1..2203f8c 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/AuthorManageSeviceImplTest.java @@ -33,6 +33,7 @@ class AuthorManageSeviceImplTest { private AuthorManageService authorManageService; @Test + @DisplayName("Получение автора по id") void getAuthorById() { Author author = authorManageService.getAuthorById(1L); @@ -47,6 +48,7 @@ void getAuthorById() { } @Test + @DisplayName("Получение всех авторов") void getAuthors() { List authors = authorManageService.getAuthors(); @@ -61,6 +63,7 @@ void getAuthors() { } @Test + @DisplayName("Добавление автора") void addAuthor() { int count = authorManageService.addAuthor("TestSurname", "TestFirstName", "TestSecondName"); Author author_selected = authorManageService.getAuthorById(4L); @@ -77,6 +80,7 @@ void addAuthor() { } @Test + @DisplayName("Обновление автора") void updateAuthor() { Author author1 = authorManageService.getAuthorById(1L); int count = authorManageService.updateAuthor(1L, "TestSurname", "TestFirstName", "TestSecondName"); @@ -95,6 +99,7 @@ void updateAuthor() { } @Test + @DisplayName("Удаление автора, который используется в таблице книг") void deleteAuthor() { assertThrows(PersistenceException.class, () -> { authorManageService.deleteAuthor(1L); }); } diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index 2198576..d017f57 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -33,6 +33,7 @@ class BookManageSeviceImplTest { private BookManageSevice booksManageSevice; @Test + @DisplayName("Получение книги по id") void getBookById() { Book book = booksManageSevice.getBookById(1L); @@ -51,24 +52,7 @@ void getBookById() { } @Test - void getFullBookById() { - Book book = booksManageSevice.getFullBookById(1); - - assertAll( - "book", - () -> assertNotNull(book), - () -> assertNotNull(book.getAuthor()), - () -> assertNotNull(book.getGenre()), - () -> assertEquals(1L, book.getId()), - () -> assertEquals("2019-01-01", DateUtil.dateToString(book.getAddRecordDate())), - () -> assertEquals("book_1", book.getCaption()), - () -> assertEquals(1, book.getAuthor().getId()), - () -> assertEquals(1, book.getGenre().getId()), - () -> assertEquals("comment", book.getComment()) - ); - } - - @Test + @DisplayName("Получение всех книг") void getBooks() { List books = booksManageSevice.getBooks(); @@ -83,6 +67,7 @@ void getBooks() { } @Test + @DisplayName("Добавление книги") void addBook() { int count = booksManageSevice.addBook("Test_Book", 2, 3, "Test_Comment"); Book book = booksManageSevice.getBookById(4L); @@ -100,6 +85,7 @@ void addBook() { } @Test + @DisplayName("Обновление книги") void updateBook() { Book book1 = booksManageSevice.getBookById(1L); int count = booksManageSevice.updateBook(1L, "Test_Book", 2, 3, "Test_Comment"); @@ -116,6 +102,7 @@ void updateBook() { } @Test + @DisplayName("Удаление книги по id") void deleteBook() { int count = booksManageSevice.deleteBook(1L); diff --git a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java index 784d44c..da4d95f 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/GenreManageSeviceImplTest.java @@ -33,6 +33,7 @@ class GenreManageSeviceImplTest { private GenreManageService genreManageService; @Test + @DisplayName("Получение жанра по id") void getGenreById() { Genre genre = genreManageService.getGenreById(1L); @@ -45,6 +46,7 @@ void getGenreById() { } @Test + @DisplayName("Получение всех жанров") void getGenres() { List genres = genreManageService.getGenres(); @@ -59,6 +61,7 @@ void getGenres() { } @Test + @DisplayName("Добавление жанра") void addGenre() { int count = genreManageService.addGenre("Test4"); Genre genre = genreManageService.getGenreById(4L); @@ -73,6 +76,7 @@ void addGenre() { } @Test + @DisplayName("Обновление жанра") void updateGenre() { Genre genre1 = genreManageService.getGenreById(1L); int count = genreManageService.updateGenre(1L, "UpdatedName"); @@ -87,6 +91,7 @@ void updateGenre() { } @Test + @DisplayName("Удаление жанра, который используется в таблице книг") void deleteGenre() { assertThrows(PersistenceException.class, () -> { genreManageService.deleteGenre(1L); }); } From d7900084e9ce206f44904114ebba6113631baebd Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Thu, 20 Jun 2019 13:40:47 +0300 Subject: [PATCH 26/30] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=80=D1=83=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= =?UTF-8?q?=20Book.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ .../java/ru/otus/mkulikov/app/dao/BookDaoJpa.java | 12 ++++++++++-- src/main/java/ru/otus/mkulikov/app/model/Book.java | 8 ++++++-- src/test/resources/application.yml | 4 ++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 40b2856..a2255dd 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,6 @@ ### 19-09-19 Доработки: - Добавлены названия тэстов. - Связи OneToOne изменены на ManyToOne. + +### 19-09-20 Доработки: +- Изменена струкрура запроса для сущности Book. \ No newline at end of file diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java index 76b1fa9..9abc144 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -28,7 +28,11 @@ public class BookDaoJpa implements BookDao { @Override public Book getById(long id) { - List books = em.createQuery("select b from Book b where b.id = :id ") + List books = em.createQuery("select b " + + "from Book b " + + "inner join fetch b.author a " + + "inner join fetch b.genre g " + + "where b.id = :id ") .setParameter("id", id) .getResultList(); @@ -37,7 +41,11 @@ public Book getById(long id) { @Override public List getAllObjects() { - List books = em.createQuery("select b from Book b order by b.id ") + List books = em.createQuery("select b " + + "from Book b " + + "inner join fetch b.author a " + + "inner join fetch b.genre g " + + "order by b.id ") .getResultList(); return books; diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 1b7f81b..8cfc9a8 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -1,6 +1,8 @@ package ru.otus.mkulikov.app.model; import lombok.Data; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; import javax.persistence.*; import java.util.Date; @@ -29,10 +31,12 @@ public class Book { @Column(name = "COMMENT") private String comment; - @ManyToOne(optional=false) + @Fetch(FetchMode.JOIN) + @ManyToOne(optional=false, fetch = FetchType.EAGER) private Author author; - @ManyToOne(optional=false) + @Fetch(FetchMode.JOIN) + @ManyToOne(optional=false, fetch = FetchType.EAGER) private Genre genre; public Book() { diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index e2c030c..6175668 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -12,6 +12,6 @@ spring: properties: hibernate: - show_sql: false - format_sql: false + show_sql: true + format_sql: true From 6d1e02fd6338c144eb5949b1fd42e70d0ff58cb1 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Fri, 21 Jun 2019 08:18:38 +0300 Subject: [PATCH 27/30] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=20comment=20=D0=B8=20=D0=BA=D0=BB=D0=B0=D1=87?= =?UTF-8?q?=D1=87=D0=BE=D0=B2=20=D0=BA=20=D0=BD=D0=B5=D0=B9.=20-=20=D0=94?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D1=81=D0=BA?= =?UTF-8?q?=D1=80=D0=B8=D0=BF=D1=82=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/otus/mkulikov/app/dao/BookDaoJpa.java | 10 ++- .../ru/otus/mkulikov/app/dao/CommentDao.java | 28 +++++++ .../otus/mkulikov/app/dao/CommentDaoJpa.java | 82 +++++++++++++++++++ .../java/ru/otus/mkulikov/app/model/Book.java | 22 +++-- .../ru/otus/mkulikov/app/model/Comment.java | 60 ++++++++++++++ .../app/service/BookManageSevice.java | 4 +- .../app/service/BookManageSeviceImpl.java | 10 ++- .../app/service/CommentManageService.java | 25 ++++++ .../app/service/CommentManageServiceImpl.java | 50 +++++++++++ .../app/service/GenreManageService.java | 4 +- .../ru/otus/mkulikov/shell/BookCommands.java | 8 +- src/main/resources/data-h2.sql | 24 ++++-- src/main/resources/schema-h2.sql | 24 ++++-- 13 files changed, 314 insertions(+), 37 deletions(-) create mode 100644 src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java create mode 100644 src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java create mode 100644 src/main/java/ru/otus/mkulikov/app/model/Comment.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java create mode 100644 src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java index 9abc144..12eee8f 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -32,7 +32,8 @@ public Book getById(long id) { + "from Book b " + "inner join fetch b.author a " + "inner join fetch b.genre g " - + "where b.id = :id ") + + "inner join fetch b.comment c " + + "where b.id = :id ", Book.class) .setParameter("id", id) .getResultList(); @@ -45,7 +46,8 @@ public List getAllObjects() { + "from Book b " + "inner join fetch b.author a " + "inner join fetch b.genre g " - + "order by b.id ") + + "inner join fetch b.comment c " + + "order by b.id ", Book.class) .getResultList(); return books; @@ -68,13 +70,13 @@ public int deleteObject(long id) { public int updateObject(Book book) { int count = em.createNativeQuery( "update Book b " - + "set b.add_record_date = :add_record_date, b.caption = :caption, b.author_id = :author_id, b.genre_id = :genre_id, b.comment = :comment " + + "set b.add_record_date = :add_record_date, b.caption = :caption, b.author_id = :author_id, b.genre_id = :genre_id, b.description = :description " + "where b.id = :id ") .setParameter("add_record_date", new Date()) .setParameter("caption", book.getCaption()) .setParameter("author_id", book.getAuthor().getId()) .setParameter("genre_id", book.getGenre().getId()) - .setParameter("comment", book.getComment()) + .setParameter("description", book.getDescription()) .setParameter("id", book.getId()) .executeUpdate(); diff --git a/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java b/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java new file mode 100644 index 0000000..b7a33e1 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java @@ -0,0 +1,28 @@ +package ru.otus.mkulikov.app.dao; + +import ru.otus.mkulikov.app.model.Comment; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 20.06.2019 + * Time: 23:48 + */ + +public interface CommentDao { + + T getById(long id); + + T getByBookId(long id); + + List getAllObjects(); + + int addObject(T t); + + int deleteObject(long id); + + int updateObject(T t); +} diff --git a/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java new file mode 100644 index 0000000..bba522a --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java @@ -0,0 +1,82 @@ +package ru.otus.mkulikov.app.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Comment; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 23.05.2019 + * Time: 17:06 + */ + +@SuppressWarnings({"SqlNoDataSourceInspection", "ConstantConditions", "SqlDialectInspection"}) +@Repository +@Transactional +@RequiredArgsConstructor +public class CommentDaoJpa implements CommentDao { + + @PersistenceContext + private EntityManager em; + + @Override + public Comment getById(long id) { + List list = em.createQuery("select a from Comment a where a.id = :id", Comment.class) + .setParameter("id", id) + .getResultList(); + + // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных + // не хочу ошибку, хочу null + return (list != null && !list.isEmpty()) ? list.get(0) : null; + } + + @Override + public Comment getByBookId(long bookId) { + List list = em.createQuery("select a from Comment a where a.bookId = :bookId", Comment.class) + .setParameter("bookId", bookId) + .getResultList(); + + // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных + // не хочу ошибку, хочу null + return (list != null && !list.isEmpty()) ? list.get(0) : null; + } + + @Override + public List getAllObjects() { + return em.createQuery("select a from Comment a order by a.id", Comment.class) + .getResultList(); + } + + @Override + public int addObject(Comment comment) { + em.persist(comment); + return 1; + } + + @Override + public int deleteObject(long id) { + return em.createQuery("delete from Comment a where a.id = :id ") + .setParameter("id", id) + .executeUpdate(); + } + + @Override + public int updateObject(Comment comment) { + int count = em.createQuery("update Comment a set a.addRecordDate = :addRecordDate, a.userName = :userName , a.text = :text where a.id = :id ") + .setParameter("addRecordDate", comment.getAddRecordDate()) + .setParameter("userName", comment.getUserName()) + .setParameter("text", comment.getText()) + .setParameter("id", comment.getId()) + .executeUpdate(); + + em.clear(); + return count; + } +} diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 8cfc9a8..9aefa3b 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -28,8 +28,12 @@ public class Book { private Date addRecordDate; @Column(name = "CAPTION") private String caption; - @Column(name = "COMMENT") - private String comment; + @Column(name = "DESCRIPTION") + private String description; + +// @Fetch(FetchMode.JOIN) +// @ManyToOne(optional=false, fetch = FetchType.EAGER) +// private Comment comment; @Fetch(FetchMode.JOIN) @ManyToOne(optional=false, fetch = FetchType.EAGER) @@ -42,29 +46,29 @@ public class Book { public Book() { } - public Book(long id, Date addRecordDate, String caption, Author author, Genre genre, String comment) { + public Book(long id, Date addRecordDate, String caption, Author author, Genre genre, String description) { this.id = id; this.addRecordDate = addRecordDate; this.author = author; this.genre = genre; this.caption = caption; - this.comment = comment; + this.description = description; } - public Book(long id, String caption, Author author, Genre genre, String comment) { + public Book(long id, String caption, Author author, Genre genre, String description) { this.id = id; this.caption = caption; this.author = author; this.genre = genre; - this.comment = comment; + this.description = description; } - public Book(String caption, Author author, Genre genre, String comment) { + public Book(String caption, Author author, Genre genre, String description) { this.id = 0L; this.caption = caption; this.author = author; this.genre = genre; - this.comment = comment; + this.description = description; } @Override @@ -73,7 +77,7 @@ public String toString() { "id=" + id + ", addRecordDate=" + addRecordDate + ", caption='" + caption + '\'' + - ", comment='" + comment + '\'' + + ", description=" + description + ", author=" + author + ", genre=" + genre + "}\n"; diff --git a/src/main/java/ru/otus/mkulikov/app/model/Comment.java b/src/main/java/ru/otus/mkulikov/app/model/Comment.java new file mode 100644 index 0000000..00424b9 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/model/Comment.java @@ -0,0 +1,60 @@ +package ru.otus.mkulikov.app.model; + +import lombok.Data; + +import javax.persistence.*; +import java.util.Date; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 20.06.2019 + * Time: 23:38 + */ + +@Data +@Entity +@Table(name = "COMMENT") +public class Comment { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sq_comment") + @SequenceGenerator(name = "sq_comment", sequenceName = "sq_comment", allocationSize = 1) + @Column(name = "ID") + private long id; + @Column(name = "BOOK_ID") + private long bookId; + @Column(name = "ADD_RECORD_DATE") + private Date addRecordDate; + @Column(name = "USER_NAME") + private String userName; + @Column(name = "TEXT") + private String text; + + public Comment(long id, long bookId, Date addRecordDate, String userName, String text) { + this.id = id; + this.bookId = bookId; + this.addRecordDate = addRecordDate; + this.userName = userName; + this.text = text; + } + + public Comment(long bookId, Date addRecordDate, String userName, String text) { + this.id = 0L; + this.bookId = bookId; + this.addRecordDate = addRecordDate; + this.userName = userName; + this.text = text; + } + + @Override + public String toString() { + return "Comment{" + + "id=" + id + + ", bookId=" + bookId + + ", addRecordDate=" + addRecordDate + + ", userName=" + userName + + ", text='" + text + '\'' + + "}\n"; + } +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java index 535b2dd..e08867d 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSevice.java @@ -17,9 +17,9 @@ public interface BookManageSevice { List getBooks(); - int addBook(String caption, int authorId, int genreId, String comment); + int addBook(String caption, int authorId, int genreId, String description); - int updateBook(long id, String caption, int authorId, int genreId, String comment); + int updateBook(long id, String caption, int authorId, int genreId, String description); int deleteBook(long id); } diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java index 1caf2b0..faf01b2 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java @@ -4,9 +4,11 @@ import org.springframework.stereotype.Service; import ru.otus.mkulikov.app.dao.AuthorDao; import ru.otus.mkulikov.app.dao.BookDao; +import ru.otus.mkulikov.app.dao.CommentDao; import ru.otus.mkulikov.app.dao.GenreDao; import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Comment; import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -37,19 +39,19 @@ public List getBooks() { } @Override - public int addBook(String caption, int authorId, int genreId, String comment) { + public int addBook(String caption, int authorId, int genreId, String description) { Author author = authorDao.getById(authorId); Genre genre = genreDao.getById(genreId); - return bookDao.addObject(new Book(caption, author, genre, comment)); + return bookDao.addObject(new Book(caption, author, genre, description)); } @Override - public int updateBook(long id, String caption, int authorId, int genreId, String comment) { + public int updateBook(long id, String caption, int authorId, int genreId, String description) { Author author = authorDao.getById(authorId); Genre genre = genreDao.getById(genreId); - return bookDao.updateObject(new Book(id, caption, author, genre, comment)); + return bookDao.updateObject(new Book(id, caption, author, genre, description)); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java b/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java new file mode 100644 index 0000000..2565a14 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java @@ -0,0 +1,25 @@ +package ru.otus.mkulikov.app.service; + +import ru.otus.mkulikov.app.model.Comment; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:50 + */ +public interface CommentManageService { + + T getCommentById(long id); + + List getComments(); + + int addComment(long bookId, String userName, String text); + + int updateComment(long id, long bookId, String userName, String text); + + int deleteComment(long id); +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java new file mode 100644 index 0000000..9b21664 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java @@ -0,0 +1,50 @@ +package ru.otus.mkulikov.app.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.otus.mkulikov.app.dao.CommentDao; +import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Comment; +import ru.otus.mkulikov.app.model.Genre; + +import java.util.Date; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:52 + */ + +@Service +@RequiredArgsConstructor +public class CommentManageServiceImpl implements CommentManageService { + + private final CommentDao commentDao; + + @Override + public Comment getCommentById(long id) { + return commentDao.getById(id); + } + + @Override + public List getComments() { + return commentDao.getAllObjects(); + } + + @Override + public int addComment(long bookId, String userName, String text) { + return commentDao.addObject(new Comment(bookId, new Date(), userName, text)); + } + + @Override + public int updateComment(long id, long bookId, String userName, String text) { + return commentDao.updateObject(new Comment(id, bookId, new Date(), userName, text)); + } + + @Override + public int deleteComment(long id) { + return commentDao.deleteObject(id); + } +} diff --git a/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java b/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java index d2f62af..80015b3 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java +++ b/src/main/java/ru/otus/mkulikov/app/service/GenreManageService.java @@ -12,9 +12,9 @@ */ public interface GenreManageService { - Genre getGenreById(long id); + T getGenreById(long id); - List getGenres(); + List getGenres(); int addGenre(String name); diff --git a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java index 163788d..b5119f5 100644 --- a/src/main/java/ru/otus/mkulikov/shell/BookCommands.java +++ b/src/main/java/ru/otus/mkulikov/shell/BookCommands.java @@ -35,14 +35,14 @@ public String getBooks() { } @ShellMethod(key = {"addBook"}, value = "Add new book.") - public String addBook(@ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { - int count = bookManageSevice.addBook(caption, authorId, genreId, comment); + public String addBook(@ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String description) { + int count = bookManageSevice.addBook(caption, authorId, genreId, description); return "Add " + count + " row(s)"; } @ShellMethod(key = {"updateBook"}, value = "Update book by id.") - public String updateBook(@ShellOption long id, @ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String comment) { - int count = bookManageSevice.updateBook(id, caption, authorId, genreId, comment); + public String updateBook(@ShellOption long id, @ShellOption String caption, @ShellOption int authorId, @ShellOption int genreId, @ShellOption String description) { + int count = bookManageSevice.updateBook(id, caption, authorId, genreId, description); return "Updated " + count + " row(s)"; } diff --git a/src/main/resources/data-h2.sql b/src/main/resources/data-h2.sql index a0fbb68..eb74cd6 100644 --- a/src/main/resources/data-h2.sql +++ b/src/main/resources/data-h2.sql @@ -15,13 +15,25 @@ insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre3'); -------------------------- -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, DESCRIPTION) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'description'); -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, DESCRIPTION) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'description'); -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, DESCRIPTION) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'description'); -------------------------- + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 1, to_date('2019-01-01','YYYY-MM-DD'), 'user1', 'text1'); + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 1, to_date('2019-01-01','YYYY-MM-DD'), 'user2', 'text2'); + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 2, to_date('2019-01-01','YYYY-MM-DD'), 'user3', 'text3'); + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 2, to_date('2019-01-01','YYYY-MM-DD'), 'user4', 'text4'); \ No newline at end of file diff --git a/src/main/resources/schema-h2.sql b/src/main/resources/schema-h2.sql index 8f77a94..d8d9c5c 100644 --- a/src/main/resources/schema-h2.sql +++ b/src/main/resources/schema-h2.sql @@ -1,31 +1,43 @@ DROP TABLE IF EXISTS BOOK; DROP TABLE IF EXISTS AUTHOR; DROP TABLE IF EXISTS GENRE; +DROP TABLE IF EXISTS COMMENT; CREATE TABLE AUTHOR( - ID NUMBER(22,0) PRIMARY KEY not null, + ID NUMBER(20,0) PRIMARY KEY not null, SURNAME VARCHAR(100) not null, FIRST_NAME VARCHAR(100) not null, SECOND_NAME VARCHAR(100) ); CREATE TABLE GENRE( - ID NUMBER(22,0) PRIMARY KEY not null, + ID NUMBER(20,0) PRIMARY KEY not null, NAME VARCHAR(100) not null ); CREATE TABLE BOOK( - ID NUMBER(22,0) PRIMARY KEY not null, + ID NUMBER(20,0) PRIMARY KEY not null, ADD_RECORD_DATE DATE default sysdate, CAPTION VARCHAR(255) not null, - AUTHOR_ID NUMBER(22,0) not null, - GENRE_ID NUMBER(22,0) not null, - COMMENT VARCHAR(255), + AUTHOR_ID NUMBER(20,0) not null, + GENRE_ID NUMBER(20,0) not null, + DESCRIPTION VARCHAR(255), foreign key (AUTHOR_ID) references AUTHOR(ID), foreign key (GENRE_ID) references GENRE(ID) ); +CREATE TABLE COMMENT( + ID NUMBER(20,0) PRIMARY KEY not null, + BOOK_ID NUMBER(20,0) not null, + ADD_RECORD_DATE DATE default sysdate, + USER_NAME VARCHAR(20), + TEXT VARCHAR(500), + + foreign key (BOOK_ID) references BOOK(ID) +); + CREATE SEQUENCE sq_author minvalue 1 start with 1 increment by 1; CREATE SEQUENCE sq_genre minvalue 1 start with 1 increment by 1; CREATE SEQUENCE sq_book minvalue 1 start with 1 increment by 1; +CREATE SEQUENCE sq_comment minvalue 1 start with 1 increment by 1; \ No newline at end of file From 13c56fced1dc6a32c3c6a0d8532b22b75cb4e150 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Sat, 22 Jun 2019 14:06:58 +0300 Subject: [PATCH 28/30] =?UTF-8?q?-=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B5=D1=85=D0=B0=D0=BD=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B0=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F/=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=B9.=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= =?UTF-8?q?=20Comment=20=D0=B8=20=D0=BF=D0=BE=D0=BA=D1=80=D1=8B=D1=82?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +- .../java/ru/otus/mkulikov/Application.java | 2 - .../ru/otus/mkulikov/app/dao/AuthorDao.java | 4 +- .../otus/mkulikov/app/dao/AuthorDaoJpa.java | 30 ++-- .../ru/otus/mkulikov/app/dao/BookDao.java | 4 +- .../ru/otus/mkulikov/app/dao/BookDaoJpa.java | 32 ++-- .../ru/otus/mkulikov/app/dao/CommentDao.java | 10 +- .../otus/mkulikov/app/dao/CommentDaoJpa.java | 56 ++++--- .../ru/otus/mkulikov/app/dao/GenreDao.java | 4 +- .../ru/otus/mkulikov/app/dao/GenreDaoJpa.java | 36 ++--- .../java/ru/otus/mkulikov/app/model/Book.java | 11 +- .../ru/otus/mkulikov/app/model/Comment.java | 21 ++- .../app/service/AuthorManageServiceImpl.java | 4 +- .../app/service/BookManageSeviceImpl.java | 6 +- .../app/service/CommentManageService.java | 5 +- .../app/service/CommentManageServiceImpl.java | 25 +++- .../app/service/GenreManageServiceImpl.java | 4 +- .../ru/otus/mkulikov/app/utils/DateUtil.java | 7 + .../otus/mkulikov/shell/CommentCommands.java | 60 ++++++++ src/main/resources/data-h2.sql | 8 +- src/main/resources/schema-h2.sql | 4 +- .../mkulikov/app/dao/AuthorDaoJpaTest.java | 4 +- .../otus/mkulikov/app/dao/BookDaoJpaTest.java | 16 +- .../mkulikov/app/dao/CommentDaoJpaTest.java | 139 ++++++++++++++++++ .../mkulikov/app/dao/GenreDaoJpaTest.java | 4 +- .../otus/mkulikov/app/model/DateUtilTest.java | 15 +- .../app/service/BookManageSeviceImplTest.java | 12 +- .../service/CommentManageSeviceImplTest.java | 126 ++++++++++++++++ src/test/resources/data-test.sql | 24 ++- src/test/resources/schema-test.sql | 24 ++- 30 files changed, 536 insertions(+), 168 deletions(-) create mode 100644 src/main/java/ru/otus/mkulikov/shell/CommentCommands.java create mode 100644 src/test/java/ru/otus/mkulikov/app/dao/CommentDaoJpaTest.java create mode 100644 src/test/java/ru/otus/mkulikov/app/service/CommentManageSeviceImplTest.java diff --git a/README.md b/README.md index a2255dd..e5a364a 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,9 @@ - Связи OneToOne изменены на ManyToOne. ### 19-09-20 Доработки: -- Изменена струкрура запроса для сущности Book. \ No newline at end of file +- Изменена струкрура запроса для сущности Book. + +### 19-09-22 Доработки: +- Добавлена сущность Comment. +- Изменение механизма добавления/обновления сущностей. +- Добавление классов для обработки сущности Comment и покрытие тестами. \ No newline at end of file diff --git a/src/main/java/ru/otus/mkulikov/Application.java b/src/main/java/ru/otus/mkulikov/Application.java index 70a6c6d..005151d 100644 --- a/src/main/java/ru/otus/mkulikov/Application.java +++ b/src/main/java/ru/otus/mkulikov/Application.java @@ -1,10 +1,8 @@ package ru.otus.mkulikov; -import org.h2.tools.Console; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.PropertySource; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java index 099b02b..6f09bc7 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java @@ -17,9 +17,7 @@ public interface AuthorDao { List getAllObjects(); - int addObject(T t); + int save(T t); int deleteObject(long id); - - int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java index 640852d..9c8cdb4 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java @@ -31,20 +31,27 @@ public Author getById(long id) { .setParameter("id", id) .getResultList(); - // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных - // не хочу ошибку, хочу null + em.clear(); return (list != null && !list.isEmpty()) ? list.get(0) : null; } @Override public List getAllObjects() { - return em.createQuery("select a from Author a order by a.id", Author.class) + List list = em.createQuery("select a from Author a order by a.id", Author.class) .getResultList(); + + em.clear(); + return list; } @Override - public int addObject(Author author) { - em.persist(author); + public int save(Author author) { + if (author.getId() == 0) { + em.persist(author); + } else { + em.merge(author); + } + System.out.println("Author saved with id: " + author.getId()); return 1; } @@ -54,17 +61,4 @@ public int deleteObject(long id) { .setParameter("id", id) .executeUpdate(); } - - @Override - public int updateObject(Author author) { - int count = em.createQuery("update Author a set a.surname = :surname, a.firstName = :firstName, a.secondName = :secondName where a.id = :id ") - .setParameter("surname", author.getSurname()) - .setParameter("firstName", author.getFirstName()) - .setParameter("secondName", author.getSecondName()) - .setParameter("id", author.getId()) - .executeUpdate(); - - em.clear(); - return count; - } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java index 3e2faa1..58aaf0f 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDao.java @@ -17,9 +17,7 @@ public interface BookDao { List getAllObjects(); - int addObject(T t); + int save(T t); int deleteObject(long id); - - int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java index 12eee8f..fbeb9a0 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -7,7 +7,6 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; -import java.util.Date; import java.util.List; /** @@ -32,11 +31,11 @@ public Book getById(long id) { + "from Book b " + "inner join fetch b.author a " + "inner join fetch b.genre g " - + "inner join fetch b.comment c " + "where b.id = :id ", Book.class) .setParameter("id", id) .getResultList(); + em.clear(); return (books != null) ? books.get(0) : null; } @@ -46,16 +45,21 @@ public List getAllObjects() { + "from Book b " + "inner join fetch b.author a " + "inner join fetch b.genre g " - + "inner join fetch b.comment c " + "order by b.id ", Book.class) .getResultList(); + em.clear(); return books; } @Override - public int addObject(Book book) { - em.persist(book); + public int save(Book book) { + if (book.getId() == 0) { + em.persist(book); + } else { + em.merge(book); + } + System.out.println("Book saved with id: " + book.getId()); return 1; } @@ -65,23 +69,5 @@ public int deleteObject(long id) { .setParameter("id", id) .executeUpdate(); } - - @Override - public int updateObject(Book book) { - int count = em.createNativeQuery( - "update Book b " - + "set b.add_record_date = :add_record_date, b.caption = :caption, b.author_id = :author_id, b.genre_id = :genre_id, b.description = :description " - + "where b.id = :id ") - .setParameter("add_record_date", new Date()) - .setParameter("caption", book.getCaption()) - .setParameter("author_id", book.getAuthor().getId()) - .setParameter("genre_id", book.getGenre().getId()) - .setParameter("description", book.getDescription()) - .setParameter("id", book.getId()) - .executeUpdate(); - - em.clear(); - return count; - } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java b/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java index b7a33e1..49ddac6 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/CommentDao.java @@ -1,7 +1,7 @@ package ru.otus.mkulikov.app.dao; +import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Comment; -import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -16,13 +16,11 @@ public interface CommentDao { T getById(long id); - T getByBookId(long id); + List getByBook(Book book); - List getAllObjects(); + int save(T t); - int addObject(T t); + List getAllObjects(); int deleteObject(long id); - - int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java index bba522a..94a313d 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/CommentDaoJpa.java @@ -3,7 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import ru.otus.mkulikov.app.model.Author; +import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Comment; import javax.persistence.EntityManager; @@ -28,36 +28,47 @@ public class CommentDaoJpa implements CommentDao { @Override public Comment getById(long id) { - List list = em.createQuery("select a from Comment a where a.id = :id", Comment.class) + List list = em.createQuery( + "select c " + + "from Comment c " + + "inner join fetch c.book b " + + "where c.id = :id", Comment.class) .setParameter("id", id) .getResultList(); - // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных - // не хочу ошибку, хочу null + em.clear(); return (list != null && !list.isEmpty()) ? list.get(0) : null; } @Override - public Comment getByBookId(long bookId) { - List list = em.createQuery("select a from Comment a where a.bookId = :bookId", Comment.class) - .setParameter("bookId", bookId) + public List getByBook(Book book) { + List list = em.createQuery( + "select c " + + "from Comment c " + + "inner join fetch c.book b " + + "where c.book = :book", Comment.class) + .setParameter("book", book) .getResultList(); - // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных - // не хочу ошибку, хочу null - return (list != null && !list.isEmpty()) ? list.get(0) : null; + em.clear(); + return list; } @Override - public List getAllObjects() { - return em.createQuery("select a from Comment a order by a.id", Comment.class) - .getResultList(); + public int save(Comment comment) { + if (comment.getId() == 0) { + em.persist(comment); + } else { + em.merge(comment); + } + System.out.println("Comment saved with id: " + comment.getId()); + return 1; } @Override - public int addObject(Comment comment) { - em.persist(comment); - return 1; + public List getAllObjects() { + return em.createQuery("select a from Comment a order by a.id", Comment.class) + .getResultList(); } @Override @@ -66,17 +77,4 @@ public int deleteObject(long id) { .setParameter("id", id) .executeUpdate(); } - - @Override - public int updateObject(Comment comment) { - int count = em.createQuery("update Comment a set a.addRecordDate = :addRecordDate, a.userName = :userName , a.text = :text where a.id = :id ") - .setParameter("addRecordDate", comment.getAddRecordDate()) - .setParameter("userName", comment.getUserName()) - .setParameter("text", comment.getText()) - .setParameter("id", comment.getId()) - .executeUpdate(); - - em.clear(); - return count; - } } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java index 348b84d..4121f3f 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java @@ -17,9 +17,7 @@ public interface GenreDao { List getAllObjects(); - int addObject(T t); + int save(T t); int deleteObject(long id); - - int updateObject(T t); } diff --git a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java index 17331a5..f487fd2 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java @@ -27,24 +27,37 @@ public class GenreDaoJpa implements GenreDao { @Override public Genre getById(long id) { - List list = em.createQuery("select g from Genre g where g.id = :id ", Genre.class) + List list = em.createQuery( + "select g " + + "from Genre g " + + "where g.id = :id ", Genre.class) .setParameter("id", id) .getResultList(); - // не использую getSingleResult, т.к. он возвращает ошибку, если нет данных - // не хочу ошибку, хочу null + em.clear(); return (list != null && !list.isEmpty()) ? list.get(0) : null; } @Override public List getAllObjects() { - return em.createQuery("select g from Genre g order by g.id", Genre.class) + List list = em.createQuery( + "select g " + + "from Genre g " + + "order by g.id", Genre.class) .getResultList(); + + em.clear(); + return list; } @Override - public int addObject(Genre genre) { - em.persist(genre); + public int save(Genre genre) { + if (genre.getId() == 0) { + em.persist(genre); + } else { + em.merge(genre); + } + System.out.println("Genre saved with id: " + genre.getId()); return 1; } @@ -54,15 +67,4 @@ public int deleteObject(long id) { .setParameter("id", id) .executeUpdate(); } - - @Override - public int updateObject(Genre genre) { - int count = em.createQuery("update Genre g set g.name = :name where g.id = :id ") - .setParameter("name", genre.getName()) - .setParameter("id", genre.getId()) - .executeUpdate(); - - em.clear(); - return count; - } } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 9aefa3b..17cdc5c 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -3,9 +3,12 @@ import lombok.Data; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; import javax.persistence.*; import java.util.Date; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -31,10 +34,6 @@ public class Book { @Column(name = "DESCRIPTION") private String description; -// @Fetch(FetchMode.JOIN) -// @ManyToOne(optional=false, fetch = FetchType.EAGER) -// private Comment comment; - @Fetch(FetchMode.JOIN) @ManyToOne(optional=false, fetch = FetchType.EAGER) private Author author; @@ -43,6 +42,10 @@ public class Book { @ManyToOne(optional=false, fetch = FetchType.EAGER) private Genre genre; + @OneToMany(mappedBy = "book", fetch = FetchType.LAZY) + @OnDelete(action = OnDeleteAction.CASCADE) + private List comments; + public Book() { } diff --git a/src/main/java/ru/otus/mkulikov/app/model/Comment.java b/src/main/java/ru/otus/mkulikov/app/model/Comment.java index 00424b9..dd7a0a5 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Comment.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Comment.java @@ -1,6 +1,8 @@ package ru.otus.mkulikov.app.model; import lombok.Data; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; import javax.persistence.*; import java.util.Date; @@ -22,26 +24,32 @@ public class Comment { @SequenceGenerator(name = "sq_comment", sequenceName = "sq_comment", allocationSize = 1) @Column(name = "ID") private long id; - @Column(name = "BOOK_ID") - private long bookId; @Column(name = "ADD_RECORD_DATE") + @Temporal(TemporalType.TIMESTAMP) private Date addRecordDate; @Column(name = "USER_NAME") private String userName; @Column(name = "TEXT") private String text; - public Comment(long id, long bookId, Date addRecordDate, String userName, String text) { + @Fetch(FetchMode.JOIN) + @ManyToOne(optional=false, fetch = FetchType.EAGER) + private Book book; + + public Comment() { + } + + public Comment(long id, Book book, Date addRecordDate, String userName, String text) { this.id = id; - this.bookId = bookId; + this.book = book; this.addRecordDate = addRecordDate; this.userName = userName; this.text = text; } - public Comment(long bookId, Date addRecordDate, String userName, String text) { + public Comment(Book book, Date addRecordDate, String userName, String text) { this.id = 0L; - this.bookId = bookId; + this.book = book; this.addRecordDate = addRecordDate; this.userName = userName; this.text = text; @@ -51,7 +59,6 @@ public Comment(long bookId, Date addRecordDate, String userName, String text) { public String toString() { return "Comment{" + "id=" + id + - ", bookId=" + bookId + ", addRecordDate=" + addRecordDate + ", userName=" + userName + ", text='" + text + '\'' + diff --git a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java index 63632f9..f0bd226 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java @@ -32,12 +32,12 @@ public List getAuthors() { @Override public int addAuthor(String surname, String firstName, String secondName) { - return authorDao.addObject(new Author(surname, firstName, secondName)); + return authorDao.save(new Author(surname, firstName, secondName)); } @Override public int updateAuthor(long id, String surname, String firstName, String secondName) { - return authorDao.updateObject(new Author(id, surname, firstName, secondName)); + return authorDao.save(new Author(id, surname, firstName, secondName)); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java index faf01b2..94a97f1 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java @@ -4,11 +4,9 @@ import org.springframework.stereotype.Service; import ru.otus.mkulikov.app.dao.AuthorDao; import ru.otus.mkulikov.app.dao.BookDao; -import ru.otus.mkulikov.app.dao.CommentDao; import ru.otus.mkulikov.app.dao.GenreDao; import ru.otus.mkulikov.app.model.Author; import ru.otus.mkulikov.app.model.Book; -import ru.otus.mkulikov.app.model.Comment; import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -43,7 +41,7 @@ public int addBook(String caption, int authorId, int genreId, String description Author author = authorDao.getById(authorId); Genre genre = genreDao.getById(genreId); - return bookDao.addObject(new Book(caption, author, genre, description)); + return bookDao.save(new Book(caption, author, genre, description)); } @Override @@ -51,7 +49,7 @@ public int updateBook(long id, String caption, int authorId, int genreId, String Author author = authorDao.getById(authorId); Genre genre = genreDao.getById(genreId); - return bookDao.updateObject(new Book(id, caption, author, genre, description)); + return bookDao.save(new Book(id, caption, author, genre, description)); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java b/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java index 2565a14..5c9e5e7 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java +++ b/src/main/java/ru/otus/mkulikov/app/service/CommentManageService.java @@ -1,7 +1,6 @@ package ru.otus.mkulikov.app.service; import ru.otus.mkulikov.app.model.Comment; -import ru.otus.mkulikov.app.model.Genre; import java.util.List; @@ -17,9 +16,11 @@ public interface CommentManageService { List getComments(); + List getCommentsByBookId(long bookId); + int addComment(long bookId, String userName, String text); - int updateComment(long id, long bookId, String userName, String text); + int updateComment(long id, String userName, String text); int deleteComment(long id); } diff --git a/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java index 9b21664..591e132 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/CommentManageServiceImpl.java @@ -2,10 +2,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import ru.otus.mkulikov.app.dao.BookDao; import ru.otus.mkulikov.app.dao.CommentDao; -import ru.otus.mkulikov.app.dao.GenreDao; +import ru.otus.mkulikov.app.model.Book; import ru.otus.mkulikov.app.model.Comment; -import ru.otus.mkulikov.app.model.Genre; import java.util.Date; import java.util.List; @@ -22,6 +22,7 @@ public class CommentManageServiceImpl implements CommentManageService { private final CommentDao commentDao; + private final BookDao bookDao; @Override public Comment getCommentById(long id) { @@ -33,14 +34,28 @@ public List getComments() { return commentDao.getAllObjects(); } + @Override + public List getCommentsByBookId(long bookId) { + Book book = bookDao.getById(bookId); + + return commentDao.getByBook(book); + } + @Override public int addComment(long bookId, String userName, String text) { - return commentDao.addObject(new Comment(bookId, new Date(), userName, text)); + Book book = bookDao.getById(bookId); + + return commentDao.save(new Comment(book, new Date(), userName, text)); } @Override - public int updateComment(long id, long bookId, String userName, String text) { - return commentDao.updateObject(new Comment(id, bookId, new Date(), userName, text)); + public int updateComment(long id, String userName, String text) { + Comment comment = commentDao.getById(id); + comment.setAddRecordDate(new Date()); + comment.setUserName(userName); + comment.setText(text); + + return commentDao.save(comment); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java b/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java index f0b56a6..2cf897a 100644 --- a/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java +++ b/src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java @@ -32,12 +32,12 @@ public List getGenres() { @Override public int addGenre(String name) { - return genreDao.addObject(new Genre(name)); + return genreDao.save(new Genre(name)); } @Override public int updateGenre(long id, String name) { - return genreDao.updateObject(new Genre(id, name)); + return genreDao.save(new Genre(id, name)); } @Override diff --git a/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java b/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java index 2507a0a..ffbce20 100644 --- a/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java +++ b/src/main/java/ru/otus/mkulikov/app/utils/DateUtil.java @@ -15,8 +15,15 @@ public class DateUtil { private final static String DATE_FORMAT = "yyyy-MM-dd"; + private final static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static String dateToString(Date date) { DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); return date != null ? dateFormat.format(date) : null; } + + public static String dateTimeToString(Date date) { + DateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT); + return date != null ? dateFormat.format(date) : null; + } } diff --git a/src/main/java/ru/otus/mkulikov/shell/CommentCommands.java b/src/main/java/ru/otus/mkulikov/shell/CommentCommands.java new file mode 100644 index 0000000..3965c34 --- /dev/null +++ b/src/main/java/ru/otus/mkulikov/shell/CommentCommands.java @@ -0,0 +1,60 @@ +package ru.otus.mkulikov.shell; + +import lombok.RequiredArgsConstructor; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellOption; +import ru.otus.mkulikov.app.model.Comment; +import ru.otus.mkulikov.app.service.CommentManageService; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 14:47 + */ + +@ShellComponent +@RequiredArgsConstructor +public class CommentCommands { + + private final CommentManageService commentManageService; + + @ShellMethod(key = {"getCommentById"}, value = "Select comment by id.") + public String getCommentById(@ShellOption long id) { + Comment comment = commentManageService.getCommentById(id); + return comment.toString(); + } + + @ShellMethod(key = {"getComments"}, value = "Select all comments.") + public String getComments() { + List allObjects = commentManageService.getComments(); + return allObjects.toString(); + } + + @ShellMethod(key = {"getCommentsByBookId"}, value = "Select all comments.") + public String getCommentsByBookId(@ShellOption long bookId) { + List allObjects = commentManageService.getCommentsByBookId(bookId); + return allObjects.toString(); + } + + @ShellMethod(key = {"addComment"}, value = "Add new comment.") + public String addComment(@ShellOption long bookId, @ShellOption String userName, @ShellOption String text) { + int count = commentManageService.addComment(bookId, userName, text); + return "Add " + count + " row(s)"; + } + + @ShellMethod(key = {"updateComment"}, value = "Update comment by id.") + public String updateComment(@ShellOption long id, @ShellOption String userName, @ShellOption String text) { + int count = commentManageService.updateComment(id, userName, text); + return "Updated " + count + " row(s)"; + } + + @ShellMethod(key = {"deleteComment"}, value = "Delete comment by id.") + public String deleteComment(@ShellOption long id) { + int count = commentManageService.deleteComment(id); + return "Deleted " + count + " row(s)"; + } +} diff --git a/src/main/resources/data-h2.sql b/src/main/resources/data-h2.sql index eb74cd6..bca97c4 100644 --- a/src/main/resources/data-h2.sql +++ b/src/main/resources/data-h2.sql @@ -27,13 +27,13 @@ values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'de -------------------------- insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) -values (sq_comment.nextval, 1, to_date('2019-01-01','YYYY-MM-DD'), 'user1', 'text1'); +values (sq_comment.nextval, 1, to_date('2019-01-01 10:01:01','YYYY-MM-DD HH24-MI-SS'), 'user1', 'text1'); insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) -values (sq_comment.nextval, 1, to_date('2019-01-01','YYYY-MM-DD'), 'user2', 'text2'); +values (sq_comment.nextval, 1, to_date('2019-01-01 10:01:02','YYYY-MM-DD HH24-MI-SS'), 'user2', 'text2'); insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) -values (sq_comment.nextval, 2, to_date('2019-01-01','YYYY-MM-DD'), 'user3', 'text3'); +values (sq_comment.nextval, 2, to_date('2019-01-01 10:01:03','YYYY-MM-DD HH24-MI-SS'), 'user3', 'text3'); insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) -values (sq_comment.nextval, 2, to_date('2019-01-01','YYYY-MM-DD'), 'user4', 'text4'); \ No newline at end of file +values (sq_comment.nextval, 2, to_date('2019-01-01 10:01:04','YYYY-MM-DD HH24-MI-SS'), 'user4', 'text4'); \ No newline at end of file diff --git a/src/main/resources/schema-h2.sql b/src/main/resources/schema-h2.sql index d8d9c5c..7156478 100644 --- a/src/main/resources/schema-h2.sql +++ b/src/main/resources/schema-h2.sql @@ -30,11 +30,11 @@ CREATE TABLE BOOK( CREATE TABLE COMMENT( ID NUMBER(20,0) PRIMARY KEY not null, BOOK_ID NUMBER(20,0) not null, - ADD_RECORD_DATE DATE default sysdate, + ADD_RECORD_DATE TIMESTAMP default sysdate, USER_NAME VARCHAR(20), TEXT VARCHAR(500), - foreign key (BOOK_ID) references BOOK(ID) + foreign key (BOOK_ID) references BOOK(ID) ON DELETE CASCADE ); CREATE SEQUENCE sq_author minvalue 1 start with 1 increment by 1; diff --git a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java index 96ebe9d..3ec510f 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java @@ -66,7 +66,7 @@ void getAllObjects() { @DisplayName("Добавление автора") void addObject() { Author author = new Author("TestSurname", "TestFirstName", "TestSecondName"); - int count = authorDaoJpa.addObject(author); + int count = authorDaoJpa.save(author); Author author_selected = authorDaoJpa.getById(4L); assertAll( @@ -90,7 +90,7 @@ void deleteObject() { @DisplayName("Обновление автора") void updateObject() { Author author1 = authorDaoJpa.getById(1L); - int count = authorDaoJpa.updateObject( + int count = authorDaoJpa.save( new Author(1L, "TestSurname", "TestFirstName", "TestSecondName") ); Author author2 = authorDaoJpa.getById(1L); diff --git a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java index 6958758..6c1e247 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java @@ -51,7 +51,7 @@ void getById() { () -> assertEquals("book_1", book.getCaption()), () -> assertEquals(1, book.getAuthor().getId()), () -> assertEquals(1, book.getGenre().getId()), - () -> assertEquals("comment", book.getComment()) + () -> assertEquals("description", book.getDescription()) ); } @@ -73,7 +73,7 @@ void getAllObjects() { @Test @DisplayName("Добавление книги") void addObject() { - int count = bookDaoJpa.addObject(getNewBook()); + int count = bookDaoJpa.save(getNewBook()); Book book = bookDaoJpa.getById(4L); assertAll( @@ -84,7 +84,7 @@ void addObject() { () -> assertEquals("Test_Book", book.getCaption()), () -> assertEquals(1, book.getAuthor().getId()), () -> assertEquals(1, book.getGenre().getId()), - () -> assertEquals("Test_Comment", book.getComment()) + () -> assertEquals("Test_Description", book.getDescription()) ); } @@ -104,28 +104,28 @@ void deleteObject() { @DisplayName("Обновление книги") void updateObject() { Book book1 = bookDaoJpa.getById(1L); - int count = bookDaoJpa.updateObject(getUpdatedBook()); + int count = bookDaoJpa.save(getUpdatedBook()); Book book2 = bookDaoJpa.getById(1L); assertAll( "book", () -> assertEquals(1, count), () -> assertEquals("book_1", book1.getCaption()), - () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("description", book1.getDescription()), () -> assertEquals("Test_Book", book2.getCaption()), - () -> assertEquals("Test_Comment", book2.getComment()) + () -> assertEquals("Test_Description", book2.getDescription()) ); } private Book getNewBook() { Author author = authorDao.getById(1); Genre genre = genreDao.getById(1); - return new Book("Test_Book", author, genre, "Test_Comment"); + return new Book("Test_Book", author, genre, "Test_Description"); } private Book getUpdatedBook() { Author author = authorDao.getById(1); Genre genre = genreDao.getById(1); - return new Book(1L,"Test_Book", author, genre, "Test_Comment"); + return new Book(1L,"Test_Book", author, genre, "Test_Description"); } } \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/dao/CommentDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/CommentDaoJpaTest.java new file mode 100644 index 0000000..3336556 --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/dao/CommentDaoJpaTest.java @@ -0,0 +1,139 @@ +package ru.otus.mkulikov.app.dao; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.app.model.Book; +import ru.otus.mkulikov.app.model.Comment; +import ru.otus.mkulikov.app.utils.DateUtil; + +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 28.05.2019 + * Time: 9:45 + */ + +@DisplayName("Класс CommentDaoJpa") +@RunWith(SpringRunner.class) +@Import({CommentDaoJpa.class, BookDaoJpa.class}) +@DataJpaTest +@TestPropertySource(locations= "classpath:application.yml") +class CommentDaoJpaTest { + + @Autowired + private BookDao bookDaoJpa; + @Autowired + private CommentDao commentDaoJpa; + + @Test + @DisplayName("Получение комментария по id") + void getById() { + Comment comment = commentDaoJpa.getById(1L); + + assertAll( + "comment", + () -> assertNotNull(comment), + () -> assertNotNull(comment.getBook()), + () -> assertEquals(1L, comment.getId()), + () -> assertEquals("user1", comment.getUserName()), + () -> assertEquals("2019-01-01 10:01:01", DateUtil.dateTimeToString(comment.getAddRecordDate())), + () -> assertEquals("text1", comment.getText()) + ); + } + + @Test + @DisplayName("Получение всех комментариев") + void getAllObjects() { + List comments = commentDaoJpa.getAllObjects(); + + assertAll( + "comments", + () -> assertNotNull(comments), + () -> assertEquals(4, comments.size()), + () -> assertEquals("text1", comments.get(0).getText()), + () -> assertEquals("text2", comments.get(1).getText()), + () -> assertEquals("text3", comments.get(2).getText()), + () -> assertEquals("text4", comments.get(3).getText()) + ); + } + + @Test + @DisplayName("Получение всех комментариев для книги") + void getObjectsByBook() { + Book book = bookDaoJpa.getById(1L); + List comments = commentDaoJpa.getByBook(book); + + assertAll( + "comments", + () -> assertNotNull(comments), + () -> assertEquals(2, comments.size()), + () -> assertEquals("text1", comments.get(0).getText()), + () -> assertEquals("text2", comments.get(1).getText()) + ); + } + + @Test + @DisplayName("Добавление комментария") + void addObject() { + Date date = new Date(); + Book book = bookDaoJpa.getById(1L); + int count = commentDaoJpa.save(new Comment(book, date, "user5", "text5")); + + Comment comment = commentDaoJpa.getById(5L); + + assertAll( + "comment", + () -> assertNotNull(comment), + () -> assertNotNull(comment.getBook()), + () -> assertEquals(1, count), + () -> assertEquals(5L, comment.getId()), + () -> assertEquals(date, comment.getAddRecordDate()), + () -> assertEquals("user5", comment.getUserName()), + () -> assertEquals("text5", comment.getText()) + ); + } + + @Test + @DisplayName("Удаление комментария") + void deleteObject() { + commentDaoJpa.deleteObject(1L); + assertNull(commentDaoJpa.getById(1L)); + } + + @Test + @DisplayName("Обновление комментария") + void updateObject() { + Comment comment1 = commentDaoJpa.getById(1L); + + Date date = new Date(); + int count = commentDaoJpa.save(new Comment(1L, comment1.getBook(), date, "TestUser", "TestText")); + + Comment comment2 = commentDaoJpa.getById(1L); + + assertAll( + "comment", + () -> assertNotNull(comment1), + () -> assertNotNull(comment2), + () -> assertNotNull(comment1.getBook()), + () -> assertNotNull(comment2.getBook()), + () -> assertEquals(1, count), + () -> assertEquals("user1", comment1.getUserName()), + () -> assertEquals("text1", comment1.getText()), + () -> assertEquals(date, comment2.getAddRecordDate()), + () -> assertEquals("TestUser", comment2.getUserName()), + () -> assertEquals("TestText", comment2.getText()) + ); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java index ab25d87..a91800e 100644 --- a/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java +++ b/src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java @@ -63,7 +63,7 @@ void getAllObjects() { @Test @DisplayName("Добавление жанра") void addObject() { - int count = genreDaoJpa.addObject(new Genre("Test4")); + int count = genreDaoJpa.save(new Genre("Test4")); Genre genre = genreDaoJpa.getById(4L); @@ -86,7 +86,7 @@ void deleteObject() { @DisplayName("Обновление жанра") void updateObject() { Genre genre1 = genreDaoJpa.getById(1L); - int count = genreDaoJpa.updateObject(new Genre(1L, "UpdatedName")); + int count = genreDaoJpa.save(new Genre(1L, "UpdatedName")); Genre genre2 = genreDaoJpa.getById(1L); assertAll( diff --git a/src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java b/src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java index 291acd0..1276d90 100644 --- a/src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java +++ b/src/test/java/ru/otus/mkulikov/app/model/DateUtilTest.java @@ -25,7 +25,7 @@ class DateUtilTest { @Test @DisplayName("Формат даты 'yyyy-MM-dd'") - void getAddRecordDateString() { + void dateToString() { Book book = getNewBook(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); @@ -36,6 +36,19 @@ void getAddRecordDateString() { ); } + @Test + @DisplayName("Формат даты 'yyyy-MM-dd HH:mm:ss'") + void dateTimeToString() { + Book book = getNewBook(); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + assertAll( + "book", + () -> assertNotNull(book), + () -> assertEquals(dateFormat.format(new Date()), DateUtil.dateTimeToString(book.getAddRecordDate())) + ); + } + private Book getNewBook() { Author author = new Author(1L, "TestSurname", "TestFirstName", "TestSecondName"); Genre genre = new Genre("Test4"); diff --git a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java index d017f57..5dbb053 100644 --- a/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java +++ b/src/test/java/ru/otus/mkulikov/app/service/BookManageSeviceImplTest.java @@ -47,7 +47,7 @@ void getBookById() { () -> assertEquals("book_1", book.getCaption()), () -> assertEquals(1, book.getAuthor().getId()), () -> assertEquals(1, book.getGenre().getId()), - () -> assertEquals("comment", book.getComment()) + () -> assertEquals("description", book.getDescription()) ); } @@ -69,7 +69,7 @@ void getBooks() { @Test @DisplayName("Добавление книги") void addBook() { - int count = booksManageSevice.addBook("Test_Book", 2, 3, "Test_Comment"); + int count = booksManageSevice.addBook("Test_Book", 2, 3, "Test_Description"); Book book = booksManageSevice.getBookById(4L); assertAll( @@ -80,7 +80,7 @@ void addBook() { () -> assertEquals("Test_Book", book.getCaption()), () -> assertEquals(2, book.getAuthor().getId()), () -> assertEquals(3, book.getGenre().getId()), - () -> assertEquals("Test_Comment", book.getComment()) + () -> assertEquals("Test_Description", book.getDescription()) ); } @@ -88,16 +88,16 @@ void addBook() { @DisplayName("Обновление книги") void updateBook() { Book book1 = booksManageSevice.getBookById(1L); - int count = booksManageSevice.updateBook(1L, "Test_Book", 2, 3, "Test_Comment"); + int count = booksManageSevice.updateBook(1L, "Test_Book", 2, 3, "Test_Description"); Book book2 = booksManageSevice.getBookById(1L); assertAll( "book", () -> assertEquals(1, count), () -> assertEquals("book_1", book1.getCaption()), - () -> assertEquals("comment", book1.getComment()), + () -> assertEquals("description", book1.getDescription()), () -> assertEquals("Test_Book", book2.getCaption()), - () -> assertEquals("Test_Comment", book2.getComment()) + () -> assertEquals("Test_Description", book2.getDescription()) ); } diff --git a/src/test/java/ru/otus/mkulikov/app/service/CommentManageSeviceImplTest.java b/src/test/java/ru/otus/mkulikov/app/service/CommentManageSeviceImplTest.java new file mode 100644 index 0000000..e641616 --- /dev/null +++ b/src/test/java/ru/otus/mkulikov/app/service/CommentManageSeviceImplTest.java @@ -0,0 +1,126 @@ +package ru.otus.mkulikov.app.service; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import ru.otus.mkulikov.app.model.Comment; +import ru.otus.mkulikov.app.utils.DateUtil; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Created by IntelliJ IDEA. + * Developer: Maksim Kulikov + * Date: 30.05.2019 + * Time: 15:56 + */ + +@DisplayName("Класс CommentManageSevice") +@RunWith(SpringRunner.class) +@ComponentScan("ru.otus.mkulikov.app") +@DataJpaTest +@TestPropertySource(locations= "classpath:application.yml") +class CommentManageSeviceImplTest { + + @Autowired + private CommentManageService commentManageService; + + @Test + @DisplayName("Получение комментария по id") + void getCommentById() { + Comment comment = commentManageService.getCommentById(1L); + + assertAll( + "comment", + () -> assertNotNull(comment), + () -> assertNotNull(comment.getBook()), + () -> assertEquals(1L, comment.getId()), + () -> assertEquals("user1", comment.getUserName()), + () -> assertEquals("2019-01-01 10:01:01", DateUtil.dateTimeToString(comment.getAddRecordDate())), + () -> assertEquals("text1", comment.getText()) + ); + } + + @Test + @DisplayName("Получение всех комментариев") + void getComments() { + List comments = commentManageService.getComments(); + + assertAll( + "comments", + () -> assertNotNull(comments), + () -> assertEquals(4, comments.size()), + () -> assertEquals("text1", comments.get(0).getText()), + () -> assertEquals("text2", comments.get(1).getText()), + () -> assertEquals("text3", comments.get(2).getText()), + () -> assertEquals("text4", comments.get(3).getText()) + ); + } + + @Test + @DisplayName("Добавление комментария") + void addComment() { + int count = commentManageService.addComment(1L, "user5", "text5"); + + Comment comment = commentManageService.getCommentById(5L); + + assertAll( + "comment", + () -> assertNotNull(comment), + () -> assertNotNull(comment.getBook()), + () -> assertEquals(1, count), + () -> assertEquals(5L, comment.getId()), + () -> assertEquals("user5", comment.getUserName()), + () -> assertEquals("text5", comment.getText()) + ); + } + + @Test + @DisplayName("Получение комментариев по Id книги") + void getCommentsByBookId() { + List comments = commentManageService.getCommentsByBookId(1L); + + assertAll( + "comments", + () -> assertNotNull(comments), + () -> assertEquals(2, comments.size()), + () -> assertEquals("text1", comments.get(0).getText()), + () -> assertEquals("text2", comments.get(1).getText()) + ); + } + + @Test + @DisplayName("Обновление комментария") + void updateComment() { + Comment comment1 = commentManageService.getCommentById(1L); + int count = commentManageService.updateComment(1L, "TestUser", "TestText"); + Comment comment2 = commentManageService.getCommentById(1L); + + assertAll( + "comment", + () -> assertNotNull(comment1), + () -> assertNotNull(comment2), + () -> assertNotNull(comment1.getBook()), + () -> assertNotNull(comment2.getBook()), + () -> assertEquals(1, count), + () -> assertEquals("user1", comment1.getUserName()), + () -> assertEquals("text1", comment1.getText()), + () -> assertEquals("TestUser", comment2.getUserName()), + () -> assertEquals("TestText", comment2.getText()) + ); + } + + @Test + @DisplayName("Удаление комментария") + void deleteComment() { + commentManageService.deleteComment(1L); + assertNull(commentManageService.getCommentById(1L)); + } +} diff --git a/src/test/resources/data-test.sql b/src/test/resources/data-test.sql index e1ff332..75ebe2d 100644 --- a/src/test/resources/data-test.sql +++ b/src/test/resources/data-test.sql @@ -15,13 +15,25 @@ insert into GENRE (ID, NAME) values (sq_genre.nextval, 'Genre3'); -------------------------- -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, DESCRIPTION) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_1', 1, 1, 'description'); -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, DESCRIPTION) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_2', 1, 1, 'description'); -insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, COMMENT) -values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'comment'); +insert into BOOK (ID, ADD_RECORD_DATE, CAPTION, AUTHOR_ID, GENRE_ID, DESCRIPTION) +values (sq_book.nextval, to_date('2019-01-01','YYYY-MM-DD'), 'book_3', 1, 1, 'description'); -------------------------- + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 1, to_date('2019-01-01 10:01:01','YYYY-MM-DD HH24-MI-SS'), 'user1', 'text1'); + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 1, to_date('2019-01-01 10:01:02','YYYY-MM-DD HH24-MI-SS'), 'user2', 'text2'); + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 2, to_date('2019-01-01 10:01:03','YYYY-MM-DD HH24-MI-SS'), 'user3', 'text3'); + +insert into COMMENT (ID, BOOK_ID, ADD_RECORD_DATE, USER_NAME, TEXT) +values (sq_comment.nextval, 2, to_date('2019-01-01 10:01:04','YYYY-MM-DD HH24-MI-SS'), 'user4', 'text4'); \ No newline at end of file diff --git a/src/test/resources/schema-test.sql b/src/test/resources/schema-test.sql index 8f77a94..7156478 100644 --- a/src/test/resources/schema-test.sql +++ b/src/test/resources/schema-test.sql @@ -1,31 +1,43 @@ DROP TABLE IF EXISTS BOOK; DROP TABLE IF EXISTS AUTHOR; DROP TABLE IF EXISTS GENRE; +DROP TABLE IF EXISTS COMMENT; CREATE TABLE AUTHOR( - ID NUMBER(22,0) PRIMARY KEY not null, + ID NUMBER(20,0) PRIMARY KEY not null, SURNAME VARCHAR(100) not null, FIRST_NAME VARCHAR(100) not null, SECOND_NAME VARCHAR(100) ); CREATE TABLE GENRE( - ID NUMBER(22,0) PRIMARY KEY not null, + ID NUMBER(20,0) PRIMARY KEY not null, NAME VARCHAR(100) not null ); CREATE TABLE BOOK( - ID NUMBER(22,0) PRIMARY KEY not null, + ID NUMBER(20,0) PRIMARY KEY not null, ADD_RECORD_DATE DATE default sysdate, CAPTION VARCHAR(255) not null, - AUTHOR_ID NUMBER(22,0) not null, - GENRE_ID NUMBER(22,0) not null, - COMMENT VARCHAR(255), + AUTHOR_ID NUMBER(20,0) not null, + GENRE_ID NUMBER(20,0) not null, + DESCRIPTION VARCHAR(255), foreign key (AUTHOR_ID) references AUTHOR(ID), foreign key (GENRE_ID) references GENRE(ID) ); +CREATE TABLE COMMENT( + ID NUMBER(20,0) PRIMARY KEY not null, + BOOK_ID NUMBER(20,0) not null, + ADD_RECORD_DATE TIMESTAMP default sysdate, + USER_NAME VARCHAR(20), + TEXT VARCHAR(500), + + foreign key (BOOK_ID) references BOOK(ID) ON DELETE CASCADE +); + CREATE SEQUENCE sq_author minvalue 1 start with 1 increment by 1; CREATE SEQUENCE sq_genre minvalue 1 start with 1 increment by 1; CREATE SEQUENCE sq_book minvalue 1 start with 1 increment by 1; +CREATE SEQUENCE sq_comment minvalue 1 start with 1 increment by 1; \ No newline at end of file From f8d243346313933ac37c3bb6bad14bb958b6dfb7 Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Sat, 22 Jun 2019 14:18:19 +0300 Subject: [PATCH 29/30] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BA=D0=BD=D0=B8=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java | 6 ++++-- src/main/java/ru/otus/mkulikov/app/model/Book.java | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java index fbeb9a0..dad9f26 100644 --- a/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java +++ b/src/main/java/ru/otus/mkulikov/app/dao/BookDaoJpa.java @@ -27,10 +27,11 @@ public class BookDaoJpa implements BookDao { @Override public Book getById(long id) { - List books = em.createQuery("select b " + List books = em.createQuery("select distinct b " + "from Book b " + "inner join fetch b.author a " + "inner join fetch b.genre g " + + "left join b.comments c " + "where b.id = :id ", Book.class) .setParameter("id", id) .getResultList(); @@ -41,10 +42,11 @@ public Book getById(long id) { @Override public List getAllObjects() { - List books = em.createQuery("select b " + List books = em.createQuery("select distinct b " + "from Book b " + "inner join fetch b.author a " + "inner join fetch b.genre g " + + "left join b.comments c " + "order by b.id ", Book.class) .getResultList(); diff --git a/src/main/java/ru/otus/mkulikov/app/model/Book.java b/src/main/java/ru/otus/mkulikov/app/model/Book.java index 17cdc5c..7586ff6 100644 --- a/src/main/java/ru/otus/mkulikov/app/model/Book.java +++ b/src/main/java/ru/otus/mkulikov/app/model/Book.java @@ -42,6 +42,7 @@ public class Book { @ManyToOne(optional=false, fetch = FetchType.EAGER) private Genre genre; + @Fetch(FetchMode.JOIN) @OneToMany(mappedBy = "book", fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private List comments; @@ -83,6 +84,7 @@ public String toString() { ", description=" + description + ", author=" + author + ", genre=" + genre + + ", comments=" + (comments != null ? comments : "none") + "}\n"; } } From 1abe9cc10180d29c8b2bfa62df094b691c2bf4af Mon Sep 17 00:00:00 2001 From: Maksim Kulikov Date: Mon, 19 Aug 2019 11:01:44 +0300 Subject: [PATCH 30/30] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e5a364a..0a53118 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,14 @@ - Добавить комментарии к книгам, и высокоуровневые сервисы, оставляющие комментарии к книгам. - Покрыть DAO тестами используя H2 базу данных и соответствующий H2 Hibernate-диалект. -### 19-09-19 Доработки: +### 19-06-19 Доработки: - Добавлены названия тэстов. - Связи OneToOne изменены на ManyToOne. -### 19-09-20 Доработки: +### 19-06-20 Доработки: - Изменена струкрура запроса для сущности Book. -### 19-09-22 Доработки: +### 19-06-22 Доработки: - Добавлена сущность Comment. - Изменение механизма добавления/обновления сущностей. -- Добавление классов для обработки сущности Comment и покрытие тестами. \ No newline at end of file +- Добавление классов для обработки сущности Comment и покрытие тестами.