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”类重新设定自动执行。

Apex计划作业框架的实现的更多相关文章

  1. JobEngine 基于quartz.net 跨平台作业框架

    github:https://github.com/zzhi/JobEngine 基于quartz.net 的跨平台作业框架 quartz.net(https://github.com/quartzn ...

  2. [转帖]Linux教程(11)- linux中的计划作业

    Linux教程(11)- linux中的计划作业 2018-08-21 17:13:36 钱婷婷 阅读数 160更多 分类专栏: Linux教程与操作 Linux教程与使用   版权声明:本文为博主原 ...

  3. asp.net 后台任务作业框架收集

    收集几个可以用于 asp.net 的后台任务工具库并简单介绍. hangfire.io 支持 单次任务(Fire-and-forget),延时任务(Delayed),重复任务(Recurring ), ...

  4. HHR计划---作业复盘-直播第三课

    一,出租车广告: 1,三个点不合格:周期太长了,大而全互联网产品,不符合MVP原则:业务关键点丢掉了:没有业务认知和成长. 2,关键假设: (1)车主有没有需求呀,画像怎么样? (2)车主收入如何,能 ...

  5. Phoenix核心功能原理及应用场景介绍以及Calcite 查询计划生成框架介绍

    Phoenix是一个开源的HBase SQL层.它不仅可以使用标准的JDBC API替代HBase Client API创建表,插入和查询HBase,也支持二级索引.事物以及多种SQL层优化. 此系列 ...

  6. Linux计划作业练习

    1.crontab -eu zh  //每天晚上10天提醒用户可以去睡觉了 * */10  * *  * go to sleep 2.查询crontab的工作内容 3.当crontab命令格式出错时 ...

  7. 新一代分布式任务调度框架:当当elastic-job开源项目的10项特性

    作者简介: 张亮,当当网架构师.当当技术委员会成员.消息中间件组负责人.对架构设计.分布式.优雅代码等领域兴趣浓厚.目前主导当当应用框架ddframe研发,并负责推广及撰写技术白皮书.   一.为什么 ...

  8. ABP框架学习

    一.总体与公共结构 1,ABP配置 2,多租户 3,ABP Session 4,缓存 5,日志 6,设置管理 7,Timing 8,ABPMapper 9,发送电子邮件 二.领域层 10,实体 11, ...

  9. .NET Core下开源任务调度框架Hangfire的Api任务拓展(支持秒级任务)

    HangFire的拓展和使用 看了很多博客,小白第一次写博客. 最近由于之前的任务调度框架总出现问题,因此想寻找一个替代品,之前使用的是Quartz.Net,这个框架方便之处就是支持cron表达式适合 ...

随机推荐

  1. Nginx + Tomcat 在 Windows7 上搭建负载均衡集群

    一.安装Tomcat和Nginx 首先安装两个apache-tomcat-8.0.41,下载地址:http://tomcat.apache.org 并安装一个nginx-1.13.0,下载地址http ...

  2. Rocketmq日志收集与logback集成Demo

    官方文档有简洁的例子,这里就做一个简单补充和实践 直接上logback-boot.xml文件 <?xml version="1.0" encoding="UTF-8 ...

  3. 使用node.js + json-server + mock.js 搭建本地开发mock数据服务

    在开发过程中,前后端不论是否分离,接口多半是滞后于页面开发的.所以建立一个REST风格的API接口,给前端页面提供虚拟的数据,是非常有必要的.对比过多种mock工具后,我最终选择了使用 json se ...

  4. 声反馈抑制使用matlab/simulink仿真

    第一份工作时做啸叫抑制的仿真,调大0.3可以有大的啸叫产生,下图的SIMULINK仿真模型 实现移相有多种方法: 1.iir实现 2.FFT实现 3.使用FIR实现 所有信号均可以由正弦信号叠加而成.

  5. .NET手记-为ASP.NET MVC程序集成Autofac

    MVC Autofac总是会紧跟最新版本的ASP.NET MVC框架,所以文档也会一直保持更新.一般来讲,不同版本的框架集成Autofac的方法一般不变. MVC集成需要引用 Autofac.Mvc5 ...

  6. html2canvas的踩坑之路

    html2canvas的踩坑之路 前言 早有耳闻这个html2canvas比较坑,但无奈于产品需求的压迫,必须实现html转图片的功能,自此走上了填坑之路,好在最后的效果还算令人满意,这才没有误了产品 ...

  7. php实现聊天室功能

    原理:长连接 一.长连接与短连接 短连接:客户端与服务端每进行一次报文收发交易时才进行通讯连接.交易完毕后立即断开连接. 长连接:客户端与服务端先建立连接, 连接建立后不断开,然后在进行报文发送和接收 ...

  8. Android 源码分析01_AsyncTask

    [参考文献] http://blog.csdn.net/singwhatiwanna/article/details/17596225 /* * Copyright (C) 2008 The Andr ...

  9. Re:从零开始的MySQL入门学习

    Linux作为操作系统,Apache作为Web服务器,MySQL作为数据库,PHP作为服务器端脚本解释器.由于这四个软件都是免费或开放式源码软件,因此使用这种不用花一分钱(人工成本除外)就可以建立起一 ...

  10. Linux 学习手记(1):命令行BASH的基本操作

    1. Shell 是什么 Shell(壳)是用户与操作系统底层(通常是内核)之间交互的中介程序,负责将用户指令.操作传递给操作系统底层. Shell一般分为:图形化Shell(GUI).命令行Shel ...