昨天我們完成了 Spring Data JPA 的準備工作及資料庫連線設定。
今天將會透過以下情境來實現與資料庫中資料表的互動操作:
情境一,假設老師想要根據班級來查詢班上共有多少人
在 Service 類中,我們可以先定義一個方法,用於從資料庫中取得特定班級的學生人數,且該方法會透過 Repository 呼叫自定義的查詢方法,最後根據查詢結果的大小來統計該班級的人數。
public int getClassNumberOfPeople(String className){
List<StudentInformation> students = studentInformationRepository.getClassMembers(className);
if(!students.isEmpty()){
return students.size();
}
return 0;
}
在 Repository 內 我們可以透過 @Query
註解來進行JPQL的自定義查詢,範例程式碼如下:
@Query("SELECT s FROM StudentInformation s WHERE s.siClass =:className")
List<StudentInformation> getClassMembers(
@Param("className") String className);
@Query("SELECT s FROM StudentInformation s WHERE s.siClass =:className")
是 JPQL的語句,其中的 s 代表的是 StudentInformation 實體類的”別名”;s.siClass 代表的是StudentInformation 實體類內的其中一個屬性物件; @Param
註解用於將傳入方法的參數與 @Query
語句中的參數進行綁訂,以上段程式碼為例,當 getClassMembers 方法被呼叫後,傳入的 className
的值就會自動的填入 JPQL查詢語句中的具名參數(Named Parameter) :className
內。
具名參數舉例如下:
假設傳入了一個班級名稱 “ A ”,當我們呼叫getClassMembers方法時
List<StudentInformation> students = studentInformationRepository.getClassMembers("A");
此時,JPQL 查詢語句會被剖析成
SELECT s FROM StudentInformation s WHERE s.siClass = 'A'
在這裡的 ‘A’ 就是根據方法傳遞進來的參數 className
替換 :className
後的結果。
完整範例如下:
Controller
@RestController("StudentController")
@RequestMapping("/Student")
public class StudentController {
private final StudentService studentService;
@Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
@RequestMapping(value = "/getNumberOfPeople", method = RequestMethod.GET)
public String getNumberOfPeople(
@RequestParam(value = "className", required = true) String className
) {
int returnNumberOfPeople = studentService.getClassNumberOfPeople(className);
if(returnNumberOfPeople == 0){
return "查無此班級";
}
return String.valueOf(returnNumberOfPeople);
}
}
Service
@Service("StudentService")
public class StudentService {
private StudentInformationRepository studentInformationRepository;
private StudentScoresRepository studentScoresRepository;
@Autowired
public StudentService(StudentInformationRepository studentInformationRepository,
StudentScoresRepository studentScoresRepository) {
this.studentInformationRepository = studentInformationRepository;
this.studentScoresRepository = studentScoresRepository;
}
public int getClassNumberOfPeople(String className){
List<StudentInformation> students = studentInformationRepository.getClassMembers(className);
if(!students.isEmpty()){
return students.size();
}
return 0;
}
}
Repository
public interface StudentInformationRepository extends JpaRepository<StudentInformation, Long> {
@Query("SELECT s FROM StudentInformation s WHERE s.siClass =:className")
List<StudentInformation> getClassMembers(
@Param("className") String className);
}
透過 Postman 發 API 查詢結果如下: