您好,登錄后才能下訂單哦!
今天小編給大家分享一下Salesforce的Trigger觸發(fā)器怎么使用的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
一 . Apex Trigger 觸發(fā)器
Apex 觸發(fā)器(Apex Triggers)是一種特殊的 Apex 類。 Apex觸發(fā)器類似于當特定事件發(fā)生時執(zhí)行的存儲過程。 它在記錄事件發(fā)生之前和之后執(zhí)行。 它的主要作用是在一條記錄被插入、修改、刪除之前或之后自動執(zhí)行一系列的操作。每一個 Trigger 類必須對應(yīng)一種對象。
Trigger 的語法和普通的 Apex 類一樣。
Salesforce 建議開發(fā)者在創(chuàng)建 Trigger 之前,考慮一下相同的操作可否通過 Salesforce 的設(shè)置界面中的功能完成,比如驗證規(guī)則(Validation Rule)、工作流規(guī)則(Workflow Rule)等。如果可以,則優(yōu)先使用它們。
二 . Apex Trigger 的結(jié)構(gòu) 和 觸發(fā)事件
語法結(jié)構(gòu) :
//語法結(jié)構(gòu) trigger triggerName on ObjectName (trigger_events) { Trigger_code_block } // 說明 trigger Trigger名字(觸發(fā)器名字) on 對象名字 (觸發(fā)事件) { //Do something }
Trigger 類必須以關(guān)鍵字 “trigger” 開始,然后是此 Trigger 的名字。接下來是 “on” 關(guān)鍵字,然后是 Trigger 對應(yīng)的對象的名字。對象名字后面的括號中寫入觸發(fā) Trigger 的事件。
Trigger觸發(fā) 的事件分為以下幾種 :
insert //添加
update //修改
delete //刪除
merge //合并
upsert //添加或修改 ,即 無該條數(shù)據(jù) 就添加 有這條數(shù)據(jù)則修改
upsert原理:upsert通過是否存在此ID來判斷此條記錄是否存在, 1.如果不存在此ID則執(zhí)行insert操作; 2.如果存在并且只存在一個ID,則執(zhí)行update操作; 3.存在并且存在多個ID,則拋出DMLException
undelete //取消刪除 , 可以取消刪除已刪除并存在于回收站中的記錄
Trigger觸發(fā) 的類型分為以下幾種 :
Before trigger 通常用于在他們被保存在數(shù)據(jù)庫以前更新或者校驗數(shù)據(jù);
After trigger 通常用于保存后訪問系統(tǒng)的字段(Id等).
小喵把它們理解為前置觸發(fā)器和后置觸發(fā)器,即 在 觸發(fā)事件之前 和 觸發(fā)事件之后 干什么.(這只是小喵的個人理解,只是為了方便了解/學(xué)習(xí))
三 . 設(shè)計思想
Trigger設(shè)計思想為 'One Trigger per Object ' 即 ' 一個對象 一個觸發(fā)器 ' , 我們 可以將特定對象的所有可能觸發(fā)的觸發(fā)器組合成一個觸發(fā)器.
注意:trigger代碼塊中不能包含static關(guān)鍵字。
這種設(shè)計模式的好處 :
? 可重用性 : 將邏輯放在一個類中,現(xiàn)在可以在觸發(fā)器之外重用它,例如在Visualforce頁面,測試類,批處理Apex等中。無需復(fù)制代碼!
? 簡便性 : 在主觸發(fā)器中,每個“觸發(fā)器”都減少為僅兩行代碼。一個面向?qū)ο蟮拇a庫更加有組織的,可預(yù)見的和模塊化的呢!
? 控制執(zhí)行順序 : 在Apex中,“不能保證同一對象上的多個觸發(fā)器的執(zhí)行順序?!?nbsp;這種模式使您可以全面控制訂單。
? 代碼風(fēng)格 : 無論是否利用了上述任何優(yōu)勢,都將看起來像使用此模式的Apex主服務(wù)器。
四 . 常用變量
Trigger類中封裝了很多的上下文的變量,這些變量在開發(fā)中經(jīng)常用到。
isExecuting:當前Apex代碼的上下文環(huán)境為trigger環(huán)境,而不是VF等則返回true,否則返回false;
isInsert:當前操作是否為正在執(zhí)行添加操作,是返回true,否則返回false;
isUpdate:當前操作是否為正在執(zhí)行修改操作,是返回true,否則返回false;
isDelete:當前操作是否為正在執(zhí)行刪除操作,是返回true,否則返回false;
isBefore:當前操作是否為在save以前操作,是返回true,否則返回false;
isAfter:當前操作是否為在save以后操作,是返回true,否則返回false;
isUndelete:當前操作是否為在回收箱中回復(fù)數(shù)據(jù)以后操作,是返回true,否則返回false;
注意 : 以上布爾類型的變量 , 用于 標志 Trigger 或數(shù)據(jù)的狀態(tài) .
new:返回sObject的記錄的最新的數(shù)據(jù)的列表;
newMap:返回一個ID映射到最新的數(shù)據(jù)列表的Map集合;
old:返回sObject的記錄修改以前的數(shù)據(jù)的列表;
oldMap:返回一個ID映射到修改以前的數(shù)據(jù)列表的Map集合;
size:在觸發(fā)器中調(diào)用的數(shù)據(jù)總數(shù),包括new和old。
其中, new , new Map , old , oldMap 是有使用限制的,需要重點說明一下 :
new只適用于執(zhí)行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 是兩個預(yù)定義變量 , 可以用于每一個Trigger類中 . 前者代表了即將被插入、更新的數(shù)據(jù) , 后者代表了更新之前、刪除之前的數(shù)據(jù) . 它們可能包含一條數(shù)據(jù) , 也可能包含一組數(shù)據(jù),取決于觸發(fā)Trigger 時的狀態(tài) .
注意 : Trigger.New 不存在于 delete 操作中 , 因為 刪除之后就沒有數(shù)據(jù)了 ; 而 Trigger.Old 不存在 insert 操作 , 因為 插入數(shù)據(jù)之前是沒有數(shù)據(jù)的.
五 . Trigger 觸發(fā)器的使用
目前小喵使用trigger主要有兩種方式 : 第一種是 直接使用trigger , 在trigger內(nèi)部塊中寫業(yè)務(wù)邏輯 ; 第二種是 通過Handler 對 trigger 進行封裝 .
1) 直接在Trigger內(nèi)部塊中寫代碼 :
trigger AccountBeforeDelete on Account (before delete) { if (Trigger.isBefore) { // 在SFDelete c中追加數(shù)據(jù) 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創(chuàng)建其自身的Handler,將trigger業(yè)務(wù)邏輯寫在自身的Handler里面,并通過Factory實例化,達到更好的可擴展性以及可讀性 .
2.1) 創(chuàng)建 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應(yīng)該注意以下幾點: 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) 創(chuàng)建相關(guān)對象的Handler , 繼承TriggerHandler 并實現(xiàn)其MyTrigger接口 , 并實現(xiàn)相關(guān)方法 .
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) 創(chuàng)建TriggerFactory,此方法用于實例化Trigger的Handler并執(zhí)行相應(yīng)的before或者after操作,其中MyException為自定義異常類。
public class MyException extends Exception {}
public class TriggerFactory { /* 實例化Handler,如果不跳過executeTrigger情況下,自動執(zhí)行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); } } /* 執(zhí)行trigger應(yīng)該注意以下幾點: 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,在此方法添加相應(yīng)的匹配處理, 同時此object的Handler必須繼承TriggerHandler以及實現(xiàn)TriggerHandler.MyTrigger 每個Object的Object Token不同,所以使用Token作為參數(shù)更加便捷 */ public static TriggerHandler.MyTrigger getTriggerByObjectToken(Schema.SObjectType objectToken) { if(objectToken == Goods__c.sObjectType) { return new GoodsHandler(); } // TODO 有其他Object需要使用trigger可以繼承TriggerHandler實現(xiàn)其中MyTrigger然后在此處配置 return null; } }
2.4) 相應(yīng)Object的trigger調(diào)用Factory的實例化方法
trigger GoodsTrigger on Goods__c (before delete, before update) { TriggerFactory.instanceHandler(Goods__c.sObjectType); }
當Goods__c字段進行delete或者update操作時,save以前,會自動觸發(fā)GoodsTrigger,GoodsTrigger會執(zhí)行TriggerFactory的instanceHandler方法,此方法會調(diào)用執(zhí)行instanceHandler以及executeTrigger函數(shù),從而最終將Goods__c表trigger業(yè)務(wù)邏輯由GoodsHandler類處理。
提示 : 如果業(yè)務(wù)相對簡單,可以采用第一種方式,開發(fā)效率高;如果業(yè)務(wù)相對復(fù)雜,第二種方式可以在相應(yīng)的Handler模塊更加明了的書寫業(yè)務(wù)邏輯,方便后期維護以及有更好的可讀性
以上就是“Salesforce的Trigger觸發(fā)器怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。