本文的內容有助于理解JAVA Spring Boot框架的層次結構。
“我決定不讓自己徹底崩潰,而是每個周二晚上都讓自己小崩潰一下。” —— Graham Parke
檢查任何軟件的最好方法是將其分成層,然后將這些層合并在一起。我們在這里遵循同樣的方法。
在深入研究Java Spring Boot之前,讓我們先來看一個眾所周知的例子——計算機網絡中的OSI模型。雖然網絡整體上看起來很復雜,但我們通常將其分成層次以組織協議。我們還聲明每個層都依賴于下面一層提供的服務。在Spring Boot中,同樣的原則也適用。
1 Spring Boot的層次結構
我們主要可以將Spring Boot分成四層:
1.1 控制器層
系統與客戶端請求交互的第一部分是控制器。它們定義了API的端點,可以將端點想象為有效的路由和請求方法(GET、POST、PUT)。控制器的主要目標是向客戶端提供服務,即提供響應、狀態等。控制器利用服務層提供的服務來為客戶端提供服務。
端點的示例:
-
/login (POST) -
/register (POST) -
/products (GET)
1.2 服務層
服務層旨在實現業務邏輯。服務層的主要目的是向控制器層提供服務。所有對數據的計算都在這一層中執行,因此服務層需要數據。所以,它們依賴于DAO/Repository層提供的服務。
1.3 DAO/Repository層
DAO代表數據訪問對象,這一層的主要目標是從數據庫中高效地訪問(查詢)數據,并向服務層提供服務。
在Spring Boot中存在提供CRUD操作(創建、檢索、更新、刪除)的接口。因此,Repository層可以實現其中的一個。
1.4 模型層
模型表示現實世界中的對象,這些對象被稱為模型。JPA(Java Persistence API)提供了關于ORM(對象關系映射)的參考或詳細信息,這意味著Java類可以與數據庫表相關聯。在Spring Boot中存在許多JPA ORM的實現,其中之一是Hibernate。因此,您需要現實世界實體的Java類,然后將其映射到關系(表)中。
2 上述層次結構的實現模板
注意:對于實施,我們把項目管理作為一個主題。
2.1 控制器層:
ProjectController.java
package com.example.Controller;
//導入語句在此處
@RestController
public class UserController {
//列出所有可用項目
@GetMApping(path = "/projects", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Project>> getProjects() {
// 執行驗證檢查
// 返回服務層提供的服務
}
//申請項目
@PostMapping(path = "/apply-project", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<HttpStatus> applyProject(@RequestBody Map<String,String> json) {
// 執行驗證檢查
// 返回服務層提供的服務
}
//上傳簡歷
@PostMapping(path = "/upload-resume/{usn}")
public ResponseEntity<List<Object>> uploadToDB(@RequestParam("file") MultipartFile[] file,@PathVariable String usn) {
// 執行驗證檢查
// 返回服務層提供的服務
}
//下載簡歷
@GetMapping("/files/download/{fileName:.+}")
public ResponseEntity downloadFromDB(@PathVariable String fileName) {
// 執行驗證檢查
// 返回服務層提供的服務
}
}
上述示例使用了@注釋,這些注釋用于告知spring是否是RestController,PostMapping等。
2.2 服務層:
ProjectService.java
package com.example.Service;
// 導入語句
public interface ProjectService {
ResponseEntity<List<Project>> getProjects();
HttpStatus applyProject(String USN,int project_id);
ResponseEntity<List<Object>> uploadProjectDocument(MultipartFile[] files,int project_id);
}
ProjectServiceImpl.Java
package com.example.Service;
//導入語句
@Service
public class ProjectServiceImpl implements ProjectService {
//將DAO進行依賴注入(Autowire)
@Override
public ResponseEntity<List<Project>> getProjects() {
try {
//利用DAO服務實現業務邏輯
} catch (Exception e) {
return new ResponseEntity<>(null,HttpStatus.INTERNAL_SERVER_ERROR) ;
}
}
@Override
public HttpStatus applyProject(String USN, int project_id) {
//利用DAO服務實現業務邏輯
}
//輔助函數
public ResponseEntity uploadToLocalFileSystem(MultipartFile file,int project_id) {
}
@Override
public ResponseEntity<List<Object>> uploadProjectDocument(MultipartFile[] files,int project_id) {
//利用DAO服務實現業務邏輯
}
}
2.3 Repository/DAO層:
ProjectDAO.java
package com.example.Dao;
//導入語句
public interface ProjectDao extends JpaRepository<Project,Integer> {
//你也可以在JPA提供的CRUD操作之上包含本地查詢
//使用@Query注釋和相應的函數在此處添加查詢
@Query(value = "Your SQL query ",nativeQuery = true)
public List<Project> getProjects();
}
}
2.4 模型層:
Project.java
package com.example.Entity;
//導入語句
@Entity
@Table(name = "project")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int project_id;
@Column(nullable = false, name = "company_name")
private String company_name;
@Column(nullable = false, name = "description")
private String description;
@Column(nullable = false, name = "requirements")
private String requirements;
@Column(nullable = false, name = "manager")
private String manager;
@Column(nullable = false, name = "start_date")
private Date start_date = new Date();
@Column( name = "end_date")
private Date end_date = new Date();
@Column(nullable = false,name = "opening")
private int opening;
@Column(name = "resources")
private String resources;
public Set<Staff> getStaff_incharge() {
return staff_incharge;
}
public void setStaff_incharge(Set<Staff> staff_incharge) {
this.staff_incharge = staff_incharge;
}
public Set<Student> getApplied_students() {
return applied_students;
}
public Set<Document> getDocuments() {
return documents;
}
public void setDocuments(Set<Document> documents) {
this.documents = documents;
}
@JsonIgnore
@ManyToMany(mappedBy="funded_projects")
private Set<Fund> funds;
public Set<Fund> getFunds() {
return funds;
}
public void setFunds(Set<Fund> funds) {
this.funds = funds;
}
public void setApplied_students(Set<Student> applied_students) {
this.applied_students = applied_students;
}
public Set<Student> getWorking_students() {
return working_students;
}
public void setWorking_students(Set<Student> working_students) {
this.working_students = working_students;
}
//構造函數
public Project() {
super();
}
public Project(int project_id, String company_name, String description, String requirements, String manager, Date start_date, Date end_date, int opening, String resources) {
super();
this.project_id = project_id;
this.company_name = company_name;
this.description = description;
this.requirements = requirements;
this.manager = manager;
this.start_date = start_date;
this.end_date = end_date;
this.opening = opening;
this.resources = resources;
}
public int getProject_id() {
return project_id;
}
public void setProject_id(int project_id) {
this.project_id = project_id;
}
public String getCompany_name() {
return company_name;
}
public void setCompany_name(String company_name) {
this.company_name = company_name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getRequirements() {
return requirements;
}
public void setRequirements(String requirements) {
this.requirements = requirements;
}
public String getManager() {
return manager;
}
public void setManager(String manager) {
this.manager = manager;
}
public Date getStart_date() {
return start_date;
}
public void setStart_date(Date start_date) {
this.start_date = start_date;
}
public Date getEnd_date() {
return end_date;
}
public void setEnd_date(Date end_date) {
this.end_date = end_date;
}
public int getOpening() {
return opening;
}
public void setOpening(int opening) {
this.opening = opening;
}
public String getResources() {
return resources;
}
public void setResources(String resources) {
this.resources = resources;
}
@Override
public String toString() {
return "Project{" +
"project_id=" + project_id +
", company_name='" + company_name + ''' +
", description='" + description + ''' +
", requirements='" + requirements + ''' +
", manager='" + manager + ''' +
", start_date=" + start_date +
", end_date=" + end_date +
", opening=" + opening +
", resources='" + resources + ''' +
'}';
}
}
在上面的示例中,該類表示一個表,其數據成員表示表的屬性。我們還可以使用.NEToOne、ManyToOne、ManyToMany注釋表示表之間的關系。
上述實現是不完整的,因為本文的目的是了解工作流程和層次結構。Spring Boot非常龐大,本文只涵蓋了其中的一小部分。如果本文有任何錯誤,在此深表歉意,希望對您有所幫助,謝謝!