ฉันใช้ 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)
ฯลฯ
คุณสามารถใช้การประมาณการจากฤดูใบไม้ผลิข้อมูล JPA (doc) ในกรณีของคุณสร้างอินเตอร์เฟส:
interface ProjectIdAndName{
String getId();
String getName();
}
และเพิ่มวิธีการต่อไปนี้ไปยังที่เก็บของคุณ
List<ProjectIdAndName> findAll();
ฉันไม่ชอบไวยากรณ์โดยเฉพาะ (ดูเหมือนแฮ็คเล็กน้อย ... ) แต่นี่เป็นโซลูชันที่หรูหราที่สุดที่ฉันสามารถหาได้ (ใช้การสืบค้น JPQL แบบกำหนดเองในคลาสที่เก็บ 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);
แน่นอนว่าคุณต้องจัดทำคอนสตรัคเตอร์สำหรับการ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 ทำงานได้อย่างไร้ที่ติ
ในกรณีของฉันฉันสร้างคลาสเอนทิตีแยกต่างหากโดยไม่มีฟิลด์ที่ไม่จำเป็น (เฉพาะกับฟิลด์ที่จำเป็น)
แมปเอนทิตีกับตารางเดียวกัน ตอนนี้เมื่อต้องการคอลัมน์ทั้งหมดฉันใช้เอนทิตีเก่าเมื่อต้องการเพียงบางคอลัมน์เท่านั้นฉันใช้เอนทิตี lite
เช่น
@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ซึ่งมาพร้อมกับ Spring-Data
ใช้กับคำถามของคุณคำตอบได้
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));
}}
ผู้จัดการเอนทิตีสามารถ Autowired และคุณจะทำงานกับวัตถุและ clases โดยไม่ต้องใช้ภาษา * 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(){....}
}
ด้วย Spring เวอร์ชั่นที่ใหม่กว่า One สามารถทำได้ดังนี้:
หากไม่ได้ใช้เคียวรีแบบดั้งเดิมคุณสามารถทำได้ดังนี้:
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;
}
---- ใน Repo ----
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();
มันเป็นไปได้ที่จะระบุว่าnull
เป็นค่าของเขตข้อมูลใน sql พื้นเมือง
@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);
คุณสามารถใช้รหัสด้านล่างในคลาสอินเทอร์เฟซที่เก็บข้อมูลของคุณ
เอนทิตี้ชื่อหมายถึงชื่อตารางฐานข้อมูลของคุณเช่นโครงการ และรายการหมายถึง Project เป็นคลาส Entity ในโครงการของคุณ
@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();
คุณสามารถใช้คำตอบที่แนะนำโดย @jombie และ:
findAll()
เมธอดเพื่อจุดประสงค์นี้ แต่ใช้ชื่อที่คุณเลือกList
parametrized ด้วยอินเทอร์เฟซใหม่ของคุณ (เช่นList<SmallProject>
)