From 2d2c88f440ffef8fd9c654eadaac7177cd002123 Mon Sep 17 00:00:00 2001 From: stvort Date: Fri, 8 Sep 2023 23:44:28 +0400 Subject: [PATCH] 2023-07 spring-13-data-jpa added --- 2023-07/spring-13-data-jpa/.gitignore | 4 + 2023-07/spring-13-data-jpa/demo/.gitignore | 4 + 2023-07/spring-13-data-jpa/demo/pom.xml | 56 ++++++++++++++ .../main/java/ru/otus/springdata/Main.java | 75 +++++++++++++++++++ .../java/ru/otus/springdata/domain/Email.java | 26 +++++++ .../ru/otus/springdata/domain/Person.java | 34 +++++++++ .../repository/EmailRepository.java | 21 ++++++ .../repository/EmailRepositoryCustom.java | 9 +++ .../repository/EmailRepositoryCustomImpl.java | 20 +++++ .../repository/PersonRepository.java | 20 +++++ .../repository/PersonSpecification.java | 21 ++++++ .../demo/src/main/resources/application.yml | 20 +++++ .../spring-13-data-jpa/exercise/.gitignore | 4 + 2023-07/spring-13-data-jpa/exercise/pom.xml | 51 +++++++++++++ .../main/java/ru/otus/springdata/Main.java | 23 ++++++ .../java/ru/otus/springdata/domain/Email.java | 21 ++++++ .../ru/otus/springdata/domain/Person.java | 25 +++++++ .../repository/EmailRepository.java | 4 + .../repository/PersonRepository.java | 4 + .../src/main/resources/application.yml | 20 +++++ 2023-07/spring-13-data-jpa/pom.xml | 21 ++++++ .../spring-13-data-jpa/solution-01/.gitignore | 4 + .../spring-13-data-jpa/solution-01/pom.xml | 56 ++++++++++++++ .../main/java/ru/otus/springdata/Main.java | 37 +++++++++ .../java/ru/otus/springdata/domain/Email.java | 24 ++++++ .../ru/otus/springdata/domain/Person.java | 27 +++++++ .../repository/EmailRepository.java | 12 +++ .../repository/PersonRepository.java | 15 ++++ .../src/main/resources/application.yml | 20 +++++ .../spring-13-data-jpa/solution-02/.gitignore | 4 + .../spring-13-data-jpa/solution-02/pom.xml | 56 ++++++++++++++ .../main/java/ru/otus/springdata/Main.java | 53 +++++++++++++ .../java/ru/otus/springdata/domain/Email.java | 27 +++++++ .../ru/otus/springdata/domain/Person.java | 27 +++++++ .../repository/EmailRepository.java | 13 ++++ .../repository/PersonRepository.java | 14 ++++ .../src/main/resources/application.yml | 20 +++++ .../spring-13-data-jpa/solution-03/.gitignore | 4 + .../spring-13-data-jpa/solution-03/pom.xml | 56 ++++++++++++++ .../main/java/ru/otus/springdata/Main.java | 55 ++++++++++++++ .../java/ru/otus/springdata/domain/Email.java | 26 +++++++ .../ru/otus/springdata/domain/Person.java | 34 +++++++++ .../repository/EmailRepository.java | 13 ++++ .../repository/PersonRepository.java | 18 +++++ .../src/main/resources/application.yml | 20 +++++ .../spring-13-data-jpa/solution-04/.gitignore | 4 + .../spring-13-data-jpa/solution-04/pom.xml | 56 ++++++++++++++ .../main/java/ru/otus/springdata/Main.java | 64 ++++++++++++++++ .../java/ru/otus/springdata/domain/Email.java | 26 +++++++ .../ru/otus/springdata/domain/Person.java | 34 +++++++++ .../repository/EmailRepository.java | 21 ++++++ .../repository/PersonRepository.java | 20 +++++ .../src/main/resources/application.yml | 20 +++++ 53 files changed, 1363 insertions(+) create mode 100644 2023-07/spring-13-data-jpa/.gitignore create mode 100644 2023-07/spring-13-data-jpa/demo/.gitignore create mode 100644 2023-07/spring-13-data-jpa/demo/pom.xml create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java create mode 100644 2023-07/spring-13-data-jpa/demo/src/main/resources/application.yml create mode 100644 2023-07/spring-13-data-jpa/exercise/.gitignore create mode 100644 2023-07/spring-13-data-jpa/exercise/pom.xml create mode 100644 2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java create mode 100644 2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java create mode 100644 2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java create mode 100644 2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java create mode 100644 2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java create mode 100644 2023-07/spring-13-data-jpa/exercise/src/main/resources/application.yml create mode 100644 2023-07/spring-13-data-jpa/pom.xml create mode 100644 2023-07/spring-13-data-jpa/solution-01/.gitignore create mode 100644 2023-07/spring-13-data-jpa/solution-01/pom.xml create mode 100644 2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java create mode 100644 2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java create mode 100644 2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java create mode 100644 2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-01/src/main/resources/application.yml create mode 100644 2023-07/spring-13-data-jpa/solution-02/.gitignore create mode 100644 2023-07/spring-13-data-jpa/solution-02/pom.xml create mode 100644 2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java create mode 100644 2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java create mode 100644 2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java create mode 100644 2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-02/src/main/resources/application.yml create mode 100644 2023-07/spring-13-data-jpa/solution-03/.gitignore create mode 100644 2023-07/spring-13-data-jpa/solution-03/pom.xml create mode 100644 2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java create mode 100644 2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java create mode 100644 2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java create mode 100644 2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-03/src/main/resources/application.yml create mode 100644 2023-07/spring-13-data-jpa/solution-04/.gitignore create mode 100644 2023-07/spring-13-data-jpa/solution-04/pom.xml create mode 100644 2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java create mode 100644 2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java create mode 100644 2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java create mode 100644 2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java create mode 100644 2023-07/spring-13-data-jpa/solution-04/src/main/resources/application.yml diff --git a/2023-07/spring-13-data-jpa/.gitignore b/2023-07/spring-13-data-jpa/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/demo/.gitignore b/2023-07/spring-13-data-jpa/demo/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/demo/pom.xml b/2023-07/spring-13-data-jpa/demo/pom.xml new file mode 100644 index 00000000..c6268f5f --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + ru.otus + demo + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 00000000..bd056210 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java @@ -0,0 +1,75 @@ +package ru.otus.springdata; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.data.jpa.domain.Specification; +import ru.otus.springdata.domain.Email; +import ru.otus.springdata.domain.Person; +import ru.otus.springdata.repository.EmailRepository; +import ru.otus.springdata.repository.PersonRepository; + +import java.util.Objects; +import java.util.stream.Collectors; + +import static ru.otus.springdata.repository.PersonSpecification.emailAddressLike; +import static ru.otus.springdata.repository.PersonSpecification.nameLike; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(Main.class); + + PersonRepository personRepository = context.getBean(PersonRepository.class); + EmailRepository emailRepository = context.getBean(EmailRepository.class); + + var pushkin = new Person("Александр Сергеевич Пушкин", new Email("alex.pushkin@mail.ru")); + var block = new Person("Александр Александрович Блок", new Email("alex.block@mail.ru")); + var lermontov = new Person("Михаил Юрьевич Лермонтов", new Email("michail.lermontov@bk.ru")); + var gorbachev = new Person("Михаил Сергеевич Горбачев", new Email("gorbachev@mail.ru")); + var bulgakov = new Person("Михаил Афанасьевич Булгаков", new Email("bulgakov@mail.ru")); + + emailRepository.save(pushkin.getEmail()); + emailRepository.save(block.getEmail()); + emailRepository.save(lermontov.getEmail()); + emailRepository.save(gorbachev.getEmail()); + emailRepository.save(bulgakov.getEmail()); + + personRepository.save(pushkin); + personRepository.save(block); + personRepository.save(lermontov); + personRepository.save(gorbachev); + personRepository.save(bulgakov); + + System.out.println("\n\nИщем почту Горбачева по его id"); + emailRepository.findByPersonId(gorbachev.getId()) + .ifPresent(System.out::println); + + + System.out.println("\n\nС помощью Example ищем всех пёрсонов с именем \"Михаил\" и почтой на \"mail.ru\""); + ExampleMatcher ignoringExampleMatcher = ExampleMatcher.matchingAll() + .withMatcher("email.address", ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase()) + .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase()) + .withIgnorePaths("id", "email.id"); + + Example example = Example.of(new Person("Михаил", new Email(0, "mail.ru")), ignoringExampleMatcher); + + System.out.println(personRepository.findAll(example).stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + + System.out.println("\n\nС помощью Specification ищем всех пёрсонов с именем \"Александр\" или с почтой на \"bk.ru\""); + + Specification specification = Specification.where(nameLike("Александр")) + .or(emailAddressLike("bk.ru")); + + System.out.println(personRepository.findAll(specification).stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\n"); + + } +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 00000000..bf40bee2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java @@ -0,0 +1,26 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Email { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String address; + + public Email(String address) { + this.address = address; + } +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 00000000..499cd632 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java @@ -0,0 +1,34 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + @OneToOne(orphanRemoval = true) + @JoinColumn(name = "email_id") + private Email email; + + public Person(String name, Email email) { + this.name = name; + this.email = email; + } + +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 00000000..a76a43ff --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java @@ -0,0 +1,21 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.springdata.domain.Email; + +import java.util.Optional; + +public interface EmailRepository extends JpaRepository, EmailRepositoryCustom { + + @Query("select e from Email e where e.address = :address") + Optional findByEmailAddress(@Param("address") String email); + + @Modifying + @Transactional + @Query("update Email e set e.address = :address where e.id = :id") + void updateEmailById(@Param("id") long id, @Param("address") String address); +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java new file mode 100644 index 00000000..db7112e1 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java @@ -0,0 +1,9 @@ +package ru.otus.springdata.repository; + +import ru.otus.springdata.domain.Email; + +import java.util.Optional; + +public interface EmailRepositoryCustom { + Optional findByPersonId(long personId); +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java new file mode 100644 index 00000000..18f9ac33 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java @@ -0,0 +1,20 @@ +package ru.otus.springdata.repository; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import ru.otus.springdata.domain.Email; +import ru.otus.springdata.domain.Person; + +import java.util.Optional; + +@Repository +@RequiredArgsConstructor +public class EmailRepositoryCustomImpl implements EmailRepositoryCustom { + + private final PersonRepository personRepository; + + @Override + public Optional findByPersonId(long personId) { + return personRepository.findById(personId).map(Person::getEmail); + } +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 00000000..7bb5c825 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java @@ -0,0 +1,20 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.CrudRepository; +import ru.otus.springdata.domain.Person; + +import java.util.List; +import java.util.Optional; + +public interface PersonRepository extends JpaRepository, JpaSpecificationExecutor { + + @EntityGraph(attributePaths = "email") + List findAll(); + + Optional findByName(String s); + + Optional findByEmailAddress(String email); +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java new file mode 100644 index 00000000..3f8c67b3 --- /dev/null +++ b/2023-07/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java @@ -0,0 +1,21 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.domain.Specification; +import ru.otus.springdata.domain.Person; + +public class PersonSpecification { + + public static Specification nameLike(String name) { + if (name == null) { + return null; + } + return (root, query, cb) -> cb.like(root.get("name"), "%" + name + "%"); + } + + public static Specification emailAddressLike(String address) { + if (address == null) { + return null; + } + return (root, query, cb) -> cb.like(root.join("email").get("address"), "%" + address + "%"); + } +} diff --git a/2023-07/spring-13-data-jpa/demo/src/main/resources/application.yml b/2023-07/spring-13-data-jpa/demo/src/main/resources/application.yml new file mode 100644 index 00000000..bd5b0f98 --- /dev/null +++ b/2023-07/spring-13-data-jpa/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: false + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2023-07/spring-13-data-jpa/exercise/.gitignore b/2023-07/spring-13-data-jpa/exercise/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/exercise/pom.xml b/2023-07/spring-13-data-jpa/exercise/pom.xml new file mode 100644 index 00000000..a80f5c54 --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + ru.otus + exercise + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 00000000..dbbe3598 --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java @@ -0,0 +1,23 @@ +package ru.otus.springdata; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; + + + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(Main.class); + //PersonRepository personRepository = context.getBean(PersonRepository.class); + //EmailRepository emailRepository = context.getBean(EmailRepository.class); + + // personRepository.save(new Person("Александр Сергеевич Пушкин")); + // personRepository.save(new Person("Михаил Юрьевич Лермонтов")); + // personRepository.save(new Person("Михаил Сергеевич Горбачев")); + } + + +} diff --git a/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 00000000..5cb61fa0 --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java @@ -0,0 +1,21 @@ +package ru.otus.springdata.domain; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Email { + + private long id; + + private String address; + + public Email(String address) { + this.address = address; + } + +} diff --git a/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 00000000..b087adca --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java @@ -0,0 +1,25 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + public Person(String name) { + this.name = name; + } +} diff --git a/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 00000000..7a446b95 --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java @@ -0,0 +1,4 @@ +package ru.otus.springdata.repository; + +public interface EmailRepository { +} diff --git a/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 00000000..f8e5fc8a --- /dev/null +++ b/2023-07/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java @@ -0,0 +1,4 @@ +package ru.otus.springdata.repository; + +public interface PersonRepository { +} diff --git a/2023-07/spring-13-data-jpa/exercise/src/main/resources/application.yml b/2023-07/spring-13-data-jpa/exercise/src/main/resources/application.yml new file mode 100644 index 00000000..bd5b0f98 --- /dev/null +++ b/2023-07/spring-13-data-jpa/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: false + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2023-07/spring-13-data-jpa/pom.xml b/2023-07/spring-13-data-jpa/pom.xml new file mode 100644 index 00000000..922fc48a --- /dev/null +++ b/2023-07/spring-13-data-jpa/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + ru.otus + spring-11-data-jpa + 1.0 + + pom + + + exercise + solution-01 + solution-02 + solution-03 + solution-04 + demo + + diff --git a/2023-07/spring-13-data-jpa/solution-01/.gitignore b/2023-07/spring-13-data-jpa/solution-01/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/solution-01/pom.xml b/2023-07/spring-13-data-jpa/solution-01/pom.xml new file mode 100644 index 00000000..675c0271 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + ru.otus + solution-01 + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 00000000..4961485f --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java @@ -0,0 +1,37 @@ +package ru.otus.springdata; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import ru.otus.springdata.domain.Person; +import ru.otus.springdata.repository.PersonRepository; + +import java.util.Objects; +import java.util.stream.Collectors; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(Main.class); + + PersonRepository personRepository = context.getBean(PersonRepository.class); + + + personRepository.save(new Person("Александр Сергеевич Пушкин")); + personRepository.save(new Person("Михаил Юрьевич Лермонтов")); + personRepository.save(new Person("Михаил Сергеевич Горбачев")); + + System.out.println("\n\nИщем всех пёрсонов"); + System.out.println(personRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\nИщем Пушкина"); + personRepository.findByName("Александр Сергеевич Пушкин") + .ifPresent(System.out::println); + + + System.out.println("\n\n"); + + } +} diff --git a/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 00000000..918f052a --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java @@ -0,0 +1,24 @@ +package ru.otus.springdata.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Email { + + private long id; + + private String address; + + public Email(String address) { + this.address = address; + } +} diff --git a/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 00000000..e5905f85 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java @@ -0,0 +1,27 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + public Person(String name) { + this.name = name; + } + +} diff --git a/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 00000000..50b72f9b --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java @@ -0,0 +1,12 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.otus.springdata.domain.Email; + +import java.util.List; + +public interface EmailRepository { + + //@Override + List findAll(); +} diff --git a/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 00000000..012ded26 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java @@ -0,0 +1,15 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.repository.CrudRepository; +import ru.otus.springdata.domain.Person; + +import java.util.List; +import java.util.Optional; + +public interface PersonRepository extends CrudRepository { + + @Override + List findAll(); + + Optional findByName(String s); +} diff --git a/2023-07/spring-13-data-jpa/solution-01/src/main/resources/application.yml b/2023-07/spring-13-data-jpa/solution-01/src/main/resources/application.yml new file mode 100644 index 00000000..bd5b0f98 --- /dev/null +++ b/2023-07/spring-13-data-jpa/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: false + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2023-07/spring-13-data-jpa/solution-02/.gitignore b/2023-07/spring-13-data-jpa/solution-02/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/solution-02/pom.xml b/2023-07/spring-13-data-jpa/solution-02/pom.xml new file mode 100644 index 00000000..e77a8c1a --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + ru.otus + solution-02 + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 00000000..d25a29d2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java @@ -0,0 +1,53 @@ +package ru.otus.springdata; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import ru.otus.springdata.domain.Email; +import ru.otus.springdata.domain.Person; +import ru.otus.springdata.repository.EmailRepository; +import ru.otus.springdata.repository.PersonRepository; + +import java.util.Objects; +import java.util.stream.Collectors; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + + ConfigurableApplicationContext context = SpringApplication.run(Main.class); + PersonRepository personRepository = context.getBean(PersonRepository.class); + EmailRepository emailRepository = context.getBean(EmailRepository.class); + + var pushkinEmail = new Email("alex.pushkin@mail.ru"); + var lermontovEmail = new Email("michail.lermontov@mail.ru"); + var gorbachevEmail = new Email("gorbachev@mail.ru"); + + var pushkin = new Person("Александр Сергеевич Пушкин"); + var lermontov = new Person("Михаил Юрьевич Лермонтов"); + var gorbachev = new Person("Михаил Сергеевич Горбачев"); + + emailRepository.save(pushkinEmail); + emailRepository.save(lermontovEmail); + emailRepository.save(gorbachevEmail); + + personRepository.save(pushkin); + personRepository.save(lermontov); + personRepository.save(gorbachev); + + System.out.println("\n\nИщем всех пёрсонов"); + System.out.println(personRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\nИщем Пушкина"); + personRepository.findByName("Александр Сергеевич Пушкин") + .ifPresent(System.out::println); + + System.out.println("\n\nИщем все почты"); + System.out.println(emailRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\n"); + } +} diff --git a/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 00000000..bea8c7a5 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java @@ -0,0 +1,27 @@ +package ru.otus.springdata.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Email { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String address; + + public Email(String address) { + this.address = address; + } +} diff --git a/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 00000000..e5905f85 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java @@ -0,0 +1,27 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + public Person(String name) { + this.name = name; + } + +} diff --git a/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 00000000..3d5c3152 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java @@ -0,0 +1,13 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.springdata.domain.Email; + +import java.util.Optional; + +public interface EmailRepository extends JpaRepository{ +} diff --git a/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 00000000..cd5bb3f0 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java @@ -0,0 +1,14 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.repository.CrudRepository; +import ru.otus.springdata.domain.Person; + +import java.util.List; +import java.util.Optional; + +public interface PersonRepository extends CrudRepository { + + List findAll(); + + Optional findByName(String s); +} diff --git a/2023-07/spring-13-data-jpa/solution-02/src/main/resources/application.yml b/2023-07/spring-13-data-jpa/solution-02/src/main/resources/application.yml new file mode 100644 index 00000000..bd5b0f98 --- /dev/null +++ b/2023-07/spring-13-data-jpa/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: false + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2023-07/spring-13-data-jpa/solution-03/.gitignore b/2023-07/spring-13-data-jpa/solution-03/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/solution-03/pom.xml b/2023-07/spring-13-data-jpa/solution-03/pom.xml new file mode 100644 index 00000000..85de4f4a --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + ru.otus + solution-03 + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 00000000..a02e3e25 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java @@ -0,0 +1,55 @@ +package ru.otus.springdata; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import ru.otus.springdata.domain.Email; +import ru.otus.springdata.domain.Person; +import ru.otus.springdata.repository.EmailRepository; +import ru.otus.springdata.repository.PersonRepository; + +import java.util.Objects; +import java.util.stream.Collectors; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(Main.class); + + PersonRepository personRepository = context.getBean(PersonRepository.class); + EmailRepository emailRepository = context.getBean(EmailRepository.class); + + var pushkin = new Person("Александр Сергеевич Пушкин", new Email("alex.pushkin@mail.ru")); + var lermontov = new Person("Михаил Юрьевич Лермонтов", new Email("michail.lermontov@mail.ru")); + var gorbachev = new Person("Михаил Сергеевич Горбачев", new Email("gorbachev@mail.ru")); + + emailRepository.save(pushkin.getEmail()); + emailRepository.save(lermontov.getEmail()); + emailRepository.save(gorbachev.getEmail()); + + personRepository.save(pushkin); + personRepository.save(lermontov); + personRepository.save(gorbachev); + + System.out.println("\n\nИщем всех пёрсонов"); + System.out.println(personRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\nИщем Пушкина"); + personRepository.findByName("Александр Сергеевич Пушкин") + .ifPresent(System.out::println); + + System.out.println("\n\nИщем все почты"); + System.out.println(emailRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\nИщем Пушкина по его почте"); + personRepository.findByEmailAddress("alex.pushkin@mail.ru") + .ifPresent(System.out::println); + + System.out.println("\n\n"); + } +} diff --git a/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 00000000..bf40bee2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java @@ -0,0 +1,26 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Email { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String address; + + public Email(String address) { + this.address = address; + } +} diff --git a/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 00000000..499cd632 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java @@ -0,0 +1,34 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + @OneToOne(orphanRemoval = true) + @JoinColumn(name = "email_id") + private Email email; + + public Person(String name, Email email) { + this.name = name; + this.email = email; + } + +} diff --git a/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 00000000..16f1d0c9 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java @@ -0,0 +1,13 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.springdata.domain.Email; + +import java.util.Optional; + +public interface EmailRepository extends JpaRepository { +} diff --git a/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 00000000..a6aa8dd3 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java @@ -0,0 +1,18 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.repository.CrudRepository; +import ru.otus.springdata.domain.Person; + +import java.util.List; +import java.util.Optional; + +public interface PersonRepository extends CrudRepository { + + @EntityGraph(attributePaths = "email") + List findAll(); + + Optional findByName(String s); + + Optional findByEmailAddress(String email); +} diff --git a/2023-07/spring-13-data-jpa/solution-03/src/main/resources/application.yml b/2023-07/spring-13-data-jpa/solution-03/src/main/resources/application.yml new file mode 100644 index 00000000..bd5b0f98 --- /dev/null +++ b/2023-07/spring-13-data-jpa/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: false + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file diff --git a/2023-07/spring-13-data-jpa/solution-04/.gitignore b/2023-07/spring-13-data-jpa/solution-04/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-07/spring-13-data-jpa/solution-04/pom.xml b/2023-07/spring-13-data-jpa/solution-04/pom.xml new file mode 100644 index 00000000..9274f50e --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + ru.otus + solution-04 + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 00000000..4574b783 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java @@ -0,0 +1,64 @@ +package ru.otus.springdata; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import ru.otus.springdata.domain.Email; +import ru.otus.springdata.domain.Person; +import ru.otus.springdata.repository.EmailRepository; +import ru.otus.springdata.repository.PersonRepository; + +import java.util.Objects; +import java.util.stream.Collectors; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(Main.class); + + PersonRepository personRepository = context.getBean(PersonRepository.class); + EmailRepository emailRepository = context.getBean(EmailRepository.class); + + var pushkin = new Person("Александр Сергеевич Пушкин", new Email("alex.pushkin@mail.ru")); + var lermontov = new Person("Михаил Юрьевич Лермонтов", new Email("michail.lermontov@mail.ru")); + var gorbachev = new Person("Михаил Сергеевич Горбачев", new Email("gorbachev@mail.ru")); + + emailRepository.save(pushkin.getEmail()); + emailRepository.save(lermontov.getEmail()); + emailRepository.save(gorbachev.getEmail()); + + personRepository.save(pushkin); + personRepository.save(lermontov); + personRepository.save(gorbachev); + + System.out.println("\n\nИщем всех пёрсонов"); + System.out.println(personRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\nИщем Пушкина"); + personRepository.findByName("Александр Сергеевич Пушкин") + .ifPresent(System.out::println); + + System.out.println("\n\nИщем все почты"); + System.out.println(emailRepository.findAll().stream().map(Objects::toString) + .collect(Collectors.joining("\n"))); + + System.out.println("\n\nИщем Пушкина по его почте"); + personRepository.findByEmailAddress("alex.pushkin@mail.ru") + .ifPresent(System.out::println); + + System.out.println("\n\nОбновляем почту Лермонтову"); + System.out.println("До обновления: " + lermontov.getEmail()); + emailRepository.updateEmailById(lermontov.getId(), "michail1984@lermontov.ru"); + + System.out.println("\n\nИщем почту Лермонтова по новому адресу"); + emailRepository.findByEmailAddress("michail1984@lermontov.ru") + .ifPresent(e -> System.out.println("После обновления: " + e)); + + System.out.println("\n\n"); + + } +} diff --git a/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 00000000..bf40bee2 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java @@ -0,0 +1,26 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Email { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String address; + + public Email(String address) { + this.address = address; + } +} diff --git a/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 00000000..499cd632 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java @@ -0,0 +1,34 @@ +package ru.otus.springdata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + @OneToOne(orphanRemoval = true) + @JoinColumn(name = "email_id") + private Email email; + + public Person(String name, Email email) { + this.name = name; + this.email = email; + } + +} diff --git a/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 00000000..66b4da80 --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java @@ -0,0 +1,21 @@ +package ru.otus.springdata.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.springdata.domain.Email; + +import java.util.Optional; + +public interface EmailRepository extends JpaRepository { + + @Query("select e from Email e where e.address = :address") + Optional findByEmailAddress(@Param("address") String email); + + @Modifying + @Transactional + @Query("update Email e set e.address = :address where e.id = :id") + void updateEmailById(@Param("id") long id, @Param("address") String address); +} diff --git a/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 00000000..64579e9b --- /dev/null +++ b/2023-07/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java @@ -0,0 +1,20 @@ +package ru.otus.springdata.repository; + +import jakarta.annotation.Nonnull; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.repository.CrudRepository; +import ru.otus.springdata.domain.Person; + +import java.util.List; +import java.util.Optional; + +public interface PersonRepository extends CrudRepository { + + @Nonnull + @EntityGraph(attributePaths = "email") + List findAll(); + + Optional findByName(String s); + + Optional findByEmailAddress(String email); +} diff --git a/2023-07/spring-13-data-jpa/solution-04/src/main/resources/application.yml b/2023-07/spring-13-data-jpa/solution-04/src/main/resources/application.yml new file mode 100644 index 00000000..bd5b0f98 --- /dev/null +++ b/2023-07/spring-13-data-jpa/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: false + + show-sql: true + + +logging: + level: + ROOT: ERROR \ No newline at end of file