diff --git a/2023-09/spring-13-data-jpa/.gitignore b/2023-09/spring-13-data-jpa/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/demo/.gitignore b/2023-09/spring-13-data-jpa/demo/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/demo/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/demo/pom.xml b/2023-09/spring-13-data-jpa/demo/pom.xml new file mode 100644 index 000000000..c6268f5fe --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 000000000..bd0562102 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 000000000..bf40bee22 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 000000000..499cd632b --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 000000000..a76a43ff2 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustom.java new file mode 100644 index 000000000..db7112e19 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/EmailRepositoryCustomImpl.java new file mode 100644 index 000000000..18f9ac33b --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 000000000..7bb5c8252 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java b/2023-09/spring-13-data-jpa/demo/src/main/java/ru/otus/springdata/repository/PersonSpecification.java new file mode 100644 index 000000000..3f8c67b35 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/demo/src/main/resources/application.yml b/2023-09/spring-13-data-jpa/demo/src/main/resources/application.yml new file mode 100644 index 000000000..bd5b0f984 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/.gitignore b/2023-09/spring-13-data-jpa/exercise/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/exercise/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/exercise/pom.xml b/2023-09/spring-13-data-jpa/exercise/pom.xml new file mode 100644 index 000000000..a80f5c546 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java b/2023-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 000000000..dbbe35980 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java b/2023-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 000000000..5cb61fa0b --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java b/2023-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 000000000..b087adca1 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 000000000..7a446b959 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-09/spring-13-data-jpa/exercise/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 000000000..f8e5fc8ad --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/exercise/src/main/resources/application.yml b/2023-09/spring-13-data-jpa/exercise/src/main/resources/application.yml new file mode 100644 index 000000000..bd5b0f984 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/pom.xml b/2023-09/spring-13-data-jpa/pom.xml new file mode 100644 index 000000000..922fc48a7 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/.gitignore b/2023-09/spring-13-data-jpa/solution-01/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/solution-01/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/solution-01/pom.xml b/2023-09/spring-13-data-jpa/solution-01/pom.xml new file mode 100644 index 000000000..675c02716 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java b/2023-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 000000000..4961485f2 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java b/2023-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 000000000..918f052a9 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java b/2023-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 000000000..e5905f85d --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 000000000..50b72f9bb --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-09/spring-13-data-jpa/solution-01/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 000000000..012ded267 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-01/src/main/resources/application.yml b/2023-09/spring-13-data-jpa/solution-01/src/main/resources/application.yml new file mode 100644 index 000000000..bd5b0f984 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/.gitignore b/2023-09/spring-13-data-jpa/solution-02/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/solution-02/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/solution-02/pom.xml b/2023-09/spring-13-data-jpa/solution-02/pom.xml new file mode 100644 index 000000000..e77a8c1af --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java b/2023-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 000000000..d25a29d2c --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java b/2023-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 000000000..bea8c7a51 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java b/2023-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 000000000..e5905f85d --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 000000000..3d5c31529 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-09/spring-13-data-jpa/solution-02/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 000000000..cd5bb3f0d --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-02/src/main/resources/application.yml b/2023-09/spring-13-data-jpa/solution-02/src/main/resources/application.yml new file mode 100644 index 000000000..bd5b0f984 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/.gitignore b/2023-09/spring-13-data-jpa/solution-03/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/solution-03/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/solution-03/pom.xml b/2023-09/spring-13-data-jpa/solution-03/pom.xml new file mode 100644 index 000000000..85de4f4af --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java b/2023-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 000000000..a02e3e256 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java b/2023-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 000000000..bf40bee22 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java b/2023-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 000000000..499cd632b --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 000000000..16f1d0c9f --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-09/spring-13-data-jpa/solution-03/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 000000000..a6aa8dd30 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-03/src/main/resources/application.yml b/2023-09/spring-13-data-jpa/solution-03/src/main/resources/application.yml new file mode 100644 index 000000000..bd5b0f984 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/.gitignore b/2023-09/spring-13-data-jpa/solution-04/.gitignore new file mode 100644 index 000000000..e62c33c2a --- /dev/null +++ b/2023-09/spring-13-data-jpa/solution-04/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2023-09/spring-13-data-jpa/solution-04/pom.xml b/2023-09/spring-13-data-jpa/solution-04/pom.xml new file mode 100644 index 000000000..9274f50e6 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java b/2023-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/Main.java new file mode 100644 index 000000000..4574b7837 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java b/2023-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Email.java new file mode 100644 index 000000000..bf40bee22 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java b/2023-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/domain/Person.java new file mode 100644 index 000000000..499cd632b --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java b/2023-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/EmailRepository.java new file mode 100644 index 000000000..66b4da801 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java b/2023-09/spring-13-data-jpa/solution-04/src/main/java/ru/otus/springdata/repository/PersonRepository.java new file mode 100644 index 000000000..64579e9b6 --- /dev/null +++ b/2023-09/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-09/spring-13-data-jpa/solution-04/src/main/resources/application.yml b/2023-09/spring-13-data-jpa/solution-04/src/main/resources/application.yml new file mode 100644 index 000000000..bd5b0f984 --- /dev/null +++ b/2023-09/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