문제
내가 사용하는 봄 JPA 을 수행하는 모든 데이터베이스 작업입니다.그러나 내가 알지 못하는 방법을 선택하려면 특정 테이블에 있는 열을 봄 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 Data 문서 도
다른 팁
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
를 생성자 args로 허용하는 generacodicicetagcode에 대한 생성자를 제공해야합니다.
내 상황에서는 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;
}
. 내 경우에 필드가 필요하지 않은 필드없이 별도의 엔티티 클래스를 만들었습니다 (필요한 필드 만 해당).
엔티티를 동일한 테이블에 매핑합니다. 이제 모든 열이 필요할 때 오래된 엔티티를 사용합니다. 일부 열만 필요한 경우 Lite 엔터티를 사용합니다.
e.g.
@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;
}
.
이는 가져 오기를 알고있을 때 작동합니다 (그리고 이것은 변경되지 않을 것입니다).
열을 동적으로 결정 해야하는 경우 작동하지 않습니다.
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(){....}
}
. 내 의견으로 이것은 훌륭한 해결책입니다 :
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);
}
. 최신 스프링 버전은 다음과 같이 할 수 있습니다.
기본 쿼리를 사용하지 않는 경우 다음과 같이 수행 할 수 있습니다.
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();
}
.
자세한 내용은 문서
Using Spring Data JPA there is a provision to select specific columns from database
---- In DAOImpl ----
@Override
@Transactional
public List<Employee> getAllEmployee() throws Exception {
LOGGER.info("Inside getAllEmployee");
List<Employee> empList = empRepo.getNameAndCityOnly();
return empList;
}
---- In Repo ----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
@Query("select e.name, e.city from Employee e" )
List<Employee> getNameAndCityOnly();
}
It worked 100% in my case.
Thanks.
. 기본 SQL에서 필드 값으로 null
를 지정할 수 있습니다.
@Query(value = "select p.id, p.uid, p.title, null as documentation, p.ptype " +
" from projects p " +
"where p.uid = (:uid)" +
" and p.ptype = 'P'", nativeQuery = true)
Project findInfoByUid(@Param("uid") String uid);
. 리포지토리 인터페이스 클래스에 아래 코드를 적용 할 수 있습니다.
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);
. 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();
. 기본 쿼리 사용 :
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();
. 당신이 사용할 수 있습 응답이 제안@jombie 및:
- 소에서 인터페이스는 별도의 파일을 외부터베이스
- 사용 네이티브 쿼리지(선택에 의존하의 필요);
- 지 않 override
findAll()
방법을 이 목적으로만 사용하여 당신의 선택의 이름; - 기억을 반환
List
매개 변수화와 함께 새로운 인터페이스(예:List<SmallProject>
).