Spring Data - Пользовательский DTO-запрос с фильтрацией - PullRequest
2 голосов
/ 18 июня 2019

У меня сложное приложение, и мне нужно извлечь и отфильтровать 1000 ~ 5000 объектов для экспорта в xls. Каждый объект имеет несколько рвенных отношений (они нужны мне для экспорта).

Если я получаю все объекты и их отношения как есть, я получаю некоторую ошибку переполнения стека.

Обычно, когда мне нужно сделать большой экспорт, чтобы сделать его более эффективным, я использую объект DTO с @Query, подобным этому:

public interface myRepository extends JpaRepository<Car, Long> {

    @Query("SELECT new com.blabla.myCustomObject(p.name, p.surname, c.model, c.number ...) "
            + "FROM Car c "
            + "LEFT JOIN c.person p "
            + "WHERE ... ")
    List<myCustomObject> getExportCustomObject();
}

Проблема в том, что @Query является статическим, и я хочу добавить динамический фильтр в мой запрос (спецификации, критерии или другая система ...)

Как это сделать?

Ответы [ 3 ]

0 голосов
/ 18 июня 2019

Вы можете использовать аннотацию @Param для передачи динамических значений в HQL, например:

@Query("SELECT new com.blabla.myCustomObject(p.name, p.surname, c.model, c.number ...) "
        + "FROM Car c "
        + "LEFT JOIN c.person p "
        + "WHERE c.status = :status AND p.name = :name")
List<myCustomObject> getExportCustomObject(
    @Param("status") Integer status, 
    @Param("name") String name
);
0 голосов
/ 18 июня 2019

Ниже приведен один из возможных способов добавления смещения и ограничения в ваш запрос, который можно сделать динамическим с помощью заполнителей.

Ниже приведен пример псевдокода для справки:

Dao Layer:

  @Query(value="SELECT e FROM tablename e WHERE  condition_here ORDER BY e.id offset :offset limit:limit ")
    public returnType yourMethod(String name, int offset, int limit);

Service Layer:

long count = number of records in db.

int a = // number of records to be fetched on each iterations

int num_iterations = count % a ;

int additionalrecords = count / a;

int start= 0;
while(num_iterations>0)
{
     dao.yourMethod(start,a);
     start = start+a;
     count--;

     // write your data to excel here
}

 dao.yourMethod(start,additionalrecords);

Надеюсь, это полезно.

0 голосов
/ 18 июня 2019

Спецификация не может быть использована, потому что это только предложение where.

Но вы можете использовать Criteria API. Вот пример. BasicTeacherInfo - это DTO:

CriteriaQuery<BasicTeacherInfo> query = cb.createQuery(BasicTeacherInfo.class);
Root<Teacher> teacher = query.from(Teacher.class);
        query.multiselect(teacher.get("firstName"),teacher.get("lastName"));

List<BasicTeacherInfo> results = em.createQuery(query).getResultList();
...