Tôi đang sử dụng Spring JPA để thực hiện tất cả các hoạt động cơ sở dữ liệu. Tuy nhiên tôi không biết cách chọn các cột cụ thể từ một bảng trong Spring JPA?
Ví dụ:
SELECT projectId, projectName FROM projects
Tôi đang sử dụng Spring JPA để thực hiện tất cả các hoạt động cơ sở dữ liệu. Tuy nhiên tôi không biết cách chọn các cột cụ thể từ một bảng trong Spring JPA?
Ví dụ:
SELECT projectId, projectName FROM projects
Câu trả lời:
Bạn có thể đặt nativeQuery = true
trong @Query
chú thích từ một Repository
lớp học như thế này:
public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";
@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();
Lưu ý rằng bạn sẽ phải tự làm bản đồ. Có thể dễ dàng hơn khi chỉ sử dụng tra cứu được ánh xạ thông thường như thế này trừ khi bạn thực sự chỉ cần hai giá trị đó:
public List<Project> findAll()
Có lẽ cũng đáng để xem tài liệu dữ liệu mùa xuân .
FIND_PROJECTS
) với value
tên thuộc tính (do đó nếu đây là mã của tôi, tôi sẽ phải viết nó dưới dạng @Query(value = FIND_PROJECTS, nativeQuery = true)
, v.v.
Bạn có thể sử dụng các phép chiếu từ Spring Data JPA (doc) . Trong trường hợp của bạn, tạo giao diện:
interface ProjectIdAndName{
String getId();
String getName();
}
và thêm phương thức sau vào kho lưu trữ của bạn
List<ProjectIdAndName> findAll();
Tôi không thích cú pháp đặc biệt (có vẻ hơi hack ...) nhưng đây là giải pháp tao nhã nhất mà tôi có thể tìm thấy (nó sử dụng truy vấn JPQL tùy chỉnh trong lớp kho lưu trữ JPA):
@Query("select new com.foo.bar.entity.Document(d.docId, d.filename) from Document d where d.filterCol = ?1")
List<Document> findDocumentsForListing(String filterValue);
Sau đó, tất nhiên, bạn chỉ cần cung cấp một hàm tạo cho Document
chấp nhận đó docId
& filename
như hàm tạo lập luận.
Trong tình huống của tôi, tôi chỉ cần kết quả json và điều này hiệu quả với tôi:
public interface SchoolRepository extends JpaRepository<School,Integer> {
@Query("select s.id, s.name from School s")
List<Object> getSchoolIdAndName();
}
trong Bộ điều khiển:
@Autowired
private SchoolRepository schoolRepository;
@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
List<Object> schools = schoolRepository.getSchoolIdAndName();
return schools;
}
Object
bằng một giao diện tùy chỉnh như được mô tả bởi mpr. hoạt động hoàn hảo
Trong trường hợp của tôi, tôi đã tạo một lớp thực thể riêng biệt mà không có các trường không bắt buộc (chỉ với các trường được yêu cầu).
Ánh xạ thực thể vào cùng một bảng. Bây giờ khi tất cả các cột được yêu cầu tôi sử dụng thực thể cũ, khi chỉ một số cột được yêu cầu, tôi sử dụng thực thể lite.
ví dụ
@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;
}
Bạn có thể tạo một cái gì đó như:
@Entity
@Table(name = "user")
Class UserLite{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
}
Điều này hoạt động khi bạn biết các cột để tìm nạp (và điều này sẽ không thay đổi).
sẽ không hoạt động nếu bạn cần tự động quyết định các cột.
Tôi đoán cách dễ dàng có thể là sử dụng QueryDSL , đi kèm với Spring-Data.
Sử dụng cho câu hỏi của bạn câu trả lời có thể là
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));
}}
Trình quản lý thực thể có thể được Tự động và bạn sẽ luôn làm việc với đối tượng và các cụm mà không sử dụng ngôn ngữ * QL.
Như bạn có thể thấy trong liên kết, sự lựa chọn cuối cùng dường như, đối với tôi, thanh lịch hơn, đó là sử dụng DTO để lưu trữ kết quả. Áp dụng cho ví dụ của bạn sẽ là:
JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));
Xác định ProjectDTO là:
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(){....}
}
Với các phiên bản Spring mới hơn, người ta có thể làm như sau:
Nếu không sử dụng truy vấn gốc, điều này có thể được thực hiện như dưới đây:
public interface ProjectMini {
String getProjectId();
String getProjectName();
}
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query("SELECT p FROM Project p")
List<ProjectMini> findAllProjectsMini();
}
Sử dụng truy vấn gốc tương tự có thể được thực hiện như dưới đây:
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query(value = "SELECT projectId, projectName FROM project", nativeQuery = true)
List<ProjectMini> findAllProjectsMini();
}
Để biết chi tiết kiểm tra tài liệu
Theo tôi đây là giải pháp tuyệt vời:
interface PersonRepository extends Repository<Person, UUID> {
<T> Collection<T> findByLastname(String lastname, Class<T> type);
}
và sử dụng nó như vậy
void someMethod(PersonRepository people) {
Collection<Person> aggregates =
people.findByLastname("Matthews", Person.class);
Collection<NamesOnly> aggregates =
people.findByLastname("Matthews", NamesOnly.class);
}
Sử dụng Spring Data JPA có một điều khoản để chọn các cột cụ thể từ cơ sở dữ liệu
---- Trong DAOImpl ----
@Override
@Transactional
public List<Employee> getAllEmployee() throws Exception {
LOGGER.info("Inside getAllEmployee");
List<Employee> empList = empRepo.getNameAndCityOnly();
return empList;
}
---- Trong Repo ----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
@Query("select e.name, e.city from Employee e" )
List<Employee> getNameAndCityOnly();
}
Nó hoạt động 100% trong trường hợp của tôi. Cảm ơn.
Bạn có thể sử dụng JPQL:
TypedQuery <Object[]> query = em.createQuery(
"SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);
List<Object[]> results = query.getResultList();
hoặc bạn có thể sử dụng truy vấn sql bản địa.
Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();
Bạn có thể áp dụng mã dưới đây trong lớp giao diện kho lưu trữ của bạn.
entityname có nghĩa là tên bảng cơ sở dữ liệu của bạn giống như các dự án. Và Danh sách có nghĩa là Dự án là lớp Thực thể trong Dự án của bạn.
@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);
Bạn có thể sử dụng câu trả lời được đề xuất bởi @jombie và:
findAll()
phương thức cho mục đích này mà sử dụng tên bạn chọn;List
tham số với giao diện mới của bạn (ví dụ List<SmallProject>
).