8.1.太極平臺:使用MySQL觸發器,不編寫業務邏輯代碼,實現關聯表數據更新

1、場景需求

一個數據庫表的更新,需要聯動引起另一個表的數據更新,這在很多應用場景下都需要。比如:

有1個訂單表,其中有訂單金額、已收總金額、剩餘應付、成本總支出、毛利潤5個字段;另外有1張成本支出記錄表、1張收款記錄表,這2張表都有1個OrderId字段,作爲外鍵來關聯訂單表。業務效果,如下圖所示。

現在增刪改成本支出記錄表、收款記錄表,都需要同步更新訂單表中相關金額。

這種需求,我們一般有2種方法來解決。

1)不採用表字段存儲總支出和總收入,而採用SQL的sum函數,在訂單列表時,實時統計查詢出數據。

優點:無需字段存儲,也不用考慮總計數據的聯動更新。

缺點:數據統計消耗性能,還需要進行多表連接查詢。

2)採用表字段存儲總支出和總收入。

優點:直接從表字段中取數據即可,性能高。

缺點:需要考慮各種能影響到數據變動的情況。稍有不周,易引起數據更新遺漏。

我們採用第2種方式來實現,以減小SQL查詢統計的複雜度。

2、選定方案

採用第2種方案,需要考慮到各種引起數據變動的情況。對於上述案例,無非就是單條支出的變動,會引起總支出的變動。而單條支出的變動,無非就是增刪改。所以在業務邏輯中,盯住增刪改就可以了。

使用太極平臺,我們有2種方式去實現。

1)單獨指定增刪改的action地址,在服務器後端進行編碼處理。見章節:使用自定義action來獨立處理增刪改操作

這種方式可行,但是違背了我們使用太極平臺的初衷。使用太極平臺,就是要少編碼,甚至是不編碼。所以我們不採用此方案。

2)不做任何配置變動,採用MySQL的觸發器進行實現。這也是本文重點要說明的方式。

接下來,將說明使用觸發器的方式如何實現。

3、數據表結構

先將3張表的詳細結構進行說明。爲簡單描述,刪除了不必要的字段。表設計如下:

1)訂單表(qd_order)

2)訂單支出表(qd_order_cost)

3)訂單收款表(qd_order_payee)

4)3個表關係的E-R圖,如下圖所示。

4、觸發器實現方案

觸發器是數據庫層的機制,因此與業務代碼無關。觸發器與存儲過程類似,都在數據庫上進行編寫。如果使用的是阿里雲的DMS平臺,那麼可以在這裏看到。如下圖所示,是我們編寫好的觸發器。

我們現在要實現這樣的效果:

1)增刪改支出記錄,同步更新訂單表總支出、毛利潤;

2)增刪改收款記錄,同步更新訂單表總收款、毛利潤;

3)修改訂單表的訂單金額,同步更新剩餘應付款;

觸發器的使用方法,可以自行去網上學習。我們以支出記錄爲例,進行詳細邏輯說明。

如下圖所示,是添加支出記錄時的觸發器語句。在完成支出記錄插入後,更新訂單表的總支出、毛利潤。這裏的毛利潤=總收款-總支出。

可以看到,編寫觸發器,就是編寫SQL語句。只是要注意觸發時機,是在after還是before,多實踐操作就積累經驗了。

5、觸發器的SQL語句代碼

8個觸發器的SQL語句如下。最後2個是訂單表自身的,語句稍微和其他的不一樣,因爲是觸發自身,同時更新自身,所以只需要set就可以了。

1)支出表qd_order_cost添加記錄時的觸發器:OrderCost_After_Insert

begin

/**添加成本支出時,更新訂單的總成本與毛利潤**/
update qd_order set TotalCost=(select sum(CostMoney) from qd_order_cost where OrderId=NEW.OrderId),
GrossProfit=OrderPaid-TotalCost where Id=NEW.OrderId;

end

2)支出表qd_order_cost更新記錄時的觸發器:OrderCost_After_Update

begin

/**更新成本支出時,更新訂單的總成本與毛利潤**/
update qd_order set TotalCost=(select sum(CostMoney) from qd_order_cost where OrderId=NEW.OrderId),
GrossProfit=OrderPaid-TotalCost where Id=NEW.OrderId;

end

3)支出表qd_order_cost更新記錄時的觸發器:OrderCost_After_Delete

注意:刪除數據後,有可能相關數據一條都沒有了。那麼sum出來的結果會爲null,而不是0。所以我們需要特殊對待,對sum的結果要進行IFNULL的判斷。IFNULL(SUM(字段),0),這樣就可以在一條數據都沒有的時候,仍然更新0進去。否則爲null就不會執行更新。

begin

/**刪除成本支出時,更新訂單的總成本與毛利潤**/
update qd_order set TotalCost=(select IFNULL(SUM(CostMoney),0) from qd_order_cost where OrderId=OLD.OrderId),
GrossProfit=OrderPaid-TotalCost where Id=OLD.OrderId;

end

4)支出表qd_order_cost更新記錄時的觸發器:OrderPayee_After_Insert

begin

/**添加收款記錄時,更新訂單已收款總額、剩餘金額、毛利潤**/
update qd_order set OrderPaid=(select SUM(PayMoney) from qd_order_payee where OrderId=NEW.OrderId),
OrderRemain=OrderAmount-OrderPaid,GrossProfit=OrderPaid-TotalCost where Id=NEW.OrderId;

end

5)支出表qd_order_cost更新記錄時的觸發器:OrderPayee_After_Update

begin

/**更新收款記錄時,更新訂單已收款總額、剩餘金額、毛利潤**/
update qd_order set OrderPaid=(select sum(PayMoney) from qd_order_payee where OrderId=NEW.OrderId),
OrderRemain=OrderAmount-OrderPaid,GrossProfit=OrderPaid-TotalCost where Id=NEW.OrderId;
end

6)支出表qd_order_cost更新記錄時的觸發器:OrderPayee_After_Delete

begin

/**刪除收款記錄時,更新訂單已收款總額、剩餘金額、毛利潤**/
update qd_order set OrderPaid=(select IFNULL(SUM(PayMoney),0) from qd_order_payee where OrderId=OLD.OrderId),
OrderRemain=OrderAmount-OrderPaid,GrossProfit=OrderPaid-TotalCost where Id=OLD.OrderId;

end

7)支出表qd_order_cost更新記錄時的觸發器:Order_Before_Insert

begin

/**添加訂單時,更新剩餘應付金額,等於訂單金額**/
set NEW.OrderRemain=NEW.OrderAmount;

end

8)支出表qd_order_cost更新記錄時的觸發器:Order_Before_Update

begin

/**訂單總金額更新時,更新剩餘金額**/
if NEW.OrderAmount!=OLD.OrderAmount then
	set NEW.OrderRemain=NEW.OrderAmount-NEW.OrderPaid;
end if;

end

6、詳細代碼案例

詳細的代碼與案例,到時候下載演示項目和數據庫,就可以看到了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章