Salesforce Batch Apex 批处理(一)

2021-11-20 08:06:49 浏览数 (1)

Apex SOQL 每次最多只能查询50000条数据,DML 可以操作的数据更少只有10000条,如果想要处理大量数据,就要考虑使用Batch Apex功能,Batch Apex实现Database.batchable接口

Datebase.Batchable封装了以下三个方法:

1.start方法

代码语言:javascript复制
public (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {} 

用于收集要操作的数据,然后将数据传到execute()进行具体操作,使用SOQL取得的合计数没有制限,

例如,对于Account来说,最大可以存储5000万件,全部可以返回。

2.execute方法

代码语言:javascript复制
public void execute(Database.BatchableContext BC, list<P>){} 

对start方法传进来的数据进行处理。

3.finish方法

代码语言:javascript复制
public void finish(Database.BatchableContext BC){}

batch执行完毕执行,一般用作邮件通知,或者后续操作。

4.Database.executeBatch方法

调用此方法,可以开始执行批处理,

有两个参数,第一个是被执行Batch的Class名,第二个是传入execute方法的Record数

5.实装例

代码语言:javascript复制
global with sharing class ExampleUpdateRecordBatch implements Database.Batchable<sObject>,Database.Stateful,Database.AllowsCallouts {
    public ExampleUpdateRecordBatch() {

    }
    global Database.QueryLocator start(Database.BatchableContext BC) {
        String queryS = 'SELECT Id,Name FROM Opportunity WHERE DeleteFlg__c = true';
        return Database.getQueryLocator(queryS);
    }
    global void execute(Database.BatchableContext BC, list<sObject> scope) {
        Savepoint sp = Database.setSavepoint();
        try {
            List<Opportunity> newOppList = new List<Opportunity>();
            for(Opportunity opportunityItem : (List<Opportunity>)scope) {
                opportunityItem.stageName = 'Closed Won';
                newOppList.add(opportunityItem);
            }
            update newOppList;
        } catch (Exception ex) {
            Database.rollback(sp);
        }
    }

    global void finish(Database.BatchableContext BC) {

    }
}

Batch执行:为了测试,我们在匿名框中执行以下代码

代码语言:javascript复制
ExampleUpdateRecordBatch batchTest = new ExampleUpdateRecordBatch();
Database.executeBatch(batchTest, 2000);

执行结果:

6.测试类

代码语言:javascript复制
@IsTest
private with sharing class ExampleUpdateRecordBatchTest {
    @TestSetup
    static void initialOrgInfo(){
        String strUserName = 'BatchTest001';
        Profile profile = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        User batchTestUser = new User();
        batchTestUser.ProfileId = profile.Id;
        batchTestUser.UserName = strUserName   '@sample.com';
        batchTestUser.FirstName = '';
        batchTestUser.LastName = strUserName;
        batchTestUser.EMail = 'testuser@sample.com';
        batchTestUser.Alias = 'testuser';
        batchTestUser.TimeZoneSidKey = 'Asia/Tokyo';
        batchTestUser.LocaleSidKey = 'ja_JP';
        batchTestUser.EmailEncodingKey = 'ISO-2022-JP';
        batchTestUser.LanguageLocaleKey = 'ja';
        Database.insert(batchTestUser, false);

        PermissionSet permissionSet = [SELECT Id
                                        FROM PermissionSet
                                        WHERE Name = 'Ursus_Park_User'];
        PermissionSetAssignment assignmentAss = new PermissionSetAssignment();
        assignmentAss.AssigneeId = batchTestUser.Id;
        assignmentAss.PermissionSetId = permissionSet.Id;
        Database.insert(assignmentAss, false);
    }
    @IsTest static void testBatch001() {
        User runUser = [SELECT ID, UserName FROM User WHERE username='BatchTest001@sample.com'];
        List <Opportunity> oppList = new List<Opportunity>();
        for(integer i = 0; i<200; i  ){
            Opportunity oppItem = new Opportunity(Name='testOpportunity'  i,
                                StageName='Perception Analysis',
                                Ownerid = runUser.Id,
                                CloseDate = Date.Today(),
                                DeleteFlg__c = true);
            oppList.add(oppItem);
        }
        insert oppList;
        System.runAs(runUser) {
            Test.StartTest();
            ExampleUpdateRecordBatch reassign = new ExampleUpdateRecordBatch();
            ID batchprocessid = Database.executeBatch(reassign, 200);
            Test.StopTest();
        }
        List<Opportunity> oppUpdateList = [SELECT Id,StageName FROM Opportunity WHERE Ownerid = :runUser.Id];
        System.assertEquals(200, oppUpdateList.size());
        if (oppUpdateList != null && oppUpdateList.size() >0) {
            for (Opportunity oppUpdate : oppUpdateList) {
                System.assertEquals('Closed Won', oppUpdate.StageName);
            }
        }
    }
}

TestClass执行

0 人点赞