From 50d78263044ded1c694a283188c3a8d8b7866a95 Mon Sep 17 00:00:00 2001 From: Retro Date: Mon, 18 Sep 2017 22:56:16 +0300 Subject: [PATCH 1/6] create prototype with H2 --- core/LvivTest/.gitignore | 27 +++ core/LvivTest/build.gradle | 37 ++++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54711 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + core/LvivTest/gradlew | 172 ++++++++++++++++++ core/LvivTest/gradlew.bat | 84 +++++++++ .../lviv/testlviv/TestLvivApplication.java | 16 ++ .../test/lviv/testlviv/entity/Book.java | 20 ++ .../test/lviv/testlviv/entity/Isbn.java | 16 ++ .../testlviv/repository/BookRepository.java | 11 ++ .../repository/impls/BookRepositoryImpl.java | 117 ++++++++++++ .../src/main/resources/application.properties | 6 + core/LvivTest/src/main/resources/sql/dump.sql | 86 +++++++++ .../testlviv/TestLvivApplicationTests.java | 16 ++ 14 files changed, 614 insertions(+) create mode 100644 core/LvivTest/.gitignore create mode 100644 core/LvivTest/build.gradle create mode 100644 core/LvivTest/gradle/wrapper/gradle-wrapper.jar create mode 100644 core/LvivTest/gradle/wrapper/gradle-wrapper.properties create mode 100644 core/LvivTest/gradlew create mode 100644 core/LvivTest/gradlew.bat create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java create mode 100644 core/LvivTest/src/main/resources/application.properties create mode 100644 core/LvivTest/src/main/resources/sql/dump.sql create mode 100644 core/LvivTest/src/test/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplicationTests.java diff --git a/core/LvivTest/.gitignore b/core/LvivTest/.gitignore new file mode 100644 index 0000000..90fb021 --- /dev/null +++ b/core/LvivTest/.gitignore @@ -0,0 +1,27 @@ +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ +out/ +data/ \ No newline at end of file diff --git a/core/LvivTest/build.gradle b/core/LvivTest/build.gradle new file mode 100644 index 0000000..e88e244 --- /dev/null +++ b/core/LvivTest/build.gradle @@ -0,0 +1,37 @@ +buildscript { + ext { + springBootVersion = '1.5.7.RELEASE' + } + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + } +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'org.springframework.boot' + +group = 'edu.cherkassy.test.lviv' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + + +dependencies { + compile('org.springframework.boot:spring-boot-starter-data-elasticsearch') + compile('org.springframework.boot:spring-boot-starter-thymeleaf') + compile('org.springframework.boot:spring-boot-starter-jdbc'){ + exclude (module: "org.apache.tomcat:tomcat-jdbc") + } + runtime('org.springframework.boot:spring-boot-devtools') + runtime('com.h2database:h2') + compileOnly('org.projectlombok:lombok') + testCompile('org.springframework.boot:spring-boot-starter-test') + +} diff --git a/core/LvivTest/gradle/wrapper/gradle-wrapper.jar b/core/LvivTest/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..1a958be6420a4dd04b588fe4b31eb5d7ff8748c2 GIT binary patch literal 54711 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/core/LvivTest/gradlew.bat b/core/LvivTest/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/core/LvivTest/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java new file mode 100644 index 0000000..aaeb240 --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java @@ -0,0 +1,16 @@ +package edu.cherkassy.test.lviv.testlviv; + +import edu.cherkassy.test.lviv.testlviv.repository.impls.BookRepositoryImpl; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class TestLvivApplication { + public static void main(String[] args) { + BookRepositoryImpl repository = SpringApplication.run(TestLvivApplication.class, args).getBean(BookRepositoryImpl.class); + if (repository != null) { + System.out.println("Hello"); + repository.getAllBooks().forEach(System.out::println); + } + } +} diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java new file mode 100644 index 0000000..9ed24d0 --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java @@ -0,0 +1,20 @@ +package edu.cherkassy.test.lviv.testlviv.entity; + +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class Book { + private Integer id; + private String title; + private List authors = new ArrayList<>(); + private String publishing; + private String yearOfPublishing; + private Short numberOfPages; + private List isbnList = new ArrayList<>(); + private List categories = new ArrayList<>(); + private String description; + private Double price; +} \ No newline at end of file diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java new file mode 100644 index 0000000..8d0b64e --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java @@ -0,0 +1,16 @@ +package edu.cherkassy.test.lviv.testlviv.entity; + +import lombok.*; + +@AllArgsConstructor +@NoArgsConstructor +@ToString +@EqualsAndHashCode +public class Isbn { + @Getter @Setter private Integer isbnId; + @Getter @Setter private Integer bookId; + @Getter @Setter private String language; + @Getter @Setter private String number; + @Getter @Setter private String type; + @Getter @Setter private Boolean translation; +} \ No newline at end of file diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java new file mode 100644 index 0000000..7fc694c --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java @@ -0,0 +1,11 @@ +package edu.cherkassy.test.lviv.testlviv.repository; + +import edu.cherkassy.test.lviv.testlviv.entity.Book; +import edu.cherkassy.test.lviv.testlviv.entity.Isbn; + +import java.util.List; + +public interface BookRepository { + List getAllBooks(); + boolean addNewIsbn(Isbn isbn); +} diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java new file mode 100644 index 0000000..7b6c42b --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java @@ -0,0 +1,117 @@ +package edu.cherkassy.test.lviv.testlviv.repository.impls; + +import edu.cherkassy.test.lviv.testlviv.entity.Book; +import edu.cherkassy.test.lviv.testlviv.entity.Isbn; +import edu.cherkassy.test.lviv.testlviv.repository.BookRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCallback; +import org.springframework.stereotype.Repository; + +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Repository +public class BookRepositoryImpl implements BookRepository { + + private static final String SQL_SELECT_BOOKS = "SELECT " + + "LVIV.BOOKS.BOOKID, " + + "LVIV.BOOKS.TITLE, " + + "LVIV.BOOKS.PUBLISHING, " + + "LVIV.BOOKS.YEAROFPUBLISHING, " + + "LVIV.BOOKS.NUMBEROFPAGE, " + + "LVIV.BOOKS.PRICE, " + + "LVIV.BOOKS.DESCRIPTION " + + " FROM LVIV.BOOKS"; + + private static final String SQL_SELECT_ISBN = "SELECT" + + " LVIV.ISBN.ISBNID," + + " LVIV.ISBN.BOOKID," + + " LVIV.ISBN.NUMBER," + + " LVIV.ISBN.TYPE," + + " LVIV.ISBN.TRANSLATION," + + " LVIV.ISBN.LANGUAGE" + + " FROM LVIV.ISBN WHERE BOOKID = ?"; + + private static final String SQL_SELECT_CATEGORIES = "SELECT LVIV.CATEGORY.CATEGORY " + + "FROM LVIV.CATEGORY" + + " INNER JOIN LVIV.BOOK_CATEGORY ON LVIV.BOOK_CATEGORY.CATEGORYID = LVIV.CATEGORY.CATEGORYID" + + " INNER JOIN LVIV.BOOKS ON LVIV.BOOK_CATEGORY.BOOKID = LVIV.BOOKS.BOOKID " + + "WHERE LVIV.BOOKS.BOOKID = ?"; + + private static final String SQL_SELECT_AUTHORS = "SELECT LVIV.AUTHORS.NAME " + + "FROM LVIV.AUTHORS" + + " INNER JOIN LVIV.AUTHOR_BOOK ON LVIV.AUTHOR_BOOK.AUTHORID = LVIV.AUTHORS.AUTHORID" + + " INNER JOIN LVIV.BOOKS ON LVIV.AUTHOR_BOOK.BOOKID = LVIV.BOOKS.BOOKID " + + "WHERE LVIV.BOOKS.BOOKID = ?"; + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public BookRepositoryImpl(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public List getAllBooks() { + List books = this.getBooks(); + books.forEach(book -> book.setIsbnList(this.getListIsbnsOfBook(book.getId()))); + books.forEach(book -> book.setCategories(this.getBookStringAttributes(book.getId(), SQL_SELECT_CATEGORIES, "CATEGORY"))); + books.forEach(book -> book.setAuthors(this.getBookStringAttributes(book.getId(), SQL_SELECT_AUTHORS, "NAME"))); + return books; + } + + @Override + public boolean addNewIsbn(Isbn isbn) { + return false; + } + + private List getBooks() { + List result = new ArrayList<>(); + for (Map row : this.jdbcTemplate.queryForList(SQL_SELECT_BOOKS)) { + Book book = new Book(); + book.setId((Integer) row.get("BOOKID")); + book.setTitle((String) row.get("TITLE")); + book.setPublishing((String) row.get("PUBLISHING")); + book.setYearOfPublishing((String) row.get("YEAROFPUBLISHING")); + book.setNumberOfPages((Short) row.get("NUMBEROFPAGE")); + book.setPrice((Double) row.get("PRICE")); + book.setDescription((String) row.get("DESCRIPTION")); + result.add(book); + } + return result; + } + + private List getListIsbnsOfBook(Integer bookId) { + List isbns = new ArrayList<>(); + return this.jdbcTemplate.execute(SQL_SELECT_ISBN, (PreparedStatementCallback>) ps -> { + ps.setInt(1, bookId); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + Isbn isbn = new Isbn(); + isbn.setIsbnId(rs.getInt("ISBNID")); + isbn.setBookId(rs.getInt("BOOKID")); + isbn.setNumber(rs.getString("NUMBER")); + isbn.setType(rs.getString("TYPE")); + isbn.setTranslation(rs.getBoolean("TRANSLATION")); + isbn.setLanguage(rs.getString("LANGUAGE")); + isbns.add(isbn); + } + return isbns; + }); + } + + private List getBookStringAttributes(Integer bookId, String query, String titleOfColumn) { + List resultOfQuery = new ArrayList<>(); + return this.jdbcTemplate.execute(query, (PreparedStatementCallback>) ps -> { + ps.setInt(1, bookId); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + resultOfQuery.add(rs.getString(titleOfColumn)); + } + return resultOfQuery; + }); + } +} \ No newline at end of file diff --git a/core/LvivTest/src/main/resources/application.properties b/core/LvivTest/src/main/resources/application.properties new file mode 100644 index 0000000..42ee1f4 --- /dev/null +++ b/core/LvivTest/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.datasource.url=jdbc:h2:tcp://localhost:9092/LVIV +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=root +spring.datasource.password=1 +spring.h2.console.enabled=true +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration \ No newline at end of file diff --git a/core/LvivTest/src/main/resources/sql/dump.sql b/core/LvivTest/src/main/resources/sql/dump.sql new file mode 100644 index 0000000..2cce21e --- /dev/null +++ b/core/LvivTest/src/main/resources/sql/dump.sql @@ -0,0 +1,86 @@ +; +CREATE USER IF NOT EXISTS "" SALT '' HASH '' ADMIN; +CREATE USER IF NOT EXISTS ROOT SALT 'eed89a9e45cbe153' HASH 'dfeff67a44c88dab302d3e71eb033b27bc51b94f6c81b579c61ede552d507009' ADMIN; +CREATE SCHEMA IF NOT EXISTS LVIV AUTHORIZATION ""; +CREATE SEQUENCE LVIV.SYSTEM_SEQUENCE_4740355A_BFAE_4F1E_B9C6_80DEDD87C244 START WITH 1 BELONGS_TO_TABLE; +CREATE SEQUENCE LVIV.SYSTEM_SEQUENCE_2A08AEDE_51B4_4418_887D_8D84F9F20848 START WITH 3 BELONGS_TO_TABLE; +CREATE SEQUENCE LVIV.SYSTEM_SEQUENCE_7673572B_E411_4639_87AE_55A3D08B9944 START WITH 5 BELONGS_TO_TABLE; +CREATE SEQUENCE LVIV.SYSTEM_SEQUENCE_DE11B891_CF74_4124_AFA7_2C7498078821 START WITH 4 BELONGS_TO_TABLE; +CREATE SEQUENCE LVIV.SYSTEM_SEQUENCE_6978E8A1_ACF5_4DA3_8875_EEBD229642E0 START WITH 5 BELONGS_TO_TABLE; + +CREATE CACHED TABLE LVIV.AUTHOR_BOOK( + AUTHORID INT NOT NULL, + BOOKID INT NOT NULL +); +-- 3 +/- SELECT COUNT(*) FROM LVIV.AUTHOR_BOOK; +INSERT INTO LVIV.AUTHOR_BOOK(AUTHORID, BOOKID) VALUES +(1, 1), +(2, 2), +(3, 2); +CREATE CACHED TABLE LVIV.AUTHORS( + AUTHORID INT DEFAULT (NEXT VALUE FOR LVIV.SYSTEM_SEQUENCE_DE11B891_CF74_4124_AFA7_2C7498078821) NOT NULL NULL_TO_DEFAULT SEQUENCE LVIV.SYSTEM_SEQUENCE_DE11B891_CF74_4124_AFA7_2C7498078821, + NAME VARCHAR(255) NOT NULL +); +ALTER TABLE LVIV.AUTHORS ADD CONSTRAINT LVIV.CONSTRAINT_4 PRIMARY KEY(AUTHORID); +-- 3 +/- SELECT COUNT(*) FROM LVIV.AUTHORS; +INSERT INTO LVIV.AUTHORS(AUTHORID, NAME) VALUES +(1, 'Alan Beaulieu'), +(2, 'Scott Chacon'), +(3, 'Ben Straub'); +CREATE UNIQUE INDEX LVIV.AUTHORS_NAME_UINDEX ON LVIV.AUTHORS(NAME); +CREATE CACHED TABLE LVIV.CATEGORY( + CATEGORYID INT DEFAULT (NEXT VALUE FOR LVIV.SYSTEM_SEQUENCE_7673572B_E411_4639_87AE_55A3D08B9944) NOT NULL NULL_TO_DEFAULT SEQUENCE LVIV.SYSTEM_SEQUENCE_7673572B_E411_4639_87AE_55A3D08B9944, + CATEGORY VARCHAR(255) NOT NULL +); +ALTER TABLE LVIV.CATEGORY ADD CONSTRAINT LVIV.CONSTRAINT_31 PRIMARY KEY(CATEGORYID); +-- 4 +/- SELECT COUNT(*) FROM LVIV.CATEGORY; +INSERT INTO LVIV.CATEGORY(CATEGORYID, CATEGORY) VALUES +(1, 'SQL'), +(2, 'Relational DB'), +(3, 'Git'), +(4, 'VCS'); +CREATE UNIQUE INDEX LVIV.CATEGORY_CATEGORY_UINDEX ON LVIV.CATEGORY(CATEGORY); +CREATE CACHED TABLE LVIV.ISBN( + ISBNID INT DEFAULT (NEXT VALUE FOR LVIV.SYSTEM_SEQUENCE_6978E8A1_ACF5_4DA3_8875_EEBD229642E0) NOT NULL NULL_TO_DEFAULT SEQUENCE LVIV.SYSTEM_SEQUENCE_6978E8A1_ACF5_4DA3_8875_EEBD229642E0, + BOOKID INT NOT NULL, + LANGUAGE CHAR(4) NOT NULL, + NUMBER VARCHAR(13) NOT NULL, + TYPE CHAR(2) NOT NULL, + TRANSLATION BOOLEAN NOT NULL +); +ALTER TABLE LVIV.ISBN ADD CONSTRAINT LVIV.CONSTRAINT_2 PRIMARY KEY(ISBNID); +-- 4 +/- SELECT COUNT(*) FROM LVIV.ISBN; +INSERT INTO LVIV.ISBN(ISBNID, BOOKID, LANGUAGE, NUMBER, TYPE, TRANSLATION) VALUES +(1, 1, 'UA', '9785496017633', '13', TRUE), +(2, 1, 'EN', '9781484200773', '13', FALSE), +(3, 2, 'RU', '9785496017633', '13', TRUE), +(4, 2, 'EN', '9781484200733', '13', FALSE); +CREATE CACHED TABLE LVIV.BOOK_CATEGORY( + BOOKID INT NOT NULL, + CATEGORYID INT NOT NULL +); +-- 4 +/- SELECT COUNT(*) FROM LVIV.BOOK_CATEGORY; +INSERT INTO LVIV.BOOK_CATEGORY(BOOKID, CATEGORYID) VALUES +(1, 1), +(1, 2), +(2, 3), +(2, 4); +CREATE CACHED TABLE LVIV.BOOKS( + BOOKID INT DEFAULT (NEXT VALUE FOR LVIV.SYSTEM_SEQUENCE_2A08AEDE_51B4_4418_887D_8D84F9F20848) NOT NULL NULL_TO_DEFAULT SEQUENCE LVIV.SYSTEM_SEQUENCE_2A08AEDE_51B4_4418_887D_8D84F9F20848, + TITLE VARCHAR(255) NOT NULL, + PUBLISHING VARCHAR(255) NOT NULL, + YEAROFPUBLISHING VARCHAR(4) NOT NULL, + NUMBEROFPAGE SMALLINT NOT NULL, + PRICE DOUBLE NOT NULL, + DESCRIPTION TEXT +); +ALTER TABLE LVIV.BOOKS ADD CONSTRAINT LVIV.CONSTRAINT_3 PRIMARY KEY(BOOKID); +-- 2 +/- SELECT COUNT(*) FROM LVIV.BOOKS; +INSERT INTO LVIV.BOOKS(BOOKID, TITLE, PUBLISHING, YEAROFPUBLISHING, NUMBEROFPAGE, PRICE, DESCRIPTION) VALUES +(1, 'Learn SQL', 'O''Relly', '2007', 310, 100.0, STRINGDECODE('\u041a\u043d\u0438\u0433\u0430 \u0410\u043b\u0430\u043d\u0430 \u0411\u044c\u044e\u043b\u0438, \u044d\u043a\u0441\u043f\u0435\u0440\u0442\u0430 \u043f\u043e \u044f\u0437\u044b\u043a\u0443 SQL, - \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0443\u0447\u0435\u0431\u043d\u0438\u043a \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0435\u0449\u0435 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u043d\u043e \u0445\u043e\u0447\u0435\u0442 \u043e\u0441\u0432\u043e\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u044f\u0437\u044b\u043a. \u041a\u043d\u0438\u0433\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0441\u0442\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f, \u043d\u043e \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442 \u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0443\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u043c\u044b\u0445 \u043c\u043e\u0449\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u0445 \u044f\u0437\u044b\u043a\u0430 SQL, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043e\u043f\u044b\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c\u0438.')), +(2, STRINGDECODE('Git \u0434\u043b\u044f \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430'), STRINGDECODE('\u041f\u0438\u0442\u0435\u0440'), '2016', 496, 212.45, STRINGDECODE('\u042d\u0442\u0430 \u043a\u043d\u0438\u0433\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e Git \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445. \u0421 \u0442\u0435\u0445 \u043f\u043e\u0440 \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442 Git \u2014 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 \u2014 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u041b\u0438\u043d\u0443\u0441\u043e\u043c \u0422\u043e\u0440\u0432\u0430\u043b\u044c\u0434\u0441\u043e\u043c, \u043f\u0440\u043e\u0448\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u043b\u0435\u0442, \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 Git \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u0434\u043e\u043c\u0438\u043d\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0439, \u043a\u0430\u043a \u0434\u043b\u044f \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0445 \u0446\u0435\u043b\u0435\u0439, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c')); +ALTER TABLE LVIV.AUTHOR_BOOK ADD CONSTRAINT LVIV.AUTHOR_BOOK_BOOKS_BOOKID_FK FOREIGN KEY(BOOKID) REFERENCES LVIV.BOOKS(BOOKID) NOCHECK; +ALTER TABLE LVIV.BOOK_CATEGORY ADD CONSTRAINT LVIV.BOOK_CATEGORY_CATEGORY_CATEGORYID_FK FOREIGN KEY(CATEGORYID) REFERENCES LVIV.CATEGORY(CATEGORYID) NOCHECK; +ALTER TABLE LVIV.BOOK_CATEGORY ADD CONSTRAINT LVIV.BOOK_CATEGORY_BOOKS_BOOKID_FK FOREIGN KEY(BOOKID) REFERENCES LVIV.BOOKS(BOOKID) NOCHECK; +ALTER TABLE LVIV.AUTHOR_BOOK ADD CONSTRAINT LVIV.AUTHOR_BOOK_AUTHORS_AUTHORID_FK FOREIGN KEY(AUTHORID) REFERENCES LVIV.AUTHORS(AUTHORID) NOCHECK; +ALTER TABLE LVIV.ISBN ADD CONSTRAINT LVIV.ISBN_BOOKS_BOOKID_FK FOREIGN KEY(BOOKID) REFERENCES LVIV.BOOKS(BOOKID) NOCHECK; diff --git a/core/LvivTest/src/test/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplicationTests.java b/core/LvivTest/src/test/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplicationTests.java new file mode 100644 index 0000000..775f019 --- /dev/null +++ b/core/LvivTest/src/test/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplicationTests.java @@ -0,0 +1,16 @@ +package edu.cherkassy.test.lviv.testlviv; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class TestLvivApplicationTests { + + @Test + public void contextLoads() { + } + +} From 95a5149a50ce619c2def15ef1bff41bc7e20587e Mon Sep 17 00:00:00 2001 From: Retro Date: Wed, 20 Sep 2017 16:05:38 +0300 Subject: [PATCH 2/6] applied @Data for entity Isbn, add and implemented method to BookRepository: getBookById() --- .../lviv/testlviv/TestLvivApplication.java | 11 ++++++-- .../test/lviv/testlviv/entity/Book.java | 2 +- .../test/lviv/testlviv/entity/Isbn.java | 17 +++++------- .../testlviv/repository/BookRepository.java | 1 + .../repository/impls/BookRepositoryImpl.java | 27 +++++++++++++++++++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java index aaeb240..6c6781b 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java @@ -7,10 +7,17 @@ @SpringBootApplication public class TestLvivApplication { public static void main(String[] args) { - BookRepositoryImpl repository = SpringApplication.run(TestLvivApplication.class, args).getBean(BookRepositoryImpl.class); + BookRepositoryImpl repository = SpringApplication + .run(TestLvivApplication.class, args) + .getBean(BookRepositoryImpl.class); + if (repository != null) { - System.out.println("Hello"); + System.out.println("\n*****TEST getAllBooks() method: ******"); repository.getAllBooks().forEach(System.out::println); + + System.out.println("\n*****TEST getBookById() method: *****"); + System.out.println(repository.getBookById(2)); + System.out.println(repository.getBookById(1)); } } } diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java index 9ed24d0..98d856b 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java @@ -1,6 +1,6 @@ package edu.cherkassy.test.lviv.testlviv.entity; -import lombok.*; +import lombok.Data; import java.util.ArrayList; import java.util.List; diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java index 8d0b64e..c5b0ff3 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java @@ -2,15 +2,12 @@ import lombok.*; -@AllArgsConstructor -@NoArgsConstructor -@ToString -@EqualsAndHashCode +@Data public class Isbn { - @Getter @Setter private Integer isbnId; - @Getter @Setter private Integer bookId; - @Getter @Setter private String language; - @Getter @Setter private String number; - @Getter @Setter private String type; - @Getter @Setter private Boolean translation; + private Integer isbnId; + private Integer bookId; + private String language; + private String number; + private String type; + private Boolean translation; } \ No newline at end of file diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java index 7fc694c..d203f33 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java @@ -7,5 +7,6 @@ public interface BookRepository { List getAllBooks(); + Book getBookById(Integer bookId); boolean addNewIsbn(Isbn isbn); } diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java index 7b6c42b..538ae78 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java @@ -47,6 +47,8 @@ public class BookRepositoryImpl implements BookRepository { " INNER JOIN LVIV.BOOKS ON LVIV.AUTHOR_BOOK.BOOKID = LVIV.BOOKS.BOOKID " + "WHERE LVIV.BOOKS.BOOKID = ?"; + private static final String SQL_SELECT_BOOK_BY_ID = SQL_SELECT_BOOKS + " WHERE LVIV.BOOKS.BOOKID = ?"; + private final JdbcTemplate jdbcTemplate; @Autowired @@ -63,11 +65,36 @@ public List getAllBooks() { return books; } + @Override + public Book getBookById(Integer bookId) { + Book book = this.getBook(bookId); + book.setIsbnList(this.getListIsbnsOfBook(bookId)); + book.setCategories(this.getBookStringAttributes(bookId, SQL_SELECT_CATEGORIES, "CATEGORY")); + book.setAuthors(this.getBookStringAttributes(bookId, SQL_SELECT_AUTHORS, "NAME")); + return book; + } + @Override public boolean addNewIsbn(Isbn isbn) { return false; } + private Book getBook(Integer bookId) { + return this.jdbcTemplate.queryForObject(SQL_SELECT_BOOK_BY_ID, + new Object[]{bookId}, + (rs, rowNum) -> { + Book book = new Book(); + book.setId(rs.getInt("BOOKID")); + book.setTitle(rs.getString("TITLE")); + book.setPublishing(rs.getString("PUBLISHING")); + book.setYearOfPublishing(rs.getString("YEAROFPUBLISHING")); + book.setNumberOfPages(rs.getShort("NUMBEROFPAGE")); + book.setPrice(rs.getDouble("PRICE")); + book.setDescription(rs.getString("DESCRIPTION")); + return book; + }); + } + private List getBooks() { List result = new ArrayList<>(); for (Map row : this.jdbcTemplate.queryForList(SQL_SELECT_BOOKS)) { From b0729c5c9978e300073ff474bba926c44a2d2a29 Mon Sep 17 00:00:00 2001 From: Retro Date: Thu, 21 Sep 2017 17:26:54 +0300 Subject: [PATCH 3/6] rename class BookRepositoryImpl -> BookRepositoryH2DbImpl; add service layer; implement BookRepository interface; --- .../lviv/testlviv/TestLvivApplication.java | 7 +- .../test/lviv/testlviv/entity/Book.java | 4 +- .../test/lviv/testlviv/entity/Isbn.java | 2 + .../testlviv/repository/BookRepository.java | 3 +- ...yImpl.java => BookRepositoryH2DbImpl.java} | 108 ++++++++++++++++-- .../lviv/testlviv/service/BookService.java | 13 +++ .../service/impls/BookServiceImpl.java | 42 +++++++ 7 files changed, 167 insertions(+), 12 deletions(-) rename core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/{BookRepositoryImpl.java => BookRepositoryH2DbImpl.java} (56%) create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/BookService.java create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/impls/BookServiceImpl.java diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java index 6c6781b..ab5082c 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/TestLvivApplication.java @@ -1,15 +1,16 @@ package edu.cherkassy.test.lviv.testlviv; -import edu.cherkassy.test.lviv.testlviv.repository.impls.BookRepositoryImpl; +import edu.cherkassy.test.lviv.testlviv.service.BookService; +import edu.cherkassy.test.lviv.testlviv.service.impls.BookServiceImpl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TestLvivApplication { public static void main(String[] args) { - BookRepositoryImpl repository = SpringApplication + BookService repository = SpringApplication .run(TestLvivApplication.class, args) - .getBean(BookRepositoryImpl.class); + .getBean(BookServiceImpl.class); if (repository != null) { System.out.println("\n*****TEST getAllBooks() method: ******"); diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java index 98d856b..e87e04c 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java @@ -1,11 +1,13 @@ package edu.cherkassy.test.lviv.testlviv.entity; -import lombok.Data; +import lombok.*; import java.util.ArrayList; import java.util.List; @Data +@NoArgsConstructor +@AllArgsConstructor public class Book { private Integer id; private String title; diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java index c5b0ff3..33e11b3 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java @@ -3,6 +3,8 @@ import lombok.*; @Data +@AllArgsConstructor +@NoArgsConstructor public class Isbn { private Integer isbnId; private Integer bookId; diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java index d203f33..519fb29 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/BookRepository.java @@ -8,5 +8,6 @@ public interface BookRepository { List getAllBooks(); Book getBookById(Integer bookId); - boolean addNewIsbn(Isbn isbn); + int addNewIsbn(Isbn isbn); + int addNewBook(Book book); } diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java similarity index 56% rename from core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java rename to core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java index 538ae78..58c41ef 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryImpl.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java @@ -6,15 +6,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCallback; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; +import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.sql.Statement; +import java.util.*; @Repository -public class BookRepositoryImpl implements BookRepository { +public class BookRepositoryH2DbImpl implements BookRepository { private static final String SQL_SELECT_BOOKS = "SELECT " + "LVIV.BOOKS.BOOKID, " + @@ -49,10 +51,30 @@ public class BookRepositoryImpl implements BookRepository { private static final String SQL_SELECT_BOOK_BY_ID = SQL_SELECT_BOOKS + " WHERE LVIV.BOOKS.BOOKID = ?"; + private static final String SQL_INSERT_BOOK = "INSERT INTO LVIV.BOOKS " + + "(BOOKID ,TITLE, PUBLISHING, YEAROFPUBLISHING, NUMBEROFPAGE, PRICE, DESCRIPTION) " + + "VALUES (DEFAULT ,?, ?, ?, ?, ?, ?)"; + + private static final String SQL_INSERT_ISBN = "INSERT INTO LVIV.ISBN " + + "(ISBNID, BOOKID, LANGUAGE, NUMBER, TYPE, TRANSLATION) " + + "VALUES (DEFAULT, ?, ?, ?, ?, ?)"; + + private static final String SQL_INSERT_CATEGORY = "INSERT INTO LVIV.CATEGORY " + + " (CATEGORYID, CATEGORY) VALUES (DEFAULT , ?)"; + + private static final String SQL_INSERT_AUTHORS = "INSERT INTO LVIV.AUTHORS" + + " (AUTHORID, NAME) VALUES (DEFAULT , ?)"; + + private static final String SQL_INSERT_BOOK_CATEGORY = "INSERT INTO LVIV.BOOK_CATEGORY " + + "(BOOKID, CATEGORYID) VALUES (?, ?)"; + + private static final String SQL_INSERT_AUTHOR_BOOK = "INSERT INTO LVIV.AUTHOR_BOOK " + + "(BOOKID, AUTHORID) VALUES (?, ?)"; + private final JdbcTemplate jdbcTemplate; @Autowired - public BookRepositoryImpl(JdbcTemplate jdbcTemplate) { + public BookRepositoryH2DbImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @@ -75,8 +97,80 @@ public Book getBookById(Integer bookId) { } @Override - public boolean addNewIsbn(Isbn isbn) { - return false; + public int addNewIsbn(Isbn isbn) { + return this.addIsbns(Collections.singletonList(isbn)); + } + + @Override + public int addNewBook(Book book) { + int rowAddCount = 0; + + KeyHolder holder = new GeneratedKeyHolder(); + rowAddCount += this.jdbcTemplate.update(con -> { + PreparedStatement ps = con.prepareStatement(SQL_INSERT_BOOK, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, book.getTitle()); + ps.setString(2, book.getPublishing()); + ps.setString(3, book.getYearOfPublishing()); + ps.setShort(4, book.getNumberOfPages()); + ps.setDouble(5, book.getPrice()); + ps.setString(6, book.getDescription()); + return ps; + }, holder); + + Integer generatedId = holder.getKey().intValue(); + book.setId(generatedId); + book.getIsbnList().forEach(isbn -> isbn.setBookId(generatedId)); + + rowAddCount += this.addIsbns(book.getIsbnList()); + HashMap> attrs = new HashMap<>(); + attrs.put("CATEGORIES", book.getCategories()); + attrs.put("NAME", book.getAuthors()); + + rowAddCount += this.addStringsAttributesToBook(attrs, book.getId()); + + return rowAddCount; + } + + private int addIsbns(List isbns) { + int addedRows = 0; + for (Isbn isbn : isbns) { + addedRows += this.jdbcTemplate.update(SQL_INSERT_ISBN, + isbn.getBookId(), + isbn.getLanguage(), + isbn.getNumber(), + isbn.getType(), + isbn.getTranslation()); + } + return addedRows; + } + + private int addStringsAttributesToBook(Map> attributes, Integer bookId) { + int rowAddCount = 0; + for (Map.Entry> entry : attributes.entrySet()) { + if (entry.getKey().equals("CATEGORIES")) { + for (String attribute : entry.getValue()) { + rowAddCount += fillIntermediateTable(attribute, SQL_INSERT_CATEGORY, SQL_INSERT_BOOK_CATEGORY, bookId); + } + } else if (entry.getKey().equals("NAME")) { + for (String attribute : entry.getValue()) { + rowAddCount += fillIntermediateTable(attribute, SQL_INSERT_AUTHORS, SQL_INSERT_AUTHOR_BOOK, bookId); + } + } + } + return rowAddCount; + } + + private int fillIntermediateTable(String attr, String insertAttribute, String insertIntermediateTable, Integer bookId) { + int rowAddCount = 0; + KeyHolder holder = new GeneratedKeyHolder(); + rowAddCount += this.jdbcTemplate.update(con -> { + PreparedStatement ps = con.prepareStatement(insertAttribute, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, attr); + return ps; + }, holder); + Long attrId = holder.getKey().longValue(); + rowAddCount += this.jdbcTemplate.update(insertIntermediateTable, bookId, attrId); + return rowAddCount; } private Book getBook(Integer bookId) { diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/BookService.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/BookService.java new file mode 100644 index 0000000..2a1cbb1 --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/BookService.java @@ -0,0 +1,13 @@ +package edu.cherkassy.test.lviv.testlviv.service; + +import edu.cherkassy.test.lviv.testlviv.entity.Book; +import edu.cherkassy.test.lviv.testlviv.entity.Isbn; + +import java.util.List; + +public interface BookService { + List getAllBooks(); + Book getBookById(Integer bookId); + int addNewIsbn(Isbn isbn); + int addNewBook(Book book); +} diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/impls/BookServiceImpl.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/impls/BookServiceImpl.java new file mode 100644 index 0000000..e565b97 --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/service/impls/BookServiceImpl.java @@ -0,0 +1,42 @@ +package edu.cherkassy.test.lviv.testlviv.service.impls; + +import edu.cherkassy.test.lviv.testlviv.entity.Book; +import edu.cherkassy.test.lviv.testlviv.entity.Isbn; +import edu.cherkassy.test.lviv.testlviv.repository.BookRepository; +import edu.cherkassy.test.lviv.testlviv.service.BookService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BookServiceImpl implements BookService { + + private BookRepository bookRepository; + + @Autowired + public BookServiceImpl(BookRepository bookRepository) { + this.bookRepository = bookRepository; + } + + + @Override + public List getAllBooks() { + return bookRepository.getAllBooks(); + } + + @Override + public Book getBookById(Integer bookId) { + return bookRepository.getBookById(bookId); + } + + @Override + public int addNewIsbn(Isbn isbn) { + return bookRepository.addNewIsbn(isbn); + } + + @Override + public int addNewBook(Book book) { + return bookRepository.addNewBook(book); + } +} From 42300adcbeb33d723893aed6b34537373e17ddd1 Mon Sep 17 00:00:00 2001 From: Retro Date: Thu, 21 Sep 2017 23:00:07 +0300 Subject: [PATCH 4/6] add resultSetExtractor methods to Book and Isbn entity, applied resultSetExtractor in to BookRepositoryH2DbImpl --- .../test/lviv/testlviv/entity/Book.java | 13 ++++++ .../test/lviv/testlviv/entity/Isbn.java | 13 ++++++ .../impls/BookRepositoryH2DbImpl.java | 41 ++++--------------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java index e87e04c..d4fabbc 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Book.java @@ -2,6 +2,8 @@ import lombok.*; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -19,4 +21,15 @@ public class Book { private List categories = new ArrayList<>(); private String description; private Double price; + + public static Book resultSetExtractor(ResultSet rs, Book book) throws SQLException { + book.setId(rs.getInt("BOOKID")); + book.setTitle(rs.getString("TITLE")); + book.setPublishing(rs.getString("PUBLISHING")); + book.setYearOfPublishing(rs.getString("YEAROFPUBLISHING")); + book.setNumberOfPages(rs.getShort("NUMBEROFPAGE")); + book.setPrice(rs.getDouble("PRICE")); + book.setDescription(rs.getString("DESCRIPTION")); + return book; + } } \ No newline at end of file diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java index 33e11b3..9cb30aa 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/entity/Isbn.java @@ -2,6 +2,9 @@ import lombok.*; +import java.sql.ResultSet; +import java.sql.SQLException; + @Data @AllArgsConstructor @NoArgsConstructor @@ -12,4 +15,14 @@ public class Isbn { private String number; private String type; private Boolean translation; + + public static Isbn resultSetExtractor(ResultSet rs, Isbn isbn) throws SQLException { + isbn.setIsbnId(rs.getInt("ISBNID")); + isbn.setBookId(rs.getInt("BOOKID")); + isbn.setNumber(rs.getString("NUMBER")); + isbn.setType(rs.getString("TYPE")); + isbn.setTranslation(rs.getBoolean("TRANSLATION")); + isbn.setLanguage(rs.getString("LANGUAGE")); + return isbn; + } } \ No newline at end of file diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java index 58c41ef..30a3f19 100644 --- a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/repository/impls/BookRepositoryH2DbImpl.java @@ -176,33 +176,17 @@ private int fillIntermediateTable(String attr, String insertAttribute, String in private Book getBook(Integer bookId) { return this.jdbcTemplate.queryForObject(SQL_SELECT_BOOK_BY_ID, new Object[]{bookId}, - (rs, rowNum) -> { - Book book = new Book(); - book.setId(rs.getInt("BOOKID")); - book.setTitle(rs.getString("TITLE")); - book.setPublishing(rs.getString("PUBLISHING")); - book.setYearOfPublishing(rs.getString("YEAROFPUBLISHING")); - book.setNumberOfPages(rs.getShort("NUMBEROFPAGE")); - book.setPrice(rs.getDouble("PRICE")); - book.setDescription(rs.getString("DESCRIPTION")); - return book; - }); + (rs, rowNum) -> Book.resultSetExtractor(rs, new Book())); } private List getBooks() { - List result = new ArrayList<>(); - for (Map row : this.jdbcTemplate.queryForList(SQL_SELECT_BOOKS)) { - Book book = new Book(); - book.setId((Integer) row.get("BOOKID")); - book.setTitle((String) row.get("TITLE")); - book.setPublishing((String) row.get("PUBLISHING")); - book.setYearOfPublishing((String) row.get("YEAROFPUBLISHING")); - book.setNumberOfPages((Short) row.get("NUMBEROFPAGE")); - book.setPrice((Double) row.get("PRICE")); - book.setDescription((String) row.get("DESCRIPTION")); - result.add(book); - } - return result; + return jdbcTemplate.query(SQL_SELECT_BOOKS, rs -> { + List result = new ArrayList<>(); + while (rs.next()) { + result.add(Book.resultSetExtractor(rs, new Book())); + } + return result; + }); } private List getListIsbnsOfBook(Integer bookId) { @@ -211,14 +195,7 @@ private List getListIsbnsOfBook(Integer bookId) { ps.setInt(1, bookId); ResultSet rs = ps.executeQuery(); while (rs.next()) { - Isbn isbn = new Isbn(); - isbn.setIsbnId(rs.getInt("ISBNID")); - isbn.setBookId(rs.getInt("BOOKID")); - isbn.setNumber(rs.getString("NUMBER")); - isbn.setType(rs.getString("TYPE")); - isbn.setTranslation(rs.getBoolean("TRANSLATION")); - isbn.setLanguage(rs.getString("LANGUAGE")); - isbns.add(isbn); + isbns.add(Isbn.resultSetExtractor(rs, new Isbn())); } return isbns; }); From 0b3d6968281ac245c4125cc4d58f63b3b6905118 Mon Sep 17 00:00:00 2001 From: oleksandrm Date: Sun, 24 Sep 2017 00:13:57 +0300 Subject: [PATCH 5/6] Updated gradlew version from 3.5.1 to 4.2. --- .../gradle/wrapper/gradle-wrapper.jar | Bin 54711 -> 54708 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 ++--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/LvivTest/gradle/wrapper/gradle-wrapper.jar b/core/LvivTest/gradle/wrapper/gradle-wrapper.jar index 1a958be6420a4dd04b588fe4b31eb5d7ff8748c2..736fb7d3f94c051b359fc7ae7212d351bc094bdd 100644 GIT binary patch delta 4381 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 EA7-m=qyPW_ diff --git a/core/LvivTest/gradle/wrapper/gradle-wrapper.properties b/core/LvivTest/gradle/wrapper/gradle-wrapper.properties index 3b83013..6109d5b 100644 --- a/core/LvivTest/gradle/wrapper/gradle-wrapper.properties +++ b/core/LvivTest/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sun Sep 17 21:36:40 EEST 2017 +distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5.1-all.zip +zipStoreBase=GRADLE_USER_HOME From d65de74357da224675db5357da1247116abf0eac Mon Sep 17 00:00:00 2001 From: Retro Date: Mon, 25 Sep 2017 20:23:49 +0300 Subject: [PATCH 6/6] add BookController --- .../testlviv/controllers/BookController.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/controllers/BookController.java diff --git a/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/controllers/BookController.java b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/controllers/BookController.java new file mode 100644 index 0000000..6e91faf --- /dev/null +++ b/core/LvivTest/src/main/java/edu/cherkassy/test/lviv/testlviv/controllers/BookController.java @@ -0,0 +1,44 @@ +package edu.cherkassy.test.lviv.testlviv.controllers; + +import edu.cherkassy.test.lviv.testlviv.entity.Book; +import edu.cherkassy.test.lviv.testlviv.entity.Isbn; +import edu.cherkassy.test.lviv.testlviv.service.BookService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/lviv/books") +public class BookController { + + private BookService bookService; + + @Autowired + public BookController(BookService bookService) { + this.bookService = bookService; + } + + @GetMapping() + public List getAllBooks() { + return this.bookService.getAllBooks(); + } + + @GetMapping("/{bookId}") + public Book getBookById(@PathVariable Integer bookId) { + return this.bookService.getBookById(bookId); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public void addNewBook(@RequestBody Book book) { + this.bookService.addNewBook(book); + } + + @PostMapping("/isbn") + @ResponseStatus(HttpStatus.CREATED) + public void addNewIsbn(@RequestBody Isbn isbn) { + this.bookService.addNewIsbn(isbn); + } +} \ No newline at end of file