Use Batch Apex



如果您有很多記錄要處理,例如數據清理或歸檔,則Batch Apex可能是您最好的解決方案。



假設您要使用Batch Apex處理100萬條記錄。

對於要處理的每批記錄,一次調用批處理類的執行邏輯。

每次調用批處理類時,該作業都會被放置在Apex作業隊列中,並作爲離散事務執行

此功能有兩個很棒的優點:







在批處理Apex中使用狀態

Batch Apex通常是無狀態的。批處理Apex作業的每次執行均被視爲離散事務。

例如,一個包含1,000條記錄並使用默認批處理大小的批處理Apex作業被視爲5個事務,每個事務200條記錄。



假設您有一項業務要求,其中規定,美國公司的所有聯繫人都必須以其母公司的Account 地址作爲其郵寄地址。

不幸的是,用戶正在輸入沒有正確地址的新聯繫人!

編寫一個Batch Apex類,以確保強制執行此要求。

global class UpdateContactAddresses implements 
    Database.Batchable<sObject>, Database.Stateful {
    
    // instance member to retain state across transactions
    global Integer recordsProcessed = 0;
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(
            'SELECT ID, BillingStreet, BillingCity, BillingState, ' +
            'BillingPostalCode, (SELECT ID, MailingStreet, MailingCity, ' +
            'MailingState, MailingPostalCode FROM Contacts) FROM Account ' + 
            'Where BillingCountry = \'USA\''
        );
    }
    global void execute(Database.BatchableContext bc, List<Account> scope){
        // process each batch of records
        List<Contact> contacts = new List<Contact>();
        for (Account account : scope) {
            for (Contact contact : account.contacts) {
                contact.MailingStreet = account.BillingStreet;
                contact.MailingCity = account.BillingCity;
                contact.MailingState = account.BillingState;
                contact.MailingPostalCode = account.BillingPostalCode;
                // add contact to list to be updated
                contacts.add(contact);
                // increment the instance member counter
                recordsProcessed = recordsProcessed + 1;
            }
        }
        update contacts;
    }    
    global void finish(Database.BatchableContext bc){
        System.debug(recordsProcessed + ' records processed. Shazam!');
        AsyncApexJob job = [SELECT Id, Status, NumberOfErrors, 
            JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob
            WHERE Id = :bc.getJobId()];
        // call some utility to send email
        EmailUtils.sendMessage(job, recordsProcessed);
    }    
}


測試批處理Apex

由於Apex開發和測試是並行進行的

@isTest
private class UpdateContactAddressesTest {
    @testSetup 
    static void setup() {
        List<Account> accounts = new List<Account>();
        List<Contact> contacts = new List<Contact>();
        // insert 10 accounts
        for (Integer i=0;i<10;i++) {
            accounts.add(new Account(name='Account '+i, 
                billingcity='New York', billingcountry='USA'));
        }
        insert accounts;
        // find the account just inserted. add contact for each
        for (Account account : [select id from account]) {
            contacts.add(new Contact(firstname='first', 
                lastname='last', accountId=account.id));
        }
        insert contacts;
    }
    static testmethod void test() {        
        Test.startTest();
        UpdateContactAddresses uca = new UpdateContactAddresses();
        Id batchId = Database.executeBatch(uca);
        Test.stopTest();
        // after the testing stops, assert records were updated properly
        System.assertEquals(10, [select count() from contact where MailingCity = 'New York']);
    }
    
}




Create an Apex class that uses Batch Apex to update Lead records

LeadProcessor.apxc

global class LeadProcessor implements  Database.Batchable<Sobject> 
{
    global Database.QueryLocator start(Database.BatchableContext bc) 
    {
        return Database.getQueryLocator([Select LeadSource From Lead ]);
    }
    
    global void execute(Database.BatchableContext bc, List<Lead> scope)
    {
        for (Lead Leads : scope) 
        {
            Leads.LeadSource = 'Dreamforce';
        }
        update scope;
    }    
    
    global void finish(Database.BatchableContext bc){   }    
}

LeadProcessorTest.apxc

@isTest
public class LeadProcessorTest
{
    static testMethod void testMethod1()
    {
        List<Lead> lstLead = new List<Lead>();
        for(Integer i=0 ;i <200;i++)
        {
            Lead led = new Lead();
            led.FirstName = 'FirstName';
            led.LastName = 'LastName' +i;
            led.Company = 'demo' +i;
            lstLead.add(led);
        }
        insert lstLead;
        Test.startTest();
        LeadProcessor obj = new LeadProcessor();
        Database.executeBatch(obj);
        Test.stopTest();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章