Using an Iterable Batch Scope

All of the sample code so far has used a QueryLocator object to define the scope of its batch. This enables up to 50 million records to be processed by the batch job, but requires that the scope be defined entirely using a single SOQL statement. This can be too limiting for some batch processing tasks, so the iterable batch scope is offered as an alternative.

The iterable scope allows custom Apex code to determine which records are processed in the batch. For example, you could use an iterable scope to filter the records using criteria that are too complex to be expressed in SOQL. The downside of the iterable approach is that standard SOQL limits apply. This means you can process a maximum of 50,000 records in your batch job, a dramatic reduction from the 50 million record limit of a QueryLocator object.

To develop a batch with iterable scope, you must first write code to provide data to the batch. There are two parts to this task:

Image Implement the Iterator interface—The Iterator is a class for navigating a collection of elements. It navigates in a single direction, from beginning to end. It requires that you implement two methods: hasNext and next. The hasNext method returns true if additional elements are left to navigate to, false when the end of the collection has been reached. The next method returns the next element in the collection. Iterator classes must be global.

Image Implement the Iterable interface—Think of this class as a wrapper or locator object that directs the caller to an Iterator. It requires a single global method to be implemented, called Iterator, which returns an Iterable object. Like Iterator, classes implementing Iterable must be global.

You could write two separate classes, one to implement each interface. Or you can implement both interfaces in a single class, the approach taken in the code in Listing 9.5.

Listing 9.5 Project Iterator


global class ProjectIterable
  implements Iterator<Project__c>, Iterable<Project__c> {
  List<Project__c> projects { get; set; }
  Integer i;
  public ProjectIterable() {
    projects = [SELECT Name FROM Project__c ORDER BY Name ];
    i = 0;
  }
  global Boolean hasNext() {
    if (i >= projects.size()) {
      return false;
    } else {
      return true;
    }
  }
  global Project__c next() {
    i++;
    return projects[i-1];
  }
  global Iterator<Project__c> Iterator() {
    return this;
  }
}


With the implementation of the Iterable class ready for use, examine the code in Listing 9.6. It is very similar to the first Batch Apex example. The only notable differences are that the parameterized type has been changed from SObject to Project__c, and the start method now returns the Iterable class developed in Listing 9.5.

Listing 9.6 Iterable Batch Apex Sample


global class Listing9_6
  implements Database.Batchable<Project__c> {
  global Iterable<Project__c> start(Database.BatchableContext context) {
    System.debug('start'),
    return new ProjectIterable();
  }
  global void execute(Database.BatchableContext context,
    List<Project__c> scope) {
    System.debug('execute'),
    for(Project__c rec : scope) {
      System.debug('Project: ' + rec.Name);
    }
  }
  global void finish(Database.BatchableContext context) {
    System.debug('finish'),
  }
}


Turn on the debug log for your user and run the Listing9_6 job. Examine the logs and see for yourself that you’ve accomplished the same work as the Listing9_1 code using an iterable scope instead of a QueryLocator object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.116.43