SpringBoot+Angular先後端分離的數據流淺析

零、前言

以前學過ThinkPHP,在初學的時候,幾乎沒有任何基礎。當時被這種MVC分離的框架搞暈了,都不知道數據是怎麼在各層之間傳遞的。
後來發現,搞懂MVC的關鍵,就是理解數據流。當時我還作了一張很大的圖片,記錄了MVC和數據庫之間傳值的方式和CRUD的過程。(因爲這張圖片是好久之前製做的,可能不徹底正確)
image數據庫

當把數據流融會貫通之時,就是開悟之日。瀏覽器

1、由淺入深,分析流程

瀏覽器、先後臺、數據庫

先從總體上分析瀏覽器、先後臺、數據庫之間的數據流:服務器

圖片.png

上圖只是爲了搞清楚數據在各個部門間的傳遞過程,圖中的前臺代碼和後臺代碼實際上都是MVC,只是爲了方便理解,在圖中簡化了。框架

MVC

接下來,展開它們:post

圖片.png

解釋數據流

用文字來解釋一下上圖的數據流:學習

  1. 用戶經過瀏覽器Url向前臺發起請求
  2. 前臺服務器返回前臺程序
  3. 執行前臺程序
  4. 前臺C層經過Url請求後臺C層的方法
  5. 後臺C層調用服務層方法
  6. 後臺服務層調用倉庫的接口
  7. 倉庫經過SQL請求數據庫
  8. 數據庫返回數據給倉庫
  9. 後臺倉庫接收數據,返回給後臺服務層
  10. 服務層把數據轉換成對象,返回給後臺C層
  11. 後臺C層把對象轉換爲JSON字符串,並返回給前臺C層
  12. 前臺C層接收JSON字符串,轉化爲對象,渲染V層組件
  13. 獲取返回後的組件,呈現給瀏覽器頁面

對以上過程的一些說明:this

  • 前臺C層只負責數據轉發,前臺V層是沒有數據的頁面模板
  • 後臺C層只負責數據轉發,後臺M層是業務邏輯的具體實現
  • 先後臺的交互,是經過前臺C層向後臺C層發起Http請求來實現的
  • 後臺和數據庫的交互,是經過M層發起SQL語句來實現的
  • 前臺實體、後臺實體、數據表字段始終相互對應

2、功能的具體實現

前臺請求後臺:HttpClient

//定義請求地址url
const url = 'http://localhost:8080/Klass';  
//定義須要請求的對象
const klass = new Klass(undefined, this.name.value,  
 this.teacher  
);

//執行http請求,並訂閱
//使用觀察者模式,若是成功或失敗,則執行對應的代碼
this.httpClient.post(url, klass)  
  .subscribe(() => {  
    console.log('保存成功');  
 this.router.navigateByUrl('/klass', {relativeTo: this.route});  
  }, (response) => {  
    console.log(`向${url}發起的post請求發生錯誤` + response); 
  });

前臺直接顯示C層變量:雙花括號{{}}

//V層代碼
<td>{{student.name}}</td>

前臺C、V層雙向數據綁定:[(ngModel)]

//C層代碼
username: string;

//V層代碼
<input type="text" id="username" name="username" [(ngModel)]="username">

前臺表單:(ngSubmit)

//C層代碼
public onSubmit(): void {  
 
}

//V層代碼
<form id="teacherAddForm" (ngSubmit)="onSubmit()">  

</form>

前臺按鈕:(click)

//C層代碼
onDelete(klass: Klass): void {  

}


//V層代碼
<button (click)="onDelete(klass)">刪除</button>

後臺C層調用服務層方法:接口

//StudentService(服務層)
Student save(Student student);

//StudentServiceImpl(接口的具體實現)
public Student save(Student student) {  
    return this.studentRepository.save(student);  
}

//StudentController(C層,調用M層Save()) 
public Student save(@RequestBody Student student) {  
    return studentService.save(student);  
}

後臺向數據庫請求數據:倉庫

//StudentServiceImpl (服務層接口的具體實現)
public Page<Student> findAll(Pageable pageable) {  
    return this.studentRepository.findAll(pageable);  
}

//StudentRepository (倉庫:執行請求數據庫的動做)
default Page findAll(String name, String sno, Klass klass, @NotNull Pageable pageable) {  
    Assert.notNull(pageable, "傳入的Pageable不能爲null");  
Specification<Student> specification = StudentSpecs.containingName(name)  
            .and(StudentSpecs.startWithSno(sno))  
            .and(StudentSpecs.belongToKlass(klass));  
return this.findAll(specification, pageable);  
}

總結

對於這些MVC分離或者先後臺分離的框架,理解它們的關鍵,就在於搞明白數據從哪來到哪去。這是站在一個宏觀的總體的角度去看待問題。url

若是不理解數據流,只關注代碼自己,那麼代碼就只會是一個個片斷,而沒法在思惟中連成總體。spa

從我一個小白的角度來看,搞明白數據流,是學習如何使用框架的良好開端。code

相關文章
相關標籤/搜索