Saya menggunakan Spring JPA untuk melakukan semua operasi database. Namun saya tidak tahu cara memilih kolom tertentu dari tabel di Spring JPA?
Sebagai contoh:
SELECT projectId, projectName FROM projects
Saya menggunakan Spring JPA untuk melakukan semua operasi database. Namun saya tidak tahu cara memilih kolom tertentu dari tabel di Spring JPA?
Sebagai contoh:
SELECT projectId, projectName FROM projects
Jawaban:
Anda dapat mengatur nativeQuery = true
dalam @Query
penjelasan dari Repository
kelas seperti ini:
public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";
@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();
Perhatikan bahwa Anda harus melakukan pemetaan sendiri. Mungkin lebih mudah untuk menggunakan pencarian yang dipetakan biasa seperti ini kecuali Anda benar-benar hanya membutuhkan dua nilai tersebut:
public List<Project> findAll()
Mungkin ada baiknya juga melihat dokumen data Spring .
FIND_PROJECTS
) dengan value
nama atribut (maka jika ini adalah kode saya, saya harus menuliskannya sebagai @Query(value = FIND_PROJECTS, nativeQuery = true)
, dll.
Anda dapat menggunakan proyeksi dari Spring Data JPA (doc) . Dalam kasus Anda, buat antarmuka:
interface ProjectIdAndName{
String getId();
String getName();
}
dan tambahkan metode berikut ke repositori Anda
List<ProjectIdAndName> findAll();
Saya tidak suka sintaks secara khusus (ini terlihat sedikit hacky ...) tetapi ini adalah solusi paling elegan yang dapat saya temukan (ini menggunakan kueri JPQL khusus di kelas repositori 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);
Kemudian tentu saja, Anda hanya perlu menyediakan konstruktor untuk Document
yang accept docId
& filename
as constructor args.
Dalam situasi saya, saya hanya membutuhkan hasil json, dan ini berfungsi untuk saya:
public interface SchoolRepository extends JpaRepository<School,Integer> {
@Query("select s.id, s.name from School s")
List<Object> getSchoolIdAndName();
}
di Controller:
@Autowired
private SchoolRepository schoolRepository;
@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
List<Object> schools = schoolRepository.getSchoolIdAndName();
return schools;
}
Object
dengan antarmuka khusus seperti yang dijelaskan oleh mpr. bekerja dengan sempurna
Dalam kasus saya, saya membuat kelas entitas terpisah tanpa bidang yang tidak diperlukan (hanya dengan bidang yang diperlukan).
Petakan entitas ke tabel yang sama. Sekarang ketika semua kolom diperlukan saya menggunakan entitas lama, ketika hanya beberapa kolom yang diperlukan, saya menggunakan entitas lite.
misalnya
@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;
}
Anda dapat membuat sesuatu seperti:
@Entity
@Table(name = "user")
Class UserLite{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
}
Ini berfungsi ketika Anda mengetahui kolom yang akan diambil (dan ini tidak akan berubah).
tidak akan berfungsi jika Anda perlu menentukan kolom secara dinamis.
Saya rasa cara termudah adalah menggunakan QueryDSL , yang disertakan dengan Spring-Data.
Menggunakan pertanyaan Anda, jawabannya bisa
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));
}}
Manajer entitas dapat menjadi Autowired dan Anda akan selalu bekerja dengan objek dan klas tanpa menggunakan bahasa * QL.
Seperti yang Anda lihat di tautan, pilihan terakhir tampaknya, bagi saya, lebih elegan, yaitu menggunakan DTO untuk menyimpan hasilnya. Terapkan ke contoh Anda yang akan menjadi:
JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));
Mendefinisikan ProjectDTO sebagai:
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(){....}
}
Dengan versi Spring yang lebih baru, Seseorang dapat melakukan hal berikut:
Jika tidak menggunakan kueri asli, ini dapat dilakukan seperti di bawah ini:
public interface ProjectMini {
String getProjectId();
String getProjectName();
}
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query("SELECT p FROM Project p")
List<ProjectMini> findAllProjectsMini();
}
Menggunakan kueri asli, hal yang sama dapat dilakukan seperti di bawah ini:
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query(value = "SELECT projectId, projectName FROM project", nativeQuery = true)
List<ProjectMini> findAllProjectsMini();
}
Untuk detail, periksa dokumennya
Menggunakan Spring Data JPA ada ketentuan untuk memilih kolom tertentu dari database
---- Dalam DAOImpl ----
@Override
@Transactional
public List<Employee> getAllEmployee() throws Exception {
LOGGER.info("Inside getAllEmployee");
List<Employee> empList = empRepo.getNameAndCityOnly();
return empList;
}
---- Dalam Repo ----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
@Query("select e.name, e.city from Employee e" )
List<Employee> getNameAndCityOnly();
}
Ini berhasil 100% dalam kasus saya. Terima kasih.
Menurut saya ini adalah solusi yang bagus:
interface PersonRepository extends Repository<Person, UUID> {
<T> Collection<T> findByLastname(String lastname, Class<T> type);
}
dan menggunakannya seperti itu
void someMethod(PersonRepository people) {
Collection<Person> aggregates =
people.findByLastname("Matthews", Person.class);
Collection<NamesOnly> aggregates =
people.findByLastname("Matthews", NamesOnly.class);
}
Anda dapat menerapkan kode di bawah ini di kelas antarmuka repositori Anda.
nama entitas berarti nama tabel database Anda seperti proyek. Dan Daftar berarti Proyek adalah kelas Entitas di Proyek Anda.
@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);
Anda dapat menggunakan JPQL:
TypedQuery <Object[]> query = em.createQuery(
"SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);
List<Object[]> results = query.getResultList();
atau Anda dapat menggunakan kueri sql asli.
Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();
Dimungkinkan untuk menentukan null
sebagai nilai bidang dalam sql asli.
@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);
Menggunakan Native Query:
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();
Anda dapat menggunakan jawaban yang disarankan oleh @jombie, dan:
findAll()
metode untuk tujuan ini tetapi gunakan nama pilihan Anda;List
parameter dengan antarmuka baru Anda (misalnya List<SmallProject>
).