Salesforce使用Batch Class

场景描述:UAT过后,我们需要将客户的历史数据导进生产环境,由于记录体量很大,通常会先关闭部分Trigger,Process Builder,Workflow等来保证数据能成功导入,事后,为了保证业务数据的合理性,我们会使用Batch来更新那些被禁用后的逻辑。
Template Code:
Batch class:

global class ExampleBatchClass implements Database.Batchable<sObject>{
    global ExampleBatchClass(){
        // Batch Constructor
    }
    // Start Method
    global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(query);
    }
    // Execute Logic
    global void execute(Database.BatchableContext BC, List<sObject>scope){
        // Logic to be Executed batch wise      
    }
    global void finish(Database.BatchableContext BC){
        // Logic to be Executed at finish
    }
}

Call the batch class:
ExampleBatchClass b = new ExampleBatchClass(); 
//Parameters of ExecuteBatch(context,BatchSize)
database.executebatch(b,10);

Note: if batch size is not mentioned it is 200 by default.

Sample:将Org中所有Lead历史数据的Status更新为Closed
Code Snap:

global class LeadProcessor implements Database.Batchable<sObject>, Database.Stateful {
	// instance member to retain state across transactions
    global Integer recordsProcessed = 0;
    global Database.QueryLocator start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
        String str = 'select Id, Status from Lead';
        return Database.getQueryLocator(str);
    }

    global void execute(Database.BatchableContext bc, List<Lead> records){
        // process each batch of records
        List<Lead> ldList = new List<Lead>();
        for(Lead l : records) {
            l.Status = 'Closed';
            ldList.add(l);
            recordsProcessed ++;
        }
        update ldList;
    }    

    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
        System.debug(recordsProcessed + ' records processed.');
        AsyncApexJob job = [SELECT Id, Status, NumberOfErrors, 
                            JobItemsProcessed,
                            TotalJobItems, CreatedBy.Email
                            FROM AsyncApexJob
                            WHERE Id = :bc.getJobId()];
    }    

}
Test Code:
@isTest
private class LeadProcessorTest {
    @testSetup 
    static void setup() {
        List<Lead> ldList = new List<Lead>();
        for(Integer i = 0; i < 200; i++) {
            ldList.add(new Lead(LastName = 'Lead' + i, Company = 'com' + i, Status = 'Open'));
        }
        insert ldList;
    }
    static testMethod void test1() {
        Test.startTest();
        LeadProcessor lp = new LeadProcessor();
        Id batchId = Database.executeBatch(lp);
        Test.stopTest();
    }
}
在Developer Console的Open Excute Anonymous Window执行以下代码:
LeadProcessor leadBach = new LeadProcessor(); 
Id batchId = Database.executeBatch(leadBach, 100);
参考资料:
https://trailhead.salesforce.com/modules/asynchronous_apex/units/async_apex_batch
补充:
Batch特性:如果我们在start里面写查询语句,如果查询中包含关系字段(除关系ID外),那么debug时是出不来关系字段的值的,这时候如果用公式字段代替关系字段,同样debug不出值;如果我们在excute里面做查询,那么debug出来的只有ID和Name的值,其他字段值也出不来。

举例:我们需要处理Account和Contact,在start里面查询语句为:select id, name, accountid, account.site from contact,那么只能debug出id, name, accountid的值;如果我们在excute里面写入:select id, name, site from account,只能debug出id和name的值。
建议:如果是跨对象的过滤,首先将子对象记录在start中查处来(Id),然后在excute里面将查出来的id作为参数传入外部异步方法,该方法主要用来使用select再次查询,这个时候就可以debug出关系字段了,意思是就可以做过滤了。
参考文档:http://www.iterativelogic.com/developing-custom-apex-rollup-summary-field-logic/









猜你喜欢

转载自blog.csdn.net/itsme_web/article/details/78971322