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
java
jpa
spring-data-jpa
pengguna1817436
sumber
sumber
Jawaban:
Anda dapat mengatur
nativeQuery = true
dalam@Query
penjelasan dariRepository
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 .
sumber
FIND_PROJECTS
) denganvalue
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();
sumber
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 acceptdocId
&filename
as constructor args.sumber
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; }
sumber
Object
dengan antarmuka khusus seperti yang dijelaskan oleh mpr. bekerja dengan sempurnaDalam 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.
sumber
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(){....} }
sumber
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
sumber
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.
sumber
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); }
sumber
Anda dapat menerapkan kode di bawah ini di kelas antarmuka repositori 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);
sumber
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();
sumber
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);
sumber
Menggunakan Native Query:
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects"); List result = query.getResultList();
sumber
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 (misalnyaList<SmallProject>
).sumber