如何使JPA @query与其中具有另一个投影的投影一起使用

时间:2019-04-25 01:08:36

标签: java spring hibernate jpa jpql

我正在尝试在JPA的@query上进行投影工作,并将连接的列也作为另一个项目。

说,我有2个实体:课程和学生以及学生可以开设许多课程,并且外键在课程表上:

student(id, name, email, age, grade, uuid)

course(id, name, uuid, student_id)

我有这样的预测:

public interface CourseProjection {
  UUID getUuid();
}

然后

public interface StudentProjection {
  String getName();
  String getEmail();
  Set<CourseProjection> getCourses();
}

在实体中:

public class Student {
    // other code
    @OneToMany(mappedBy = "student")
    private Set<Course> courses = new LinkedHashSet<>();
}

我需要对多列(包括课程uuid)进行LIKE搜索。 我还需要分页。 因此,在存储库中,我想执行以下操作:

@Repository
interface StudentRepository extends JpaRepository<Student, UUID> {
  @Query(
     value = "SELECT * FROM student s LEFT JOIN courses c ON s.id = 
     c.student_id WHERE s.name LIKE %str% OR c.student_id::text LIKE %str%",
     nativeQuery = true
  )
  Page<StudentProjection> findAllByKeyword(String keyword, Pageable pageable);
}

我希望结果看起来像这样:

[
  {
    name: John
    email: johndoe@gmail.com
    courses: [
      "course_uuid_1",
      "course_uuid_2"
    ]
  }
  {
    ...
  }
]

关于如何实现此目标的任何建议?

2 个答案:

答案 0 :(得分:0)

您是否尝试过:

  1. 接口StudentRepository扩展了JpaRepository,excerptProjection = projectionName.class 要将这个投影很难存储到存储库中。

  2. Https:domain / contextpath / students / search / findAllByKeyword?projection = projectionName 为其余api应用投影。 并且您需要添加以下更多配置:

     @Configuration
     public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
         @Override
         public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {   
    
              config.getProjectionConfiguration().addProjection(projectionName.class));  
    
         }
     }
    

答案 1 :(得分:0)

将 Spring Data 嵌套闭合投影自定义查询结合使用时,您需要确保:

  1. 嵌套投影
  2. 显式声明列别名

我遇到了同样的问题,试图找出解决方法。如果您刚刚完成,您的代码就会完全正常运行:

public interface StudentProjection {
    String getName();
    String getEmail();
    Set<CourseProjection> getCourses();
    
    interface CourseProjection {
        UUID getUuid();
    }
}

然后像这样使用您的自定义查询:

@Query(nativeQuery = true,
            value = "SELECT s.name as name, s.email as email, c.uuid as uuid "
                    + "FROM student s "
                    + "LEFT JOIN courses c ON s.id = c.student_id "
                    + "WHERE s.name LIKE %str% OR c.student_id::text LIKE %str%")
Page<StudentProjection> findAllByKeyword(String keyword, Pageable pageable);

我也认为没有必要使用本机查询,您可以使用 HQL/JPQL 甚至 Spring Data query methods 代替。

我知道这个问题有点老了,但它可以对其他人有所帮助。