[java] 특정 열을 선택하는 Spring JPA

Spring JPA를 사용하여 모든 데이터베이스 작업을 수행하고 있습니다. 그러나 Spring JPA의 테이블에서 특정 열을 선택하는 방법을 모르겠습니다.

예를 들면 다음과 같습니다.
SELECT projectId, projectName FROM projects



답변

다음 과 같은 클래스 nativeQuery = true에서 @Query주석을 설정할 수 있습니다 Repository.

public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";

@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();

그래도 맵핑을 직접 수행해야합니다. 실제로 두 값만 필요하지 않으면 다음과 같이 정규 매핑 조회를 사용하는 것이 더 쉽습니다.

public List<Project> findAll()

Spring 데이터 문서 도 살펴볼 가치가 있습니다.


답변

Spring Data JPA (doc)의 투영을 사용할 수 있습니다 . 귀하의 경우 인터페이스를 작성하십시오.

interface ProjectIdAndName{
    String getId();
    String getName();
}

저장소에 다음 방법을 추가하십시오.

List<ProjectIdAndName> findAll();


답변

특히 구문이 마음에 들지 않지만 (약간 해키처럼 보입니다 …) 이것은 내가 찾을 수있는 가장 우아한 솔루션입니다 (JPA 리포지토리 클래스에서 사용자 정의 JPQL 쿼리 사용).

@Query("select new com.foo.bar.entity.Document(d.docId, d.filename) from Document d where d.filterCol = ?1")
List<Document> findDocumentsForListing(String filterValue);

그런 다음 물론 & 생성자 인수 Document를 허용 하는 생성자를 제공하면 됩니다.docIdfilename


답변

내 상황에서는 json 결과 만 필요하며 이것은 나를 위해 작동합니다.

public interface SchoolRepository extends JpaRepository<School,Integer> {
    @Query("select s.id, s.name from School s")
    List<Object> getSchoolIdAndName();
}

컨트롤러에서 :

@Autowired
private SchoolRepository schoolRepository;

@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
    List<Object> schools = schoolRepository.getSchoolIdAndName();
    return schools;
}


답변

필자의 경우 필자는 필요하지 않은 필드 (필수 필드 만)없이 별도의 엔티티 클래스를 만들었습니다.

엔티티를 동일한 테이블에 맵핑하십시오. 이제 모든 열이 필요할 때 이전 엔터티를 사용하고 일부 열만 필요한 경우 라이트 엔터티를 사용합니다.

예 :

@Entity
@Table(name = "user")
Class User{
         @Column(name = "id", unique=true, nullable=false)
         int id;
         @Column(name = "name", nullable=false)
         String name;
         @Column(name = "address", nullable=false)
         Address address;
}

다음과 같은 것을 만들 수 있습니다.

@Entity
@Table(name = "user")
Class UserLite{
         @Column(name = "id", unique=true, nullable=false)
         int id;
         @Column(name = "name", nullable=false)
         String name;
}

가져올 열을 알고있을 때 작동합니다 (변경되지 않음).

열을 동적으로 결정 해야하는 경우 작동하지 않습니다.


답변

Spring-Data와 함께 제공되는 QueryDSL을 사용하는 것이 가장 쉬운 방법이라고 생각합니다 .

귀하의 질문에 대한 답은

JPAQuery query = new JPAQuery(entityManager);
List<Tuple> result = query.from(projects).list(project.projectId, project.projectName);
for (Tuple row : result) {
 System.out.println("project ID " + row.get(project.projectId));
 System.out.println("project Name " + row.get(project.projectName));
}}

엔티티 관리자는 자동 와이어 링 될 수 있으며 * QL 언어를 사용하지 않고 항상 오브젝트 및 클래스로 작업합니다.

링크에서 볼 수 있듯이 마지막 선택은 거의 나에게 더 우아합니다. 즉, 결과를 저장하기 위해 DTO를 사용하는 것 같습니다. 다음과 같은 예에 적용하십시오.

JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));

ProjectDTO를 다음과 같이 정의 :

class ProjectDTO {

 private long id;
 private String name;
 @QueryProjection
 public ProjectDTO(long projectId, String projectName){
   this.id = projectId;
   this.name = projectName;
 }
 public String getProjectId(){ ... }
 public String getProjectName(){....}
}


답변

최신 스프링 버전을 사용하면 다음과 같이 할 수 있습니다.

기본 쿼리를 사용하지 않는 경우 다음과 같이 수행 할 수 있습니다.

public interface ProjectMini {
    String getProjectId();
    String getProjectName();
}

public interface ProjectRepository extends JpaRepository<Project, String> {
    @Query("SELECT p FROM Project p")
    List<ProjectMini> findAllProjectsMini();
}

기본 쿼리를 사용하여 아래와 같이 수행 할 수 있습니다.

public interface ProjectRepository extends JpaRepository<Project, String> {
    @Query(value = "SELECT projectId, projectName FROM project", nativeQuery = true)
    List<ProjectMini> findAllProjectsMini();
}

자세한 내용은 문서를 확인하십시오.