第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰。

十七篇链接:salesforce 零基础学习(十七)Trigger用法

有的时候对于sObject的trigger处理复杂的情况下,比如一个sObject的before update要实现功能1,2.....n功能情况下,Handler中需要在before update写实现功能1--n的代码。然而有些时候,我们在执行update情况下只需要让他触发功能i的功能代码,使用上述Handler方法也可以搞定,只不过处理起来比较尴尬,此篇针对trigger中对于不同业务分成模块进行处理。

一.Triggers基类

Triggers基类主要有以下内容:

1.枚举:封装的枚举包含了Trigger中的所有情况;

2.Handler接口:此接口中声明了一个方法handle,所有实现此接口的类都需要重写次方法;

3.bind方法,用于绑定事件以及实现Handler接口的类,即绑定的事件会使用实现Handler接口的类进行业务逻辑处理;

4.execute方法,用于执行triggers中绑定的Handler。

代码如下:

  1. public class Triggers {
  2.  
  3. public enum Evt
  4. {
  5. AfterDelete,
  6. AfterInsert,
  7. AfterUndelete,
  8. AfterUpdate,
  9. BeforeDelete,
  10. BeforeInsert,
  11. BeforeUpdate
  12. }
  13.  
  14. public interface Handler
  15. {
  16. void handle();
  17. }
  18.  
  19. Map<String, List<Handler>> eventHandlerMapping = new Map<String, List<Handler>>();
  20.  
  21. public Triggers bind(Evt event, Handler eh)
  22. {
  23. List<Handler> handlers = eventHandlerMapping.get(event.name());
  24. if (handlers == null)
  25. {
  26. handlers = new List<Handler>();
  27. eventHandlerMapping.put(event.name(), handlers);
  28. }
  29. handlers.add(eh);
  30. return this;
  31. }
  32.  
  33. public void execute()
  34. {
  35. Evt ev = null;
  36. if(Trigger.isInsert && Trigger.isBefore)
  37. {
  38. ev = Evt.beforeinsert;
  39. }
  40. else if(Trigger.isInsert && Trigger.isAfter)
  41. {
  42. ev = Evt.afterinsert;
  43. }
  44. else if(Trigger.isUpdate && Trigger.isBefore)
  45. {
  46. ev = Evt.beforeupdate;
  47. }
  48. else if(Trigger.isUpdate && Trigger.isAfter)
  49. {
  50. ev = Evt.afterupdate;
  51. }
  52. else if(Trigger.isDelete && Trigger.isBefore)
  53. {
  54. ev = Evt.beforedelete;
  55. }
  56. else if(Trigger.isDelete && Trigger.isAfter)
  57. {
  58. ev = Evt.afterdelete;
  59. }
  60. else if(Trigger.isundelete)
  61. {
  62. ev = Evt.afterundelete;
  63. }
  64. List<Handler> handlers = eventHandlerMapping.get(ev.name());
  65. if (handlers != null && !handlers.isEmpty())
  66. {
  67. for (Handler h : handlers)
  68. {
  69. h.handle();
  70. }
  71. }
  72. }
  73. }

Triggers

二.相关的实现Handler接口的类

此处例举两个类,分别实现Triggers.Handler并且实现相关的Handle方法

1.F1Handler

  1. public without sharing class F1Handler implements Triggers.Handler {
  2. public void Handle(){
  3. List<Company_Info__c> companyInfoList = trigger.new;
  4. //TODO
  5. //do something start
  6. system.debug('===============executeF1Handler');
  7. //do something end
  8. }
  9. }

2.F2Handler

  1. public with sharing class F2Handler implements Triggers.Handler {
  2. public void Handle(){
  3. List<Company_Info__c> companyInfoList = trigger.new;
  4. //TODO
  5. //do something start
  6. system.debug('===============executeF2Handler');
  7. //do something end
  8. }
  9. }

三.相关Trigger中Handler是否执行的Helper类

有的时候业务需要不同地方的入口进行相同的操作,需要执行不同的trigger业务模块,比如在controller正常的更新需要全部执行trigger方法模块,在其他trigger中更新此sObject则只需要一部分模块,这个时候需要相关Helper类方法来控制是否执行哪块逻辑。

  1. public without sharing class TriggerExecutionHelper {
  2. public static Boolean enableExecuteF1 {
  3. get{
  4. if(enableExecuteF1 == null) {
  5. enableExecuteF1 = true;
  6. }
  7. return enableExecuteF1;
  8. }
  9. set;
  10. }
  11.  
  12. public static Boolean enableExecuteF2{
  13. get{
  14. if(enableExecuteF2 == null) {
  15. enableExecuteF2 = true;
  16. }
  17. return enableExecuteF2;
  18. }
  19. set;
  20. }
  21.  
  22. }

四.Trigger代码部分

trigger代码部分用来判断是否需要执行哪些情况trigger

  1. trigger CompanyInfoTrigger on Company_Info__c (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
  2.  
  3. Triggers companyInfoTrigger = new Triggers();
  4. if(TriggerExecutionHelper.enableExecuteF1) {
  5. companyInfoTrigger.bind(Triggers.Evt.BeforeInsert, new F1Handler());
  6. }
  7.  
  8. if(TriggerExecutionHelper.enableExecuteF2) {
  9. companyInfoTrigger.bind(Triggers.Evt.BeforeInsert, new F2Handler());
  10. }
  11.  
  12. companyInfoTrigger.Execute();
  13.  
  14. }

效果展示:

1.通过系统页面插入一条数据,默认走全部的trigger内容

相关log可以查看执行结果

2.通过匿名块执行insert则只执行trigger中一个业务模块代码

总结:如果业务逻辑特别清晰并且可以分模块处理,则可以使用此种方法,达到的效果为业务清晰明了,后期人员也便于维护。缺点为如果相关模块的Handler都对一个字段进行处理,则会有相关先后处理的问题以及出bug调试时间增多等,具体使用哪种还是看具体的业务以及个人使用习惯,业务简单直接写在trigger中也未尝不可。篇中有问题地方欢迎指出,有不懂的欢迎留言。

salesforce 零基础学习(五十二)Trigger使用篇(二)的更多相关文章

  1. 【转】【Salesforce】salesforce 零基础学习(十七)Trigger用法

    看本篇之前可以相应阅读以下Trigger相关文章: 1.https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigge ...

  2. salesforce 零基础学习(十七)Trigger用法

    看本篇之前可以相应阅读以下Trigger相关文章: 1.https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigge ...

  3. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  4. salesforce 零基础学习(十八)WorkFlow介绍及用法

    说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...

  5. salesforce 零基础学习(十六)Validation Rules & Date/time

    上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...

  6. salesforce零基础学习(八十二)审批邮件获取最终审批人和审批意见

    项目中,审批操作无处不在.配置审批流时,我们有时候会用到queue,related user设置当前步骤的审批人,审批人可以一个或者多个.当审批人有多个时,邮件中获取当前记录的审批人和审批意见就不能随 ...

  7. salesforce零基础学习(一百零五)Change Data Capture

    本篇参考: https://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/using ...

  8. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  9. salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件

    在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...

随机推荐

  1. java方法重载(overload)、重写(override);this、super关键简介

    一.方法重载: 条件:必须在一个类中,方法名称相同,参数列表不同(包括:数据类型.顺序.个数),典型案例构 造方重载.  注意:与返回值无关 二.方法重写: 条件: (1)继承某个类或实现某接口 (2 ...

  2. 【ORACLE】ORA-12537 问题整理

    ORA-12537主要是ORALCE 监听问题,今天帮同事处理问题时,他问道一种情况,开始连接很正常,后续多次出现ORA-12537问题 简单整理了下 一般请况下 1-检查数据库服务器是否没有启动监听 ...

  3. 整理ViewController的生命周期和加载过程

    按照执行顺序排列 - initWithCoder:通过nib文件初始化时触发 - awakeFromNib:nib文件被加载的时候,会发送一个awakeFromNib的消息到nib文件中的每个对象 p ...

  4. iOS判断是模拟器还是真机

    #if TARGET_IPHONE_SIMULATOR //模拟器   #elif TARGET_OS_IPHONE //真机   #endif

  5. 媒体查询(pc端,移动端不同布局)

    媒体查询语法: 1.内联写法:and之后必须有空格@media screen and (min-width:960px //判断浏览器大小条件){body{background:red} //常规的样 ...

  6. K线图学习

    本博文(适合入门的股民朋友)内容来自网络,股市有风险,入市需谨慎 一.起源 K线图(Candlestick Charts)又称蜡烛图.日本线.阴阳线.棒线等,常用说法是“K线”,起源于日本十八世纪德川 ...

  7. unison+inotify

    hostnamectl --static set-hostname tCentos 1.下载文件到/usr/local/srcocamlunisoninotify-tools 2.安装inotify- ...

  8. HDU(1285)—确定比赛名次

    /*最近都在复习期末了...好久没做题,都快没智商了*/   有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后 ...

  9. webpack如何与gulpfile联合的使用

    一.对webpack的一些理解 webpack支持CommonJS的书写形式. CommonJS指一个文件一个模块,但会一次性加载(即同步加载),但在浏览器端不适用这种方式,加载速率什么的,于是引入了 ...

  10. Node.js Ubuntu下安装

    安装 Node.js 依次执行以下指令: sudo apt-get update sudo apt-get install -y python-software-properties python g ...