📜  Apex-批处理

📅  最后修改于: 2020-11-05 03:20:43             🧑  作者: Mango


在本章中,我们将了解Apex中的批处理。考虑一个场景,在该场景中,我们将每天处理大量记录,可能是清除数据或删除一些未使用的数据。

什么是批处理Apex?

批处理Apex是Apex代码的异步执行,是专门为处理大量记录而设计的,并且与同步代码相比,在调控器限制方面具有更大的灵活性。

何时使用批处理Apex?

  • 如果您想每天甚至在特定的时间间隔内处理大量记录,则可以使用Batch Apex。

  • 另外,当您希望操作异步时,可以实现Batch Apex。 Batch Apex作为必须由开发人员实现的接口公开。批处理作业可以在运行时使用Apex进行编程调用。 Batch Apex可处理少量记录,涵盖您的整个记录集,并将处理分解为可管理的数据块。

使用批处理Apex

使用批处理Apex时,必须实现Salesforce提供的接口Database.Batchable,然后以编程方式调用该类。

您可以按照以下步骤监控课程-

要监视或停止批处理Apex批处理作业的执行,请转至设置→监视→Apex作业或作业→Apex作业。

监视Apex批次Step1

监控Apex批次Step2

Database.Batchable接口具有以下三种需要实现的方法-

  • 开始
  • 执行

现在让我们详细了解每种方法。

开始

Start方法是Database.Batchable接口的三种方法之一。

句法

global void execute(Database.BatchableContext BC, list

批处理作业开始时将调用此方法,并收集将在其上运行批处理作业的数据。

考虑以下几点以了解方法-

  • 使用简单查询生成批处理作业中使用的对象范围时,请使用Database.QueryLocator对象。在这种情况下,将绕过SOQL数据行限制。

  • 当您具有复杂的条件来处理记录时,请使用可迭代的对象。 Database.QueryLocator确定应处理的记录范围。

执行

现在让我们了解Database.Batchable接口的Execute方法。

句法

global void execute(Database.BatchableContext BC, list

其中,list

在Start方法之后调用此方法,并执行批处理作业所需的所有处理。

现在,我们将讨论Database.Batchable接口的Finish方法。

句法

global void finish(Database.BatchableContext BC) {}

该方法在最后被调用,您可以执行一些整理活动,例如发送一封电子邮件,其中包含有关已处理的批处理作业记录和状态的信息。

批处理Apex示例

让我们考虑一个现有化学公司的示例,并假设我们有要求更新已标记为有效且已创建日期为今天的客户记录的“客户状态”和“客户描述”字段。这应该每天进行,并且应将有关批处理状态的电子邮件发送给用户。将客户状态更新为“已处理”,将客户描述更新为“通过批处理作业更新”。

// Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable {
   global String [] email = new String[] {'test@test.com'};
   // Add here your email address here
  
   // Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
      APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
      AND APEX_Active__c = true');
      // Query which will be determine the scope of Records fetching the same
   }
   
   // Execute method
   global void execute (Database.BatchableContext BC, List scope) {
      List customerList = new List();
      List updtaedCustomerList = new List();
      
      // List to hold updated customer
      for (sObject objScope: scope) {
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;
         
         // type casting from generic sOject to APEX_Customer__c
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         updtaedCustomerList.add(newObjScope); // Add records to the List
         System.debug('Value of UpdatedCustomerList '+updtaedCustomerList);
      }
      
      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
         // Check if List is empty or not
         Database.update(updtaedCustomerList); System.debug('List Size '
          + updtaedCustomerList.size());
         // Update the Records
      }
   }
   
   // Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      
      // Below code will fetch the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];
      
      // get the job Id
      System.debug('$$$ Jobid is'+BC.getJobId());
      
      // below code will send an email to User about the status
      mail.setToAddresses(email);
      mail.setReplyTo('test@test.com'); // Add here your email address
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed'
         + a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
      processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }
}

要执行此代码,请先保存它,然后将以下代码粘贴到“执行匿名”中。这将创建类的对象,而Database.execute方法将执行Batch作业。作业完成后,将向指定的电子邮件地址发送一封电子邮件。确保您有一个客户记录,其中已选中“活动”。

// Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProessingBatch();
Database.executeBatch (objClass);

执行完此类后,请检查您提供的电子邮件地址,您将在其中收到带有信息的电子邮件。另外,您可以通过“监视”页面和上述步骤检查批处理作业的状态。

如果检查调试日志,则可以找到列表大小,该大小指示已处理了多少条记录。

局限性

我们一次只能进行5个批处理作业。这是Batch Apex的局限性之一。

使用Apex详细信息页面计划Apex批处理作业

您可以通过Apex详细信息页面安排Apex类,如下所示-

步骤1-转到设置⇒Apex类,单击Apex类。

从明细页面Step1安排Apex

步骤2-单击Schedule Apex按钮。

从明细页面Step2安排Apex

步骤3-提供详细信息。

从详细信息页面调度Apex

使用可调度界面调度Apex批处理作业

您可以使用可调度界面安排Apex批处理作业,如下所示-

// Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable {
   global String [] email = new String[] {'test@test.com'};
   // Add here your email address here
   
   // Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
      APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
      AND APEX_Active__c = true');
      // Query which will be determine the scope of Records fetching the same
   }
   
   // Execute method
   global void execute (Database.BatchableContext BC, List scope) {
      List customerList = new List();
      List updtaedCustomerList = new
      List();//List to hold updated customer
      
      for (sObject objScope: scope) {
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;//type
         casting from generic sOject to APEX_Customer__c
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         updtaedCustomerList.add(newObjScope);//Add records to the List
         System.debug('Value of UpdatedCustomerList '+updtaedCustomerList);
      }
      
      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
         // Check if List is empty or not
         Database.update(updtaedCustomerList); System.debug('List Size'
            + updtaedCustomerList.size());
         // Update the Records
      }
   }
 
   // Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      
      // Below code will fetch the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];//get the job Id
      System.debug('$$$ Jobid is'+BC.getJobId());
      
      // below code will send an email to User about the status
      mail.setToAddresses(email);
      mail.setReplyTo('test@test.com');//Add here your email address
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed' 
         + a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
      processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }
   
   // Scheduler Method to scedule the class
   global void execute(SchedulableContext sc) {
      CustomerProessingBatch conInstance = new CustomerProessingBatch();
      database.executebatch(conInstance,100);
   }
}

// Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProcessingBatch();
Database.executeBatch (objClass);