From 1f0dfe7dddbfab22d1fde22329057e2145c0f588 Mon Sep 17 00:00:00 2001 From: stvort Date: Sat, 2 Apr 2022 14:25:20 +0400 Subject: [PATCH] 2022-02 spring-09-jpql updated --- .../OtusStudentRepositoryJpaTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/2022-02/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaTest.java b/2022-02/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaTest.java index da64c75f..c02c46af 100644 --- a/2022-02/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaTest.java +++ b/2022-02/spring-09-jpql/jpql-class-work/jpql-solution-final/src/test/java/ru/otus/example/ormdemo/repositories/OtusStudentRepositoryJpaTest.java @@ -2,14 +2,21 @@ package ru.otus.example.ormdemo.repositories; import lombok.val; import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.context.annotation.Import; +import org.springframework.test.annotation.DirtiesContext; import ru.otus.example.ormdemo.models.OtusStudent; +import java.lang.reflect.Field; +import java.util.concurrent.atomic.AtomicInteger; + import static org.assertj.core.api.Assertions.assertThat; @DisplayName("Репозиторий на основе Jpa для работы со студентами ") @@ -37,6 +44,7 @@ class OtusStudentRepositoryJpaTest { .usingRecursiveComparison().isEqualTo(expectedStudent); } + @DisplayName("должен загружать список всех студентов с полной информацией о них") @Test void shouldReturnCorrectStudentsListWithAllInfo() { @@ -55,4 +63,51 @@ class OtusStudentRepositoryJpaTest { System.out.println("----------------------------------------------------------------------------------------------------------\n\n\n\n"); assertThat(sessionFactory.getStatistics().getPrepareStatementCount()).isEqualTo(EXPECTED_QUERIES_COUNT); } + + @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) + @DisplayName("должен загружать ожидаемый список студентов по номеру страницы") + @Test + void shouldReturnCorrectStudentsListByPage() { + AtomicInteger studentsSelectionsCount = new AtomicInteger(0); + applyCustomSqlStatementLogger(new SqlStatementLogger(true, false, false, 0) { + @Override + public void logStatement(String statement) { + if (!statement.contains("count") && statement.contains("from otus_students")) { + studentsSelectionsCount.incrementAndGet(); + assertThat(statement).contains("offset").contains("limit"); + } + super.logStatement(statement); + } + }); + + + var studentsCount = em.getEntityManager() + .createQuery("select count(s) from OtusStudent s", Long.class).getSingleResult(); + var pageNum = 2; + var pageSize = 3; + var pagesCount = (long) Math.ceil(studentsCount * 1d / pageSize); + + var query = em.getEntityManager().createQuery("select s from OtusStudent s ", OtusStudent.class); + // Так не будет offset + limit из-за того, что студент может занимать больше одной строки набора данных + // var query = em.getEntityManager().createQuery("select s from OtusStudent s join fetch s.courses c", OtusStudent.class); + var students = query.setFirstResult(pageNum * pageSize).setMaxResults(pageSize).getResultList(); + + assertThat(pagesCount).isEqualTo(4); + assertThat(students).isNotNull().hasSize(pageSize); + assertThat(studentsSelectionsCount.get()).isEqualTo(1); + } + + private void applyCustomSqlStatementLogger(SqlStatementLogger customSqlStatementLogger) { + StandardServiceRegistry serviceRegistry = em.getEntityManager().getEntityManagerFactory() + .unwrap(SessionFactory.class).getSessionFactoryOptions().getServiceRegistry(); + var jdbcServices = serviceRegistry.getService(JdbcServices.class); + try { + Field field = jdbcServices.getClass().getDeclaredField("sqlStatementLogger"); + field.setAccessible(true); + field.set(jdbcServices, customSqlStatementLogger); + } catch (Exception e) { + e.printStackTrace(); + } + } + } \ No newline at end of file