Spring JPA를 사용하여 모든 데이터베이스 작업을 수행하고 있습니다. 그러나 Spring JPA의 테이블에서 특정 열을 선택하는 방법을 모르겠습니다.
예를 들면 다음과 같습니다.
SELECT projectId, projectName FROM projects
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 데이터 문서 도 살펴볼 가치가 있습니다.
FIND_PROJECTS
)을 value
속성 이름 으로 한정해야했다. (그래서 이것이 내 코드라면 다음과 같이 작성해야했다 @Query(value = FIND_PROJECTS, nativeQuery = true)
.)
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
를 허용 하는 생성자를 제공하면 됩니다.docId
filename
내 상황에서는 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;
}
Object
mpr에서 설명한대로 사용자 정의 인터페이스로 대체해야합니다 . 완벽하게 작동
필자의 경우 필자는 필요하지 않은 필드 (필수 필드 만)없이 별도의 엔티티 클래스를 만들었습니다.
엔티티를 동일한 테이블에 맵핑하십시오. 이제 모든 열이 필요할 때 이전 엔터티를 사용하고 일부 열만 필요한 경우 라이트 엔터티를 사용합니다.
예 :
@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();
}
자세한 내용은 문서를 확인하십시오.
내 생각에 이것은 훌륭한 해결책입니다.
interface PersonRepository extends Repository<Person, UUID> {
<T> Collection<T> findByLastname(String lastname, Class<T> type);
}
그렇게 사용
void someMethod(PersonRepository people) {
Collection<Person> aggregates =
people.findByLastname("Matthews", Person.class);
Collection<NamesOnly> aggregates =
people.findByLastname("Matthews", NamesOnly.class);
}
Spring Data JPA를 사용하면 데이터베이스에서 특정 열을 선택하는 조항이 있습니다.
---- DAOImpl에서 ----
@Override
@Transactional
public List<Employee> getAllEmployee() throws Exception {
LOGGER.info("Inside getAllEmployee");
List<Employee> empList = empRepo.getNameAndCityOnly();
return empList;
}
---- 레포에서 ----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
@Query("select e.name, e.city from Employee e" )
List<Employee> getNameAndCityOnly();
}
내 경우에는 100 % 작동했습니다. 감사.
JPQL을 사용할 수 있습니다.
TypedQuery <Object[]> query = em.createQuery(
"SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);
List<Object[]> results = query.getResultList();
또는 네이티브 SQL 쿼리를 사용할 수 있습니다.
Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();
리포지토리 인터페이스 클래스에 아래 코드를 적용 할 수 있습니다.
entityname은 프로젝트와 같은 데이터베이스 테이블 이름을 의미합니다. 그리고 목록은 프로젝트가 프로젝트에서 프로젝트가 엔티티 클래스임을 의미합니다.
@Query(value="select p from #{#entityName} p where p.id=:projectId and p.projectName=:projectName")
List<Project> findAll(@Param("projectId") int projectId, @Param("projectName") String projectName);
기본 쿼리 사용 :
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();