久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Salesforce的Trigger觸發器怎么使用

168次閱讀
沒有評論

共計 7194 個字符,預計需要花費 18 分鐘才能閱讀完成。

今天丸趣 TV 小編給大家分享一下 Salesforce 的 Trigger 觸發器怎么使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

一 . Apex Trigger 觸發器

 Apex 觸發器(Apex Triggers)是一種特殊的 Apex 類。Apex 觸發器類似于當特定事件發生時執行的存儲過程。它在記錄事件發生之前和之后執行。它的主要作用是在一條記錄被插入、修改、刪除之前或之后自動執行一系列的操作。每一個 Trigger 類必須對應一種對象。

 Trigger 的語法和普通的 Apex 類一樣。

 Salesforce 建議開發者在創建 Trigger 之前,考慮一下相同的操作可否通過 Salesforce 的設置界面中的功能完成,比如驗證規則(Validation Rule)、工作流規則(Workflow Rule)等。如果可以,則優先使用它們。

二 . Apex Trigger 的結構 和 觸發事件

語法結構 :

 // 語法結構
trigger triggerName on ObjectName (trigger_events) { Trigger_code_block }
 //  說明
trigger Trigger 名字 (觸發器名字) on  對象名字  (觸發事件) { //Do something }

Trigger 類必須以關鍵字“trigger”開始,然后是此 Trigger 的名字。接下來是“on”關鍵字,然后是 Trigger 對應的對象的名字。對象名字后面的括號中寫入觸發 Trigger 的事件。

Trigger 觸發 的事件分為以下幾種 :

insert      // 添加  

update    // 修改

delete     // 刪除

merge     // 合并

upsert     // 添加或修改 , 即 無該條數據 就添加   有這條數據則修改

upsert 原理:upsert 通過是否存在此 ID 來判斷此條記錄是否存在,1. 如果不存在此 ID 則執行 insert 操作;2. 如果存在并且只存在一個 ID,則執行 update 操作;3. 存在并且存在多個 ID,則拋出 DMLException

undelete   // 取消刪除 ,  可以取消刪除已刪除并存在于回收站中的記錄

Trigger 觸發 的類型分為以下幾種 :

Before trigger    通常用于在他們被保存在數據庫以前更新或者校驗數據;

After trigger    通常用于保存后訪問系統的字段(Id 等).

小喵把它們理解為前置觸發器和后置觸發器, 即 在 觸發事件之前 和 觸發事件之后   干什么.(這只是小喵的個人理解, 只是為了方便了解 / 學習)

三 . 設計思想

 Trigger 設計思想為 One  Trigger  per  Object     即 一個對象 一個觸發器 , 我們 可以將特定對象的所有可能觸發的觸發器組合成一個觸發器.

注意:trigger 代碼塊中不能包含 static 關鍵字。 

    這種設計模式的好處   : 

? 可重用性 :  將邏輯放在一個類中,現在可以在觸發器之外重用它,例如在 Visualforce 頁面,測試類,批處理 Apex 等中。無需復制代碼!

? 簡便性 :  在主觸發器中,每個“觸發器”都減少為僅兩行代碼。一個面向對象的代碼庫更加有組織的,可預見的和模塊化的呢!

? 控制執行順序 :  在 Apex 中,“不能保證同一對象上的多個觸發器的執行順序。”  這種模式使您可以全面控制訂單。

?  代碼風格 :  無論是否利用了上述任何優勢,都將看起來像使用此模式的 Apex 主服務器。

四 . 常用變量  

Trigger 類中封裝了很多的上下文的變量,這些變量在開發中經常用到。

isExecuting: 當前 Apex 代碼的上下文環境為 trigger 環境,而不是 VF 等則返回 true,否則返回 false;

isInsert: 當前操作是否為正在執行添加操作,是返回 true,否則返回 false;

isUpdate: 當前操作是否為正在執行修改操作,是返回 true,否則返回 false;

isDelete: 當前操作是否為正在執行刪除操作,是返回 true,否則返回 false;

isBefore: 當前操作是否為在 save 以前操作,是返回 true,否則返回 false;

isAfter: 當前操作是否為在 save 以后操作,是返回 true,否則返回 false;

isUndelete: 當前操作是否為在回收箱中回復數據以后操作,是返回 true,否則返回 false;

注意 : 以上布爾類型的變量 , 用于 標志 Trigger 或數據的狀態 .

new: 返回 sObject 的記錄的最新的數據的列表;

newMap: 返回一個 ID 映射到最新的數據列表的 Map 集合;

old: 返回 sObject 的記錄修改以前的數據的列表;

oldMap: 返回一個 ID 映射到修改以前的數據列表的 Map 集合;

size: 在觸發器中調用的數據總數,包括 new 和 old。

其中, new , new Map , old , oldMap 是有使用限制的, 需要重點說明一下 :

new 只適用于執行 insert 和 update 的 trigger 操作時并且類型為 before 的時候,才可以使用 new 返回列表;

newMap 只適用于 before update,after insert 以及 after update 的 trigger 操作時,才可以使用 newMap 返回 map 集合;

old 以及 oldMap 只適用于 update 和 delete 操作時,才可以使用 old 以及 oldMap。

簡單來說 , Trigger.New 和 Trigger.Old 是兩個預定義變量 , 可以用于每一個 Trigger 類中 . 前者代表了即將被插入、更新的數據 , 后者代表了更新之前、刪除之前的數據 . 它們可能包含一條數據 , 也可能包含一組數據, 取決于觸發 Trigger 時的狀態 .

注意 : Trigger.New 不存在于   delete 操作中 , 因為 刪除之后就沒有數據了 ; 而 Trigger.Old 不存在 insert 操作 , 因為   插入數據之前是沒有數據的.

五 . Trigger 觸發器的使用

目前小喵使用 trigger 主要有兩種方式 : 第一種是 直接使用 trigger , 在 trigger 內部塊中寫業務邏輯 ; 第二種是 通過 Handler 對 trigger 進行封裝 .

 1)  直接在 Trigger 內部塊中寫代碼 :

trigger AccountBeforeDelete on Account (before delete) { if (Trigger.isBefore) {
 //  在 SFDelete c 中追加數據
 if (Trigger.isDelete) {
 List SFDelete__c  dlist = new List SFDelete__c 
 for (Account a : Trigger.old) {
 dlist.add(new SFDelete__c(
 delSfId__c = a.Id,
 tableName__c =  Account ,
 dataOwnerId__c = a.OwnerId
 ));
 }
 ControllerUtil.insSFDelete(dlist);
 }
 }
}

  2)  通過 Handler 對 trigger 進行封裝 :

通過 Handler 方式可以將每個 Object 創建其自身的 Handler,將 trigger 業務邏輯寫在自身的 Handler 里面,并通過 Factory 實例化,達到更好的可擴展性以及可讀性 .

        2.1) 創建 TriggerHandler 父類  

public abstract class TriggerHandler {
 /*
 Trigger 中,在運行時封裝了 new,newMap,old,oldMap 變量
  其中,new 和 old 返回類型為 List sObject 
 newMap 和 oldMap 返回類型為 Map Id,sObject 
 */
 protected Map Id,sObject  oldMap{get;set;}
 protected Map Id,sObject  newMap{get;set;}
 protected List sObject  listNew{get;set;}
 protected List sObject  listOld{get;set;}
 /*
  封裝 trigger 應該注意以下幾點: 1.trigger.new 只能用在 insert 和 update 時,且 trigger 必須是 before;
 2.trigger.old 只能用在 update 和 delete 時;
 3.trigger.newMap 只能用在 before update,after insert 和 after update 時;
 4.trigger.oldMap 只能用在 update 和 delete 時.
 */
 public interface MyTrigger { void beforeInsert(SObject currentObject);
 void beforeUpdate(SObject oldSobject, SObject currentObject);
 void beforeDelete(SObject currentObject);
 void afterInsert(SObject currentObject);
 void afterUpdate(SObject oldSobject, SObject currentObject);
 void afterDelete(SObject currentObject);
 Boolean skipExecution();
 }
}

         2.2) 創建相關對象的 Handler , 繼承 TriggerHandler 并實現其 MyTrigger 接口 , 并實現相關方法 . 

public class GoodsHandler extends TriggerHandler implements TriggerHandler.MyTrigger { public GoodsHandler() {
 // TODO Construcion
 }
 public void beforeInsert(SObject currentObject) {
 // TODO beforeInsert
 }
 public void afterInsert(SObject currentObject) {
 // TODO afterInsert
 }
 public void beforeUpdate(SObject oldSobject, SObject currentObject) {
 // TODO beforeUpdate
 }
 public void beforeDelete(SObject currentObject) {
 //TODO beforeDelete
 }

 public void afterUpdate(SObject oldSobject, SObject currentObject) { }  public void afterDelete(SObject currentObject) { }  public Boolean skipExecution() {  return false;  } }

    2.3)  創建 TriggerFactory,此方法用于實例化 Trigger 的 Handler 并執行相應的 before 或者 after 操作,其中 MyException 為自定義異常類。

public class MyException extends Exception {}
public class TriggerFactory {
 /*
  實例化 Handler, 如果不跳過 executeTrigger 情況下,自動執行 Trigger
 */
 public static void instanceHandler(Schema.SObjectType objectToken) { TriggerHandler.MyTrigger myTriggerHandler = getTriggerByObjectToken(objectToken);
 if(myTriggerHandler == null) {
 throw new MyException( 無此 object token 的 trigger 
 }
 if(!myTriggerHandler.skipExecution()) { executeTrigger(myTriggerHandler);
 }
 }
 /*
  執行 trigger 應該注意以下幾點: 1.trigger.new 只能用在 insert 和 update 時,且 trigger 必須是 before;
 2.trigger.old 只能用在 update 和 delete 時;
 3.trigger.newMap 只能用在 before update,after insert 和 after update 時;
 4.trigger.oldMap 只能用在 update 和 delete 時.
 */
 public static void executeTrigger(TriggerHandler.MyTrigger myTriggerHandler) {
 //trigger 分成 isBefore 以及 isAfter
 if(Trigger.isBefore) { if(Trigger.isInsert) { for (SObject currentObject : Trigger.new)
 { myTriggerHandler.beforeInsert(currentObject);
 }
 }else if(Trigger.isUpdate) { for (SObject oldObject : Trigger.old)
 { myTriggerHandler.beforeUpdate(oldObject, Trigger.newMap.get(oldObject.Id));
 }
 }else if(Trigger.isDelete) { for (SObject currentObject : Trigger.old)
 { myTriggerHandler.beforeDelete(currentObject);
 }
 }
 } else {//isAfter
 if (Trigger.isInsert) { for (SObject currentObject : Trigger.new) { myTriggerHandler.afterInsert(currentObject);
 }
 } else if (Trigger.isUpdate) { for (SObject oldObject : Trigger.old) { myTriggerHandler.afterUpdate(oldObject, Trigger.newMap.get(oldObject.Id));
 }
 } else if (Trigger.isDelete){ for (SObject currentObject : Trigger.old) { myTriggerHandler.afterDelete(currentObject);
 }
 }
 }
 }

 /*   此方法用于返回具體某個 object 的 trigger,如果添加一個 object 的 trigger,在此方法添加相應的匹配處理,  同時此 object 的 Handler 必須繼承 TriggerHandler 以及實現 TriggerHandler.MyTrigger   每個 Object 的 Object Token 不同,所以使用 Token 作為參數更加便捷  */  public static TriggerHandler.MyTrigger getTriggerByObjectToken(Schema.SObjectType objectToken) { if(objectToken == Goods__c.sObjectType) { return new GoodsHandler();  }  // TODO  有其他 Object 需要使用 trigger 可以繼承 TriggerHandler 實現其中 MyTrigger 然后在此處配置  return null;  } }

    2.4) 相應 Object 的 trigger 調用 Factory 的實例化方法

trigger GoodsTrigger on Goods__c (before delete, before update) { TriggerFactory.instanceHandler(Goods__c.sObjectType);
}

  當 Goods__c 字段進行 delete 或者 update 操作時,save 以前,會自動觸發 GoodsTrigger,GoodsTrigger 會執行 TriggerFactory 的 instanceHandler 方法,此方法會調用執行 instanceHandler 以及 executeTrigger 函數,從而最終將 Goods__c 表 trigger 業務邏輯由 GoodsHandler 類處理。

提示 :  如果業務相對簡單,可以采用第一種方式,開發效率高;如果業務相對復雜,第二種方式可以在相應的 Handler 模塊更加明了的書寫業務邏輯,方便后期維護以及有更好的可讀性

以上就是“Salesforce 的 Trigger 觸發器怎么使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,丸趣 TV 小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計7194字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 延边| 永济市| 重庆市| 伊通| 安平县| 江西省| 鄂尔多斯市| 刚察县| 鹰潭市| 武宣县| 板桥市| 青冈县| 铜山县| 锦州市| 哈巴河县| 介休市| 微山县| 松阳县| 桂东县| 岳西县| 金门县| 阜平县| 扶沟县| 札达县| 开平市| 南陵县| 龙里县| 黎城县| 连云港市| 左权县| 吕梁市| 灵山县| 洛川县| 大宁县| 杭锦旗| 仙居县| 隆化县| 安多县| 金华市| 文山县| 大余县|