From e8716d65f7a05b02539ad8d9d1eed8d677bb3096 Mon Sep 17 00:00:00 2001 From: stvort Date: Thu, 7 Nov 2024 21:17:32 +0400 Subject: [PATCH] 2024-09 spring-10-orm added --- .../src/main/resources/application.yml | 12 +- .../src/main/resources/schema.sql | 1 - .../otus/spring/dao/PersonDaoJdbc2Test.java | 88 ++++++++++++++ .../src/test/resources/application.yml | 8 +- .../spring-10-orm/demo-projects/.gitignore | 4 + .../demo-projects/mybatis-demo/.gitignore | 29 +++++ .../demo-projects/mybatis-demo/README.md | 2 + .../demo-projects/mybatis-demo/pom.xml | 70 +++++++++++ .../mybatisdemo/MyBatisDemoApplication.java | 14 +++ .../example/mybatisdemo/models/Avatar.java | 13 +++ .../example/mybatisdemo/models/Course.java | 13 +++ .../example/mybatisdemo/models/EMail.java | 13 +++ .../mybatisdemo/models/OtusStudent.java | 18 +++ .../repositories/AvatarRepository.java | 18 +++ .../repositories/CourseRepository.java | 17 +++ .../repositories/EmailRepository.java | 14 +++ .../repositories/OtusStudentRepository.java | 42 +++++++ .../src/main/resources/schema.sql | 31 +++++ .../OtusStudentRepositoryTest.java | 110 ++++++++++++++++++ .../src/test/resources/application.yml | 8 ++ .../mybatis-demo/src/test/resources/data.sql | 29 +++++ 2024-09/spring-10-orm/demo-projects/pom.xml | 18 +++ .../demo-projects/spring-jdbc-demo/.gitignore | 29 +++++ .../demo-projects/spring-jdbc-demo/README.md | 2 + .../demo-projects/spring-jdbc-demo/pom.xml | 66 +++++++++++ .../SpringJdbcDemoApplication.java | 13 +++ .../example/springjdbcdemo/models/Avatar.java | 13 +++ .../example/springjdbcdemo/models/Course.java | 13 +++ .../example/springjdbcdemo/models/EMail.java | 13 +++ .../springjdbcdemo/models/OtusStudent.java | 18 +++ .../repositories/CourseRepository.java | 9 ++ .../repositories/CourseRepositoryJdbc.java | 35 ++++++ .../repositories/OtusStudentRepository.java | 9 ++ .../OtusStudentRepositoryJdbc.java | 52 +++++++++ .../ext/OtusStudentResultSetExtractor.java | 37 ++++++ .../ext/StudentCourseRelation.java | 11 ++ .../src/main/resources/schema.sql | 31 +++++ .../OtusStudentRepositoryJdbcTest.java | 35 ++++++ .../src/test/resources/application.yml | 4 + .../src/test/resources/data.sql | 29 +++++ .../spring-jpa-ineritance-demo/.gitignore | 29 +++++ .../spring-jpa-ineritance-demo/README.md | 2 + .../spring-jpa-ineritance-demo/pom.xml | 65 +++++++++++ .../ineritancedemo/InheritanceDemo.java | 43 +++++++ .../otus/example/ineritancedemo/model/A.java | 45 +++++++ .../otus/example/ineritancedemo/model/B.java | 28 +++++ .../otus/example/ineritancedemo/model/C.java | 31 +++++ .../repository/ARepository.java | 10 ++ .../repository/ARepositoryJpa.java | 32 +++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-exercise/.gitignore | 29 +++++ .../orm-class-work/orm-exercise/pom.xml | 65 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 17 +++ .../otus/example/ormdemo/models/Avatar.java | 15 +++ .../otus/example/ormdemo/models/Course.java | 15 +++ .../ru/otus/example/ormdemo/models/EMail.java | 15 +++ .../example/ormdemo/models/OtusStudent.java | 18 +++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-01/.gitignore | 29 +++++ .../orm-class-work/orm-solution-01/pom.xml | 65 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 17 +++ .../otus/example/ormdemo/models/Avatar.java | 17 +++ .../otus/example/ormdemo/models/Course.java | 17 +++ .../ru/otus/example/ormdemo/models/EMail.java | 17 +++ .../example/ormdemo/models/OtusStudent.java | 23 ++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-02/.gitignore | 29 +++++ .../orm-class-work/orm-solution-02/pom.xml | 64 ++++++++++ .../example/ormdemo/OrmDemoApplication.java | 17 +++ .../otus/example/ormdemo/models/Avatar.java | 22 ++++ .../otus/example/ormdemo/models/Course.java | 22 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 23 ++++ .../example/ormdemo/models/OtusStudent.java | 27 +++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-03/.gitignore | 29 +++++ .../orm-class-work/orm-solution-03/pom.xml | 65 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 17 +++ .../otus/example/ormdemo/models/Avatar.java | 25 ++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 32 +++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-04/.gitignore | 29 +++++ .../orm-class-work/orm-solution-04/pom.xml | 66 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 17 +++ .../otus/example/ormdemo/models/Avatar.java | 25 ++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 41 +++++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-05/.gitignore | 29 +++++ .../orm-class-work/orm-solution-05/pom.xml | 66 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 14 +++ .../otus/example/ormdemo/models/Avatar.java | 30 +++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 38 ++++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-06/.gitignore | 29 +++++ .../orm-class-work/orm-solution-06/pom.xml | 66 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 15 +++ .../otus/example/ormdemo/models/Avatar.java | 30 +++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 38 ++++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-07/.gitignore | 29 +++++ .../orm-class-work/orm-solution-07/pom.xml | 66 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 15 +++ .../otus/example/ormdemo/models/Avatar.java | 29 +++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 38 ++++++ .../src/main/resources/application.yml | 20 ++++ .../orm-class-work/orm-solution-08/.gitignore | 29 +++++ .../orm-class-work/orm-solution-08/pom.xml | 65 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 15 +++ .../otus/example/ormdemo/models/Avatar.java | 25 ++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 46 ++++++++ .../src/main/resources/application.yml | 20 ++++ .../orm-solution-final/.gitignore | 29 +++++ .../orm-class-work/orm-solution-final/pom.xml | 65 +++++++++++ .../example/ormdemo/OrmDemoApplication.java | 15 +++ .../otus/example/ormdemo/models/Avatar.java | 25 ++++ .../otus/example/ormdemo/models/Course.java | 25 ++++ .../ru/otus/example/ormdemo/models/EMail.java | 26 +++++ .../example/ormdemo/models/OtusStudent.java | 53 +++++++++ .../src/main/resources/application.yml | 20 ++++ 2024-09/spring-10-orm/orm-class-work/pom.xml | 25 ++++ 131 files changed, 3675 insertions(+), 11 deletions(-) create mode 100644 2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/java/ru/otus/spring/dao/PersonDaoJdbc2Test.java create mode 100644 2024-09/spring-10-orm/demo-projects/.gitignore create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/.gitignore create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/README.md create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/pom.xml create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/resources/schema.sql create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/application.yml create mode 100644 2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/data.sql create mode 100644 2024-09/spring-10-orm/demo-projects/pom.xml create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/.gitignore create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/README.md create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/pom.xml create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/resources/schema.sql create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcTest.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/application.yml create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/data.sql create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/.gitignore create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/README.md create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/pom.xml create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/InheritanceDemo.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/A.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/B.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/C.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepository.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepositoryJpa.java create mode 100644 2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/.gitignore create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/pom.xml create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java create mode 100644 2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/resources/application.yml create mode 100644 2024-09/spring-10-orm/orm-class-work/pom.xml diff --git a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/application.yml b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/application.yml index 50b6c632..7111b699 100644 --- a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/application.yml +++ b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/application.yml @@ -1,14 +1,14 @@ spring: datasource: url: jdbc:h2:mem:testdb - #initialization-mode: always - #schema: schema.sql - #data: data.sql + initialization-mode: always + schema: schema.sql + data: data.sql sql: init: - mode: always - data-locations: data.sql - schema-locations: schema.sql + #mode: always + #data-locations: data.sql + #schema-locations: schema.sql h2: console: path: /h2-console diff --git a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/schema.sql b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/schema.sql index 583bbae0..bd6f5353 100644 --- a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/schema.sql +++ b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/main/resources/schema.sql @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS PERSONS; CREATE TABLE PERSONS ( ID BIGINT PRIMARY KEY, diff --git a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/java/ru/otus/spring/dao/PersonDaoJdbc2Test.java b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/java/ru/otus/spring/dao/PersonDaoJdbc2Test.java new file mode 100644 index 00000000..a80e9933 --- /dev/null +++ b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/java/ru/otus/spring/dao/PersonDaoJdbc2Test.java @@ -0,0 +1,88 @@ +package ru.otus.spring.dao; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.test.context.transaction.AfterTransaction; +import org.springframework.test.context.transaction.BeforeTransaction; +import ru.otus.spring.domain.Person; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("Dao для работы с пёрсонами должно") +@JdbcTest +@Import(PersonDaoJdbc.class) +//@Transactional(propagation = Propagation.NOT_SUPPORTED) +class PersonDaoJdbc2Test { + + private static final int EXPECTED_PERSONS_COUNT = 1; + private static final int EXISTING_PERSON_ID = 1; + private static final String EXISTING_PERSON_NAME = "Ivan"; + + @Autowired + private PersonDaoJdbc personDao; + + @BeforeTransaction + void beforeTransaction() { + System.out.println("beforeTransaction"); + } + + @AfterTransaction + void afterTransaction() { + System.out.println("afterTransaction"); + } + + @DisplayName("возвращать ожидаемое количество пёрсонов в БД") + @Test + void shouldReturnExpectedPersonCount() { + int actualPersonsCount = personDao.count(); + assertThat(actualPersonsCount).isEqualTo(EXPECTED_PERSONS_COUNT); + } + + //@Rollback(value = false) + //@Commit + @DisplayName("добавлять пёрсона в БД") + @Test + void shouldInsertPerson() { + Person expectedPerson = new Person(2, "Igor"); + personDao.insert(expectedPerson); + Person actualPerson = personDao.getById(expectedPerson.getId()); + assertThat(actualPerson).usingRecursiveComparison().isEqualTo(expectedPerson); + } + + @DisplayName("возвращать ожидаемого пёрсона по его id") + @Test + void shouldReturnExpectedPersonById() { + Person expectedPerson = new Person(EXISTING_PERSON_ID, EXISTING_PERSON_NAME); + Person actualPerson = personDao.getById(expectedPerson.getId()); + assertThat(actualPerson).usingRecursiveComparison().isEqualTo(expectedPerson); + } + + @DisplayName("удалять заданного пёрсона по его id") + @Test + void shouldCorrectDeletePersonById() { + assertThatCode(() -> personDao.getById(EXISTING_PERSON_ID)) + .doesNotThrowAnyException(); + + personDao.deleteById(EXISTING_PERSON_ID); + + assertThatThrownBy(() -> personDao.getById(EXISTING_PERSON_ID)) + .isInstanceOf(EmptyResultDataAccessException.class); + } + + @DisplayName("возвращать ожидаемый список пёрсонов") + @Test + void shouldReturnExpectedPersonsList() { + Person expectedPerson = new Person(EXISTING_PERSON_ID, EXISTING_PERSON_NAME); + List actualPersonList = personDao.getAll(); + assertThat(actualPersonList) + .containsExactlyInAnyOrder(expectedPerson); + } +} \ No newline at end of file diff --git a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/resources/application.yml b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/resources/application.yml index f7de231a..bbbefa76 100644 --- a/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/resources/application.yml +++ b/2024-09/spring-09-jdbc/jdbc-demo-solution-final/src/test/resources/application.yml @@ -1,10 +1,10 @@ spring: datasource: url: jdbc:h2:mem:testdb - #initialization-mode: always - #data: data.sql + initialization-mode: always + data: data.sql sql: init: - mode: always - data-locations: data.sql + #mode: always + #data-locations: data.sql #schema-locations: schema.sql diff --git a/2024-09/spring-10-orm/demo-projects/.gitignore b/2024-09/spring-10-orm/demo-projects/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/.gitignore b/2024-09/spring-10-orm/demo-projects/mybatis-demo/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/README.md b/2024-09/spring-10-orm/demo-projects/mybatis-demo/README.md new file mode 100644 index 00000000..44635273 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/README.md @@ -0,0 +1,2 @@ +# mybatis-demo +Пример работы с БД через MyBatis \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/pom.xml b/2024-09/spring-10-orm/demo-projects/mybatis-demo/pom.xml new file mode 100644 index 00000000..f4f6019e --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + mybatis-demo + 0.0.1-SNAPSHOT + mybatis-demo + MyBatis demo + + + 17 + 17 + 17 + 3.0.3 + 2.2.220 + 2.0 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis.version} + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java new file mode 100644 index 00000000..ab5f7513 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/MyBatisDemoApplication.java @@ -0,0 +1,14 @@ +package ru.otus.example.mybatisdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; + +@SpringBootApplication +public class MyBatisDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(MyBatisDemoApplication.class, args); + } + +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java new file mode 100644 index 00000000..5c8f4728 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Avatar.java @@ -0,0 +1,13 @@ +package ru.otus.example.mybatisdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Avatar { + private long id; + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java new file mode 100644 index 00000000..6aa8cff7 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/Course.java @@ -0,0 +1,13 @@ +package ru.otus.example.mybatisdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Course { + private long id; + private String name; +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java new file mode 100644 index 00000000..8fa43ebd --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/EMail.java @@ -0,0 +1,13 @@ +package ru.otus.example.mybatisdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EMail { + private long id; + private String email; +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java new file mode 100644 index 00000000..afb324fb --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/models/OtusStudent.java @@ -0,0 +1,18 @@ +package ru.otus.example.mybatisdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OtusStudent { + private long id; + private String name; + private Avatar avatar; + private List emails; + private List courses; +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java new file mode 100644 index 00000000..634d1aba --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/AvatarRepository.java @@ -0,0 +1,18 @@ +package ru.otus.example.mybatisdemo.repositories; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; +import ru.otus.example.mybatisdemo.models.Avatar; + +@Mapper +public interface AvatarRepository { + @Select("select * from avatars where id = #{id}") + @Results(value = { + @Result(property = "id", column = "id"), + @Result(property = "photoUrl", column = "photo_url") + }) + Avatar getAvatarById(long id); + +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java new file mode 100644 index 00000000..20271981 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/CourseRepository.java @@ -0,0 +1,17 @@ +package ru.otus.example.mybatisdemo.repositories; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import ru.otus.example.mybatisdemo.models.Course; + +import java.util.List; + +@Mapper +public interface CourseRepository { + + @Select("select * " + + "from student_courses sc left join courses c on sc.course_id = c.id " + + "where sc.student_id = #{studentId}") + List getCoursesByStudentId(long studentId); + +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java new file mode 100644 index 00000000..989b681d --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/EmailRepository.java @@ -0,0 +1,14 @@ +package ru.otus.example.mybatisdemo.repositories; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import ru.otus.example.mybatisdemo.models.EMail; + +import java.util.List; + +@Mapper +public interface EmailRepository { + + @Select("select * from emails where student_id = #{studentId}") + List getEmailsByStudentId(long studentId); +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java new file mode 100644 index 00000000..82a8260b --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepository.java @@ -0,0 +1,42 @@ +package ru.otus.example.mybatisdemo.repositories; + +import org.apache.ibatis.annotations.*; +import org.apache.ibatis.mapping.FetchType; +import ru.otus.example.mybatisdemo.models.Avatar; +import ru.otus.example.mybatisdemo.models.OtusStudent; + +import java.util.List; + +@Mapper +public interface OtusStudentRepository { + + @Select("select * from otus_students") + @Results(id = "studentAllMap", value = { + @Result(property = "id", column = "id"), + @Result(property = "name", column = "name"), + @Result(property = "avatar", column = "avatar_id", javaType = Avatar.class, + one = @One(select = "ru.otus.example.mybatisdemo.repositories.AvatarRepository.getAvatarById", fetchType = FetchType.EAGER)), + @Result(property = "emails", column = "id", javaType = List.class, + many = @Many(select = "ru.otus.example.mybatisdemo.repositories.EmailRepository.getEmailsByStudentId", fetchType = FetchType.EAGER)), + @Result(property = "courses", column = "id", javaType = List.class, + many = @Many(select = "ru.otus.example.mybatisdemo.repositories.CourseRepository.getCoursesByStudentId", fetchType = FetchType.EAGER)) + }) + List findAllWithAllInfo(); + + @Select("select * from otus_students where id = #{id}") + @ResultMap("studentAllMap") + OtusStudent findById(long id); + + @Select("select count(*) as students_count from otus_students") + long getStudentsCount(); + + @Insert("insert into otus_students(name, avatar_id) values (#{name}, #{avatar.id})") + void insert(OtusStudent student); + + @Update("update otus_students set name = #{name} where id = #{id}") + void updateName(OtusStudent student); + + @Delete("delete from otus_students where id = #{id}") + void deleteById(long id); + +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/resources/schema.sql b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/resources/schema.sql new file mode 100644 index 00000000..43a684bb --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/main/resources/schema.sql @@ -0,0 +1,31 @@ +create table avatars( + id bigserial, + photo_url varchar(8000), + primary key (id) +); + +create table courses( + id bigserial, + name varchar(255), + primary key (id) +); + +create table otus_students( + id bigserial, + name varchar(255), + avatar_id bigint references avatars (id), + primary key (id) +); + +create table emails( + id bigserial, + student_id bigint references otus_students(id) on delete cascade, + email varchar(255), + primary key (id) +); + +create table student_courses( + student_id bigint references otus_students(id) on delete cascade, + course_id bigint references courses(id), + primary key (student_id, course_id) +); \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java new file mode 100644 index 00000000..d9a24bce --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/java/ru/otus/example/mybatisdemo/repositories/OtusStudentRepositoryTest.java @@ -0,0 +1,110 @@ +package ru.otus.example.mybatisdemo.repositories; + +import lombok.val; +import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.example.mybatisdemo.models.Avatar; +import ru.otus.example.mybatisdemo.models.OtusStudent; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("Репозиторий на основе MyBatis для работы со студентами ") +@SpringBootTest +@Transactional +public class OtusStudentRepositoryTest { + + private static final String FIELD_ID = "id"; + private static final String FIELD_PHOTO_URL = "photoUrl"; + private static final String FIELD_NAME = "name"; + + private static final long FIRST_STUDENT_ID = 1L; + private static final long FIRST_AVATAR_ID = 1L; + private static final String FIRST_STUDENT_NAME = "student_01"; + private static final String FIRST_AVATAR_URL = "photoUrl_01"; + private static final String STUDENT_NEW_NAME = "Висусуалий"; + + private static final int EXPECTED_NUMBER_OF_STUDENTS = 10; + private static final long INSERTED_STUDENT_ID = 11L; + private static final int EXPECTED_EMAILS_COUNT = 2; + private static final int EXPECTED_COURSES_COUNT = 3; + + @Autowired + private OtusStudentRepository studentRepositoryMyBatis; + + @DisplayName("должен загружать список всех студентов с полной информацией о них") + @Test + void shouldReturnCorrectStudentsListWithAllInfo() { + val students = studentRepositoryMyBatis.findAllWithAllInfo(); + assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS) + .allMatch(s -> !s.getName().equals("")) + .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0) + .allMatch(s -> s.getAvatar() != null) + .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0); + } + + @DisplayName("должен загружать число студентов в БД") + @Test + void shouldReturnCorrectStudentsCount() { + long studentsCount = studentRepositoryMyBatis.getStudentsCount(); + assertThat(studentsCount).isEqualTo(EXPECTED_NUMBER_OF_STUDENTS); + } + + @DisplayName(" должен загружать информацию о нужном студенте") + @Test + void shouldFindExpectedStudentById(){ + val actualStudent = studentRepositoryMyBatis.findById(FIRST_STUDENT_ID); + + assertThat(actualStudent).isNotNull(); + assertThat(actualStudent.getName()).isEqualTo(FIRST_STUDENT_NAME); + assertThat(actualStudent.getAvatar()).isNotNull() + .hasFieldOrPropertyWithValue(FIELD_ID, FIRST_STUDENT_ID) + .hasFieldOrPropertyWithValue(FIELD_PHOTO_URL, FIRST_AVATAR_URL); + assertThat(actualStudent.getEmails()).isNotNull().hasSize(EXPECTED_EMAILS_COUNT); + assertThat(actualStudent.getCourses()).isNotNull().hasSize(EXPECTED_COURSES_COUNT); + } + + @DisplayName(" должен сохранить, а потом загрузить информацию о нужном студенте") + @Test + void shouldSaveAndLoadCorrectStudent() { + val expectedStudent = new OtusStudent(0, STUDENT_NEW_NAME, + new Avatar(FIRST_AVATAR_ID, FIRST_AVATAR_URL), List.of(), List.of()); + studentRepositoryMyBatis.insert(expectedStudent); + val actualStudent = studentRepositoryMyBatis.findById(INSERTED_STUDENT_ID); + + assertThat(actualStudent) + .isNotNull() + .usingRecursiveComparison( + RecursiveComparisonConfiguration.builder() + .withIgnoredFields(FIELD_ID).build()) + .isEqualTo(expectedStudent); + } + + + @DisplayName(" должен обновлять имя студента в БД") + @Test + void shouldUpdateStudentName() { + val student = studentRepositoryMyBatis.findById(FIRST_STUDENT_ID); + student.setName(STUDENT_NEW_NAME); + studentRepositoryMyBatis.updateName(student); + val actualStudent = studentRepositoryMyBatis.findById(FIRST_STUDENT_ID); + + assertThat(actualStudent).isNotNull().hasFieldOrPropertyWithValue(FIELD_NAME, student.getName()); + } + + @DisplayName("должен удалять студента из БД по id") + @Test + void shouldDeleteStudentFromDbById() { + val studentsCountBefore = studentRepositoryMyBatis.getStudentsCount(); + studentRepositoryMyBatis.deleteById(FIRST_STUDENT_ID); + val studentsCountAfter = studentRepositoryMyBatis.getStudentsCount(); + + assertThat(studentsCountBefore - studentsCountAfter).isEqualTo(1); + } + +} diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/application.yml b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/application.yml new file mode 100644 index 00000000..dc237b00 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/application.yml @@ -0,0 +1,8 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: always + +logging: + level: + ru.otus.example.mybatisdemo.repositories: TRACE \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/data.sql b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/data.sql new file mode 100644 index 00000000..a8db6b85 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/mybatis-demo/src/test/resources/data.sql @@ -0,0 +1,29 @@ +insert into avatars(photo_url) +values ('photoUrl_01'), ('photoUrl_02'), ('photoUrl_03'), ('photoUrl_04'), ('photoUrl_05'), + ('photoUrl_06'), ('photoUrl_07'), ('photoUrl_08'), ('photoUrl_09'), ('photoUrl_10'); + +insert into courses(name) +values ('course_name_01'), ('course_name_02'), ('course_name_03'), ('course_name_04'), ('course_name_05'), + ('course_name_06'), ('course_name_07'), ('course_name_08'), ('course_name_09'), ('course_name_10'), ('not_used_11'); + +insert into otus_students(name, avatar_id) +values ('student_01', 1), ('student_02', 2), ('student_03', 3), ('student_04', 4), ('student_05', 5), + ('student_06', 6), ('student_07', 7), ('student_08', 8), ('student_09', 9), ('student_10', 10); + + +insert into emails(email, student_id) +values ('email_01', 1), ('email_02', 1), ('email_03', 2), ('email_04', 2), ('email_05', 3), ('email_06', 4), + ('email_07', 5), ('email_08', 6), ('email_09', 7), ('email_10', 8), ('email_11', 9), ('email_12', 10); + + +insert into student_courses(student_id, course_id) +values (1, 1), (1, 2), (1, 3), + (2, 2), (2, 4), (2, 5), + (3, 3), (3, 6), (3, 7), + (4, 4), (4, 8), (4, 9), + (5, 5), (5, 10), (5, 1), + (6, 6), (6, 2), (6, 3), + (7, 7), (7, 4), (7, 5), + (8, 8), (8, 6), (8, 7), + (9, 9), (9, 8), (9, 10), + (10, 10), (10, 1), (10, 2); diff --git a/2024-09/spring-10-orm/demo-projects/pom.xml b/2024-09/spring-10-orm/demo-projects/pom.xml new file mode 100644 index 00000000..95c77325 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + ru.otus + demo-projects + 1.0 + + pom + + + spring-jdbc-demo + spring-jpa-ineritance-demo + mybatis-demo + + diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/.gitignore b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/README.md b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/README.md new file mode 100644 index 00000000..462216c3 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/README.md @@ -0,0 +1,2 @@ +# spring-jdbc-demo +Пример работы с БД через jdbc \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/pom.xml b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/pom.xml new file mode 100644 index 00000000..03611894 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + spring-jdbc-demo + 0.0.1-SNAPSHOT + spring-jdbc-demo + Spring jdbc demo + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java new file mode 100644 index 00000000..28ebfec4 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/SpringJdbcDemoApplication.java @@ -0,0 +1,13 @@ +package ru.otus.example.springjdbcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringJdbcDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringJdbcDemoApplication.class, args); + } + +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java new file mode 100644 index 00000000..a1963ea4 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Avatar.java @@ -0,0 +1,13 @@ +package ru.otus.example.springjdbcdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Avatar { + private long id; + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java new file mode 100644 index 00000000..07b6e2c2 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/Course.java @@ -0,0 +1,13 @@ +package ru.otus.example.springjdbcdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Course { + private long id; + private String name; +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java new file mode 100644 index 00000000..16985ad5 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/EMail.java @@ -0,0 +1,13 @@ +package ru.otus.example.springjdbcdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EMail { + private long id; + private String email; +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java new file mode 100644 index 00000000..5ae9167c --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/models/OtusStudent.java @@ -0,0 +1,18 @@ +package ru.otus.example.springjdbcdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OtusStudent { + private long id; + private String name; + private Avatar avatar; + private List emails; + private List courses; +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepository.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepository.java new file mode 100644 index 00000000..e594ee5c --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepository.java @@ -0,0 +1,9 @@ +package ru.otus.example.springjdbcdemo.repositories; + +import ru.otus.example.springjdbcdemo.models.Course; + +import java.util.List; + +public interface CourseRepository { + List findAllUsed(); +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java new file mode 100644 index 00000000..10526ed5 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/CourseRepositoryJdbc.java @@ -0,0 +1,35 @@ +package ru.otus.example.springjdbcdemo.repositories; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.otus.example.springjdbcdemo.models.Course; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class CourseRepositoryJdbc implements CourseRepository { + + private final JdbcOperations op; + + @Override + public List findAllUsed() { + return op.query("select c.id, c.name " + + "from courses c inner join student_courses sc on c.id = sc.course_id " + + "group by c.id, c.name " + + "order by c.name", new CourseRowMapper()); + } + + private static class CourseRowMapper implements RowMapper { + @Override + public Course mapRow(ResultSet rs, int i) throws SQLException { + return new Course(rs.getLong(1), rs.getString(2)); + } + } + +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepository.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepository.java new file mode 100644 index 00000000..0012af3d --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepository.java @@ -0,0 +1,9 @@ +package ru.otus.example.springjdbcdemo.repositories; + +import ru.otus.example.springjdbcdemo.models.OtusStudent; + +import java.util.List; + +public interface OtusStudentRepository { + List findAllWithAllInfo(); +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java new file mode 100644 index 00000000..5618b797 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbc.java @@ -0,0 +1,52 @@ +package ru.otus.example.springjdbcdemo.repositories; + +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.stereotype.Repository; +import ru.otus.example.springjdbcdemo.models.Course; +import ru.otus.example.springjdbcdemo.models.OtusStudent; +import ru.otus.example.springjdbcdemo.repositories.ext.OtusStudentResultSetExtractor; +import ru.otus.example.springjdbcdemo.repositories.ext.StudentCourseRelation; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Repository +@RequiredArgsConstructor +public class OtusStudentRepositoryJdbc implements OtusStudentRepository { + + private final CourseRepository courseRepository; + private final JdbcOperations op; + + @Override + public List findAllWithAllInfo() { + List courses = courseRepository.findAllUsed(); + List relations = getAllRelations(); + Map students = + op.query("select os.id, os.name, a.id avatar_id, a.photo_url, e.id email_id, e.email " + + "from (otus_students os left join avatars a on " + + "os.avatar_id = a.id) left join emails e on os.id = e.student_id", + new OtusStudentResultSetExtractor()); + + mergeStudentsInfo(students, courses, relations); + return new ArrayList<>(Objects.requireNonNull(students).values()); + } + + private List getAllRelations() { + return op.query("select student_id, course_id from student_courses sc order by student_id, course_id", + (rs, i) -> new StudentCourseRelation(rs.getLong(1), rs.getLong(2))); + } + + private void mergeStudentsInfo(Map students, List courses, + List relations) { + Map coursesMap = courses.stream().collect(Collectors.toMap(Course::getId, Function.identity())); + relations.forEach(r -> { + if (students.containsKey(r.getStudentId()) && coursesMap.containsKey(r.getCourseId())) { + students.get(r.getStudentId()).getCourses().add(coursesMap.get(r.getCourseId())); + } + }); + } + + +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java new file mode 100644 index 00000000..778a46b7 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/OtusStudentResultSetExtractor.java @@ -0,0 +1,37 @@ +package ru.otus.example.springjdbcdemo.repositories.ext; + +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import ru.otus.example.springjdbcdemo.models.Avatar; +import ru.otus.example.springjdbcdemo.models.EMail; +import ru.otus.example.springjdbcdemo.models.OtusStudent; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class OtusStudentResultSetExtractor implements + ResultSetExtractor> { + @Override + public Map extractData(ResultSet rs) throws SQLException, + DataAccessException { + + Map students = new HashMap<>(); + while (rs.next()) { + long id = rs.getLong("id"); + OtusStudent student = students.get(id); + if (student == null) { + student = new OtusStudent(id, rs.getString("name"), + new Avatar(rs.getLong("avatar_id"), rs.getString("photo_url")), + new ArrayList<>(), new ArrayList<>()); + students.put(student.getId(), student); + } + + student.getEmails().add(new EMail(rs.getLong("email_id"), + rs.getString("email"))); + } + return students; + } +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java new file mode 100644 index 00000000..408c97d2 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/java/ru/otus/example/springjdbcdemo/repositories/ext/StudentCourseRelation.java @@ -0,0 +1,11 @@ +package ru.otus.example.springjdbcdemo.repositories.ext; + +import lombok.Data; +import lombok.RequiredArgsConstructor; + +@Data +@RequiredArgsConstructor +public class StudentCourseRelation { + private final long studentId; + private final long courseId; +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/resources/schema.sql b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/resources/schema.sql new file mode 100644 index 00000000..43a684bb --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/main/resources/schema.sql @@ -0,0 +1,31 @@ +create table avatars( + id bigserial, + photo_url varchar(8000), + primary key (id) +); + +create table courses( + id bigserial, + name varchar(255), + primary key (id) +); + +create table otus_students( + id bigserial, + name varchar(255), + avatar_id bigint references avatars (id), + primary key (id) +); + +create table emails( + id bigserial, + student_id bigint references otus_students(id) on delete cascade, + email varchar(255), + primary key (id) +); + +create table student_courses( + student_id bigint references otus_students(id) on delete cascade, + course_id bigint references courses(id), + primary key (student_id, course_id) +); \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcTest.java b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcTest.java new file mode 100644 index 00000000..bf2a8197 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/java/ru/otus/example/springjdbcdemo/repositories/OtusStudentRepositoryJdbcTest.java @@ -0,0 +1,35 @@ +package ru.otus.example.springjdbcdemo.repositories; + +import lombok.val; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.Import; + + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("Репозиторий на основе Jdbc для работы со студентами ") +@JdbcTest +@Import({OtusStudentRepositoryJdbc.class, CourseRepositoryJdbc.class}) +class OtusStudentRepositoryJdbcTest { + + private static final int EXPECTED_NUMBER_OF_STUDENTS = 10; + + @Autowired + private OtusStudentRepositoryJdbc repositoryJdbc; + + @DisplayName("должен загружать список всех студентов с полной информацией о них") + @Test + void shouldReturnCorrectStudentsListWithAllInfo() { + val students = repositoryJdbc.findAllWithAllInfo(); + assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS) + .allMatch(s -> !s.getName().equals("")) + .allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0) + .allMatch(s -> s.getAvatar() != null) + .allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0); + students.forEach(System.out::println); + + } +} \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/application.yml b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/application.yml new file mode 100644 index 00000000..e1e538a4 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/application.yml @@ -0,0 +1,4 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: always \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/data.sql b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/data.sql new file mode 100644 index 00000000..a8db6b85 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jdbc-demo/src/test/resources/data.sql @@ -0,0 +1,29 @@ +insert into avatars(photo_url) +values ('photoUrl_01'), ('photoUrl_02'), ('photoUrl_03'), ('photoUrl_04'), ('photoUrl_05'), + ('photoUrl_06'), ('photoUrl_07'), ('photoUrl_08'), ('photoUrl_09'), ('photoUrl_10'); + +insert into courses(name) +values ('course_name_01'), ('course_name_02'), ('course_name_03'), ('course_name_04'), ('course_name_05'), + ('course_name_06'), ('course_name_07'), ('course_name_08'), ('course_name_09'), ('course_name_10'), ('not_used_11'); + +insert into otus_students(name, avatar_id) +values ('student_01', 1), ('student_02', 2), ('student_03', 3), ('student_04', 4), ('student_05', 5), + ('student_06', 6), ('student_07', 7), ('student_08', 8), ('student_09', 9), ('student_10', 10); + + +insert into emails(email, student_id) +values ('email_01', 1), ('email_02', 1), ('email_03', 2), ('email_04', 2), ('email_05', 3), ('email_06', 4), + ('email_07', 5), ('email_08', 6), ('email_09', 7), ('email_10', 8), ('email_11', 9), ('email_12', 10); + + +insert into student_courses(student_id, course_id) +values (1, 1), (1, 2), (1, 3), + (2, 2), (2, 4), (2, 5), + (3, 3), (3, 6), (3, 7), + (4, 4), (4, 8), (4, 9), + (5, 5), (5, 10), (5, 1), + (6, 6), (6, 2), (6, 3), + (7, 7), (7, 4), (7, 5), + (8, 8), (8, 6), (8, 7), + (9, 9), (9, 8), (9, 10), + (10, 10), (10, 1), (10, 2); diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/.gitignore b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/README.md b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/README.md new file mode 100644 index 00000000..462216c3 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/README.md @@ -0,0 +1,2 @@ +# spring-jdbc-demo +Пример работы с БД через jdbc \ No newline at end of file diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/pom.xml b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/pom.xml new file mode 100644 index 00000000..a9a119a5 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + spring-jpa-ineritance-demo + 0.0.1-SNAPSHOT + spring-jpa-demo + Spring jpa demo + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/InheritanceDemo.java b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/InheritanceDemo.java new file mode 100644 index 00000000..e8a725ee --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/InheritanceDemo.java @@ -0,0 +1,43 @@ +package ru.otus.example.ineritancedemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import ru.otus.example.ineritancedemo.model.A; +import ru.otus.example.ineritancedemo.model.C; +import ru.otus.example.ineritancedemo.model.B; +import ru.otus.example.ineritancedemo.repository.ARepository; + +import java.sql.SQLException; +import java.util.List; + +@SpringBootApplication +public class InheritanceDemo { + + public static void main(String[] args) throws SQLException { + ConfigurableApplicationContext ctx = SpringApplication.run(InheritanceDemo.class, args); + ARepository aRepository = ctx.getBean(ARepository.class); + + System.out.println("\n\n-------------------------------------------\n\n"); + System.out.println("Начинаем вставку сущностей A/B/C: "); + + var a = new A(0, "aaaaaa1"); + var b = new B(0, "aaaaaa2", "bbbbbbb"); + var c = new C(0, "aaaaaa3", "ccccccc"); + aRepository.save(a); + aRepository.save(b); + aRepository.save(c); + + System.out.println("\n\n-------------------------------------------\n\n"); + System.out.println("Загружаем все сущности A (в т.ч. наследников):"); + + List resultList = aRepository.findAll(); + + System.out.println("\n\nРезультат:"); + System.out.println(resultList); + + + Console.main(); + } +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/A.java b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/A.java new file mode 100644 index 00000000..bae6ecf1 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/A.java @@ -0,0 +1,45 @@ +package ru.otus.example.ineritancedemo.model; + +import jakarta.persistence.DiscriminatorColumn; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; +import jakarta.persistence.Table; + +@Entity +@DiscriminatorColumn(name = "discriminator") +@DiscriminatorValue("RootA") +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +//@Inheritance(strategy = InheritanceType.JOINED) +//@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Table(name = "A") +public class A { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + // Не получится использовать при InheritanceType.TABLE_PER_CLASS + //@GeneratedValue(strategy = GenerationType.IDENTITY) + protected long id; + + protected String a; + + public A() { + } + + public A(long id, String a) { + this.id = id; + this.a = a; + } + + @Override + public String toString() { + return "A{" + + "id=" + id + + ", a='" + a + '\'' + + '}'; + } +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/B.java b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/B.java new file mode 100644 index 00000000..d18ad82c --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/B.java @@ -0,0 +1,28 @@ +package ru.otus.example.ineritancedemo.model; + +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; + +@Entity +@DiscriminatorValue("LeafB") +public class B extends A { + private String b; + + public B() { + super(); + } + + public B(long id, String a, String b) { + super(id, a); + this.b = b; + } + + @Override + public String toString() { + return "B{" + + "id=" + id + + ", a='" + a + '\'' + + ", b='" + b + '\'' + + '}'; + } +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/C.java b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/C.java new file mode 100644 index 00000000..aa4c148c --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/model/C.java @@ -0,0 +1,31 @@ +package ru.otus.example.ineritancedemo.model; + + +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; + + +@Entity +@DiscriminatorValue("LeafC") +public class C extends A{ + private String c; + + public C() { + super(); + } + + + public C(long id, String a, String c) { + super(id, a); + this.c = c; + } + + @Override + public String toString() { + return "C{" + + "id=" + id + + ", a='" + a + '\'' + + ", c='" + c + '\'' + + '}'; + } +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepository.java b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepository.java new file mode 100644 index 00000000..8d787e92 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepository.java @@ -0,0 +1,10 @@ +package ru.otus.example.ineritancedemo.repository; + +import ru.otus.example.ineritancedemo.model.A; + +import java.util.List; + +public interface ARepository { + List findAll(); + void save(A a); +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepositoryJpa.java b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepositoryJpa.java new file mode 100644 index 00000000..8f580eef --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/java/ru/otus/example/ineritancedemo/repository/ARepositoryJpa.java @@ -0,0 +1,32 @@ +package ru.otus.example.ineritancedemo.repository; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.example.ineritancedemo.model.A; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.TypedQuery; +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class ARepositoryJpa implements ARepository { + + @PersistenceContext + private final EntityManager em; + + @Transactional(readOnly = true) // Только для примера. Лучше вешать на методы сервисов + @Override + public List findAll() { + TypedQuery query = em.createQuery("select a from A a", A.class); + return query.getResultList(); + } + + @Transactional // Только для примера. Лучше вешать на методы сервисов + @Override + public void save(A a) { + em.persist(a); + } +} diff --git a/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/resources/application.yml b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/demo-projects/spring-jpa-ineritance-demo/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-exercise/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-exercise/pom.xml new file mode 100644 index 00000000..2fd35455 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-exercise + orm-exercise + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..cbf71df2 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.sql.SQLException; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) throws SQLException { + SpringApplication.run(OrmDemoApplication.class, args); + Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..27ace01b --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.persistence.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Avatar { + private long id; + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..b6fbaf37 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.persistence.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Course { + private long id; + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..d0f35463 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.persistence.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EMail { + private long id; + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..7479eb7d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,18 @@ +package ru.otus.example.ormdemo.models; + +import lombok.*; + +import jakarta.persistence.*; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OtusStudent { + private long id; + private String name; + + //private Avatar avatar; + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-exercise/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/pom.xml new file mode 100644 index 00000000..2e78989d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-01 + orm-solution-01 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..f79957fe --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.sql.SQLException; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) throws SQLException { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..f07b0b43 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Avatar { + @Id + private long id; + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..d13d262d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Course { + @Id + private long id; + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..576ba63f --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class EMail { + @Id + private long id; + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..3173d4a3 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,23 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + private long id; + private String name; + + //private Avatar avatar; + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-01/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/pom.xml new file mode 100644 index 00000000..b8c23ef5 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-02 + orm-solution-02 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..f79957fe --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.sql.SQLException; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) throws SQLException { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..e8707692 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,22 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + private long id; + + @Column(name = "photo_url") + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..e4aa8680 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,22 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..0d5171f7 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,23 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..5494d703 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,27 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.*; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name") + private String name; + + //private Avatar avatar; + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-02/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/pom.xml new file mode 100644 index 00000000..dc04b33f --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-03 + orm-solution-03 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..f79957fe --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.sql.SQLException; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) throws SQLException { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..86e9900d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..b68f4f09 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,32 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Позволяет указать стратегию генерации id + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name") + private String name; + + //private Avatar avatar; + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-03/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/pom.xml new file mode 100644 index 00000000..d634455e --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-04 + orm-solution-04 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..f79957fe --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.sql.SQLException; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) throws SQLException { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..86e9900d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..fae7b5f3 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,41 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name", nullable = false, unique = true) + private String name; + + // Указывает на связь между таблицами "один к одному" + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности + @JoinColumn(name = "avatar_id") + private Avatar avatar; + + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-04/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/pom.xml new file mode 100644 index 00000000..b5b9756c --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-05 + orm-solution-04 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..2d29dd3c --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,14 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..9e2efa43 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,30 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; + + @OneToOne(fetch = FetchType.LAZY) + private OtusStudent student; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..38b93c58 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,38 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name", nullable = false, unique = true) + private String name; + + // Указывает на связь между таблицами "один к одному" + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + private Avatar avatar; + + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-05/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/pom.xml new file mode 100644 index 00000000..240d954f --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-06 + orm-solution-04 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..ae44965b --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..9e2efa43 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,30 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; + + @OneToOne(fetch = FetchType.LAZY) + private OtusStudent student; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..b08ab739 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,38 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name", nullable = false, unique = true) + private String name; + + // Указывает на связь между таблицами "один к одному" + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "student", orphanRemoval = true) + private Avatar avatar; + + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-06/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/pom.xml new file mode 100644 index 00000000..26768c1e --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-07 + orm-solution-04 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..ae44965b --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..928ac1f6 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,29 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; + + @OneToOne(mappedBy = "avatar") + private OtusStudent student; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..38b93c58 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,38 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name", nullable = false, unique = true) + private String name; + + // Указывает на связь между таблицами "один к одному" + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + private Avatar avatar; + + //private List emails; + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-07/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/pom.xml new file mode 100644 index 00000000..b778e6a0 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-08 + orm-solution-05 + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..ae44965b --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..86e9900d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..b95aa319 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,46 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name", nullable = false, unique = true) + private String name; + + // Указывает на связь между таблицами "один к одному" + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности + @JoinColumn(name = "avatar_id") + private Avatar avatar; + + // Указывает на связь между таблицами "один ко многим" + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + @JoinColumn(name = "student_id") + private List emails; + + //private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-08/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/.gitignore b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/pom.xml b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/pom.xml new file mode 100644 index 00000000..abcb6f81 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.2 + + + ru.otus.example + orm-solution-final + orm-solution-final + 0.0.1-SNAPSHOT + + + 17 + 17 + 17 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + ${h2.version} + + + + org.projectlombok + lombok + true + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java new file mode 100644 index 00000000..ae44965b --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/OrmDemoApplication.java @@ -0,0 +1,15 @@ +package ru.otus.example.ormdemo; + +import org.h2.tools.Console; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrmDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(OrmDemoApplication.class, args); + //Console.main(args); + } + +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java new file mode 100644 index 00000000..86e9900d --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Avatar.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "avatars") +public class Avatar { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "photo_url") + private String photoUrl; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java new file mode 100644 index 00000000..dad16a14 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/Course.java @@ -0,0 +1,25 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "courses") +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "name") + private String name; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java new file mode 100644 index 00000000..92880532 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/EMail.java @@ -0,0 +1,26 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "emails") +public class EMail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "email") + private String email; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java new file mode 100644 index 00000000..379458f4 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/java/ru/otus/example/ormdemo/models/OtusStudent.java @@ -0,0 +1,53 @@ +package ru.otus.example.ormdemo.models; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity // Указывает, что данный класс является сущностью +@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность +public class OtusStudent { + @Id // Позволяет указать какое поле является идентификатором + @GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов + private long id; + + // Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности + @Column(name = "name", nullable = false, unique = true) + private String name; + + // Указывает на связь между таблицами "один к одному" + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + // Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности + @JoinColumn(name = "avatar_id") + private Avatar avatar; + + // Указывает на связь между таблицами "один ко многим" + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + @JoinColumn(name = "student_id") + private List emails; + + // Указывает на связь между таблицами "многие ко многим" + @ManyToMany(fetch = FetchType.LAZY /*, cascade = CascadeType.PERSIST*/) + // Задает таблицу связей между таблицами для хранения родительской и связанной сущностью + @JoinTable(name = "student_courses", joinColumns = @JoinColumn(name = "student_id"), + inverseJoinColumns = @JoinColumn(name = "course_id")) + private List courses; +} diff --git a/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/resources/application.yml b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/resources/application.yml new file mode 100644 index 00000000..80d05f29 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/orm-solution-final/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + initialization-mode: never + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2024-09/spring-10-orm/orm-class-work/pom.xml b/2024-09/spring-10-orm/orm-class-work/pom.xml new file mode 100644 index 00000000..2d21fb30 --- /dev/null +++ b/2024-09/spring-10-orm/orm-class-work/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + ru.otus + orm-class-work + 1.0 + + pom + + + orm-exercise + orm-solution-01 + orm-solution-02 + orm-solution-03 + orm-solution-04 + orm-solution-05 + orm-solution-06 + orm-solution-07 + orm-solution-08 + orm-solution-final + +