Apex計划作業框架的實現


Apex計划作業框架的實現

在本文中,我們實現一個簡單的“計划作業框架”,用於實現數據的定時自動處理。

Apex相關接口

Apex中提供了一組接口用來實現數據的處理。我們主要使用以下兩個:

  • Schedulable:數據的定時處理
  • Batchable:數據的批量處理

示例情景

本文以如下情景為例,實現計划作業框架。

  • 數據模型:在Salesforce中有一個銀行賬號對象,API名稱為“BankAccount__c”。在此對象中有字段“到期日期”,API名稱為“ExpireDate__c”,和字段“狀態”,API名稱為“Status__c”。

  • 業務流程:

  1. 每天夜里的固定時間,系統需要自動檢查銀行賬號,並將“到期日期”和當前日期作比較
  2. 如果銀行賬號到期,則將“狀態”字段的值更新為“過期”
  • 業務邏輯代碼:在Salesforce中已經相應的業務邏輯,存放在Apex類“BankAccount_Status_Handler”中,對應的函數是“updateExpireStatus()”

框架組成部分

計划作業框架要實現的功能是定時對大批量的數據進行處理,由兩個Apex類組成:

  1. BankAccount_Batch_Status_Handler:實現了Batchable接口,查詢並提取批量數據,並調用Apex類“BankAccount_Status_Handler”中的函數對銀行賬號對象進行處理
  2. BankAccount_Batch_Status_SCH:實現了Schedulable接口,用於在Salesforce的設置界面中設置定時的任務,執行“BankAccount_Batch_Status”類的功能

代碼

BankAccount_Status_Handler類:

public class BankAccount_Status_Handler {

    public static void updateExpireStatus(Set<Id> bankAccountIds) {
        // 業務邏輯
        // ...
    }

}

BankAccount_Batch_Status_Handler類:

global class BankAccount_Batch_Status_Handler implements Database.Batchable<sObject> {

    public Database.QueryLocator start(Database.BatchableContext bc) {
        // 初始化,得到需要處理的數據
        return Database.getQueryLocator([SELECT Id, ExpireDate__c FROM BankAccount__c]);
    }

    public void execute(Database.BatchableContext bc, List<SObject> scope) {
        // 得到需要處理的數據的Id集合
        Set<Id> scopeIds = new Map<Id, SObject>(scope).keySet();

        // 進行處理
        BankAccount_Status_Handler.updateExpireStatus(scopeIds);
    }
    
    public void finish(Database.BatchableContext bc) {}

}

BankAccount_Batch_Status_SCH類:

global class BankAccount_Batch_Status_SCH implements Schedulable {

    public void execute(SchedulableContext sc) {
        // 初始化 BankAccount_Batch_Status_Handler 類
        BankAccount_Batch_Status_Handler batch = new BankAccount_Batch_Status_Handler();
            
        // 執行批處理操作
        Database.executebatch( batch, 200 );
    }
    
}

設置Job的執行

“BankAccount_Batch_Status_SCH”類實現了“Schedulable”接口,所以可以被設定為自動執行。

在Salesforce的設置界面,查找“Apex”,點擊“Apex 類”鏈接,進入Apex類的一覽表。

點擊“計划Apex”按鈕,在其中的“Apex 類”部分選擇“BankAccount_Batch_Status_SCH”類,然后設定其他的屬性。

這樣,計划作業框架就建立完成了。代碼中的邏輯會在固定的時間自動執行。

優化

上述的代碼是由兩個分別實現了Schedulable和Batchable接口的類所組成,其中直接寫死了調用銀行賬戶對象相關的類和邏輯。

我們可以將它們擴展為通用的框架,增加復用性。

停用已經計划的Apex類

在重構代碼之前,因為“BankAccount_Batch_Status_SCH”類已經被設定了計划執行,所以“BankAccount_Batch_Status_SCH”類和其調用的類都不能被修改。

要想進行代碼重構,必須先停止已經計划的Apex類。

在設置界面搜索“計划的作業”,點擊“計划的作業”鏈接,進入“所有計划的作業”一覽表。在表中可以直接刪除“BankAccount_Batch_Status_SCH”類的計划。

對Batchable相關的類進行擴展

新建一個Apex類,名叫“Job_Batch_Handler_Abstract”,代碼如下:

public abstract class Job_Batch_Handler_Abstract implements Database.Batchable<sObject> {
	
    protected abstract Database.QueryLocator getQueryLocator(); // 抽象函數,用於得到需要處理的數據
    protected abstract void executeLogic(Set<Id> scopeIds); // 抽象函數,用於執行具體的邏輯
    
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return getQueryLocator(); // 動態得到需要處理的數據
    }
	
    public void execute(Database.BatchableContext bc, List<SObject> scope) {
        // 得到需要處理的數據的Id集合
        Set<Id> scopeIds = new Map<Id, SObject>(scope).keySet();
		
        // 進行處理,具體的邏輯需要具體實現
        executeLogic(scopeIds);
    }
    
    public void finish(Database.BatchableContext bc) {}

}

將之前的“BankAccount_Batch_Status_Handler”類改為繼承了“Job_Batch_Handler_Abstract”類:

global class BankAccount_Batch_Status_Handler extends Job_Batch_Handler_Abstract {
    
    protected override Database.QueryLocator getQueryLocator() {
        // 初始化,得到需要處理的數據
        return Database.getQueryLocator([SELECT Id, ExpireDate__c FROM BankAccount__c]);
    }
    
    protected override void executeLogic(Set<Id> scopeIds) {
        // 具體的處理邏輯
        BankAccount_Status_Handler.updateExpireStatus(scopeIds);
    }

}

這樣,“Job_Batch_Handler_Abstract”類就可以作為通用的類,被其他的類所繼承和使用。

對Schedulable相關的類進行擴展

新建一個Apex類,名叫“Job_Batch_SCH_Abstract”,代碼如下:

public abstract class Job_Batch_SCH_Abstract implements Schedulable {

    protected abstract String getHandlerName(); // 抽象函數,用於得到具體的類名字

    public void execute(SchedulableContext sc) {
        // 根據開發者定義的類名,新建相應類的實例
        Object o = Type.forName( getHandlerName() ).newInstance();
        
        Job_Batch_Handler_Abstract batch;
        
        // 檢查新的實例是否是Job_Batch_Handler_Abstract抽象類的子類。如果是,則執行批量處理
        if ( o != null && o instanceof Job_Batch_Handler_Abstract) {
            batch = (Job_Batch_Handler_Abstract) o;
            
            Database.executebatch( batch, 200 );
        }
    }

}

將之前的“BankAccount_Batch_Status_SCH”類改為繼承了“Job_Batch_SCH_Abstract”類:

global class BankAccount_Batch_Status_SCH extends Job_Batch_SCH_Abstract {
    
    protected override String getHandlerName(){
        return 'BankAccount_Batch_Status_Handler';
    }
    
}

這樣,“Job_Batch_SCH_Abstract”類就可以作為通用的類,被其他的類所繼承和使用。

完成了這兩個通用類的實現,就可以在Salesforce的設置界面為“BankAccount_Batch_Status_SCH”類重新設定自動執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM