> Apex中文手册 > Apex - 批量处理

考虑一种情况,您希望每天处理大量的记录,可能是清理数据或可能删除一些未使用的数据。

什么是Batch Apex?

Batch Apex是异步执行的Apex代码,专门用于处理大量记录,并且在调节器限制方面比同步代码具有更大的灵活性。


什么时候使用批量处理Apex?

  • 当你想要每天处理大量的记录,或者在特定的时间间隔,你可以去批量Apex。
  • 另外,当你想要一个操作是异步的,你可以实现批处理。批处理Apex作为必须由开发人员实现的接口公开。批量处理作业可以在运行时使用Apex以编程方式调用。 Batch Apex对小批量记录进行操作,覆盖整个记录集,并将处理过程分解为可管理的数据块。

使用批量处理

当我们使用Batch Apex时,我们必须实现Salesforce提供的接口Database.Batchable,然后以编程方式调用类。


您可以通过以下步骤监视类:


要监视或停止批处理Apex Batch作业的执行,请转到设置 - >监视 - > Apex作业或作业 - > Apex作业。


Apex - 批量处理

Apex - 批量处理

Database.Batchable接口有三个方法,我们必须实现如下:

Start开始

  • Start开始
  • Execute执行
  • Finish结束

让我们看看他们中的每一个。


Start:

语法:

global (Database.QueryLocator | Iterable) start(Database.BatchableContext bc) {}

此方法将在启动批处理作业时调用,并收集将在其上操作批处理作业的数据。


请注意以下几点:

  • 在使用简单查询生成批处理作业中使用的对象范围时,请使用Database.QueryLocator对象。 在这种情况下,将绕过SOQL数据行限制。
  • 当您有复杂的条件来处理记录时,使用iterable对象。 Database.QueryLocator确定应该处理的记录的范围。

执行:

语法:

global void execute(Database.BatchableContext BC, list<sobject<){}

其中,list <sObject <由Database.QueryLocator方法返回。

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


结束:

语法:

global void finish(Database.BatchableContext BC){}

此方法在结束时调用,您可以执行一些整理活动,例如发送包含有关处理的批处理作业记录和状态的信息的电子邮件。


批量Apex示例

让我们举一个例子,我们现有的化学公司,让我们假设我们需要更新客户状态和客户记录的客户记录已被标记为活动,并创建日期为今天。 这应该每天进行,并且应该向用户发送有关批处理状态的电子邮件。 将客户状态更新为“已处理”,将客户状态更新为“通过批处理作业更新”。

//Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject>{
  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<sobject> scope) {
    List<apex_customer__c> customerList = new List<apex_customer__c>();
    List<apex_customer__c> updtaedCustomerList = new List<apex_customer__c>();//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});
  }
}

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

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

执行此类后,请检查您提供的电子邮件地址,您将收到包含信息的电子邮件。 此外,您可以通过监视页面和上面提供的步骤检查批处理作业的状态。


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


限制

我们一次只能有5个批处理作业。 这是Batch Apex的限制之一。


使用Apex详细信息页面计划Apex Batch作业

您可以通过Apex详细信息页面安排Apex类,以及如下:


第1步:转到Setup => Apex类,单击Apex类。


Apex - 批量处理

第2步:点击Schedule Apex按钮:


Apex - 批量处理


第3步:提供详细信息:


Apex - 批量处理


第4步:然后点击保存按钮,您的类将被安排。


使用可调度接口计划Apex Batch作业

//Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject>{  
  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<sobject> scope) {
    List<apex_customer__c> customerList = new List<apex_customer__c>();
    List<apex_customer__c> updtaedCustomerList = new List<apex_customer__c>();//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 CustomerProessingBatch();
Database.executeBatch (objClass);