Apex入门

什么是Apex?

Apex 是一种强类型、面向对象的编程语言,允许开发人员 在 Salesforce 服务器上执行流和事务控制语句,并结合 对 API 的调用。使用看起来像 Java 的语法,并且像存储的数据库一样 过程中,Apex 使开发人员能够将业务逻辑添加到大多数系统事件中,包括 按钮单击、相关记录更新和 Visualforce 页面。Apex 代码可以通过以下方式启动 Web 服务请求和来自对象上的触发器的请求。

作为一种语言,Apex 是:

综合
Apex 提供对常见 Lightning 平台习惯用语的内置支持,包括:
  • 数据操作语言 (DML) 调用,例如 、 和 ,包括内置处理INSERT UPDATE DELETE DmlException
  • 内联 Salesforce 对象查询语言 (SOQL) 和 Salesforce 对象 返回 sObject 记录列表的搜索语言 (SOSL) 查询
  • 允许一次批量处理多条记录的循环
  • 防止记录更新冲突的锁定语法
  • 可从存储的 Apex 方法构建的自定义公共 API 调用
  • 用户尝试编辑或删除自定义项时发出的警告和错误 Apex 引用的对象或字段
简单易用
Apex 基于熟悉的 Java 习语,例如变量和表达式语法, 块和条件语句语法、循环语法、对象和数组表示法。 在 Apex 引入新元素的地方,它使用简单的语法和语义 了解并鼓励有效使用 Lightning 平台。因此 Apex 生成的代码既简洁又易于编写。
以数据为中心
Apex 旨在将多个查询和 DML 语句串联成一个 Salesforce 服务器上的单个工作单元。开发人员使用存储的数据库 将数据库上的多个事务语句串联在一起的过程 服务器以类似的方式。与其他数据库存储过程一样,Apex 不 尝试为在用户中呈现元素提供常规支持 接口。
严格
Apex 是一种强类型语言,它使用对架构对象的直接引用 例如对象和字段名称。如果有的话,它在编译时会很快失败 引用无效。它存储所有自定义字段、对象和类 元数据中的依赖项,以确保它们不会在需要时被删除 活动 Apex 代码。
托管
Apex 完全由闪电解释、执行和控制 平台。
多租户感知
与 Lightning 平台的其他部分一样,Apex 在多租户环境中运行。 因此,Apex 运行时引擎旨在密切防止代码失控, 防止其垄断共享资源。任何违反限制的代码 失败,并显示易于理解的错误消息。
易于测试
Apex 为单元测试的创建和执行提供内置支持。它包括 测试结果,指示覆盖了多少代码,以及 代码可以更有效率。Salesforce 确保所有自定义 Apex 代码都能正常工作 如预期的那样,在任何平台升级之前执行所有单元测试。
版本化
您可以针对不同版本的 API 保存 Apex 代码。这样可以 你保持行为。

了解 Apex 核心概念

Apex 代码通常包含许多您可能熟悉的其他代码 编程语言。
Apex 中的编程元素

本节介绍了 Apex 的基本功能,以及一些核心 概念。

使用版本设置

在 Salesforce 用户界面中,您可以指定 Salesforce API 的版本 保存 Apex 类或触发器的对象。此设置不仅指示 要使用的 SOAP API 版本,以及 Apex 的版本。您可以更改 保存后的版本。每个类或触发器名称都必须是唯一的。你不能 保存相同的类或针对不同版本的触发器。

还可以使用版本设置将类或触发器与特定 组织中安装的托管包的版本 AppExchange。此版本的托管软件包将继续由 类或触发器(如果安装了更高版本的托管包),除非您 手动更新版本设置。要将已安装的托管软件包添加到 设置列表中,从可用包列表中选择一个包。列表是 仅当已安装的托管包尚未安装时显示 与类或触发器相关联。

有关对托管包使用版本设置的更多信息,请参阅 Salesforce 联机帮助中的关于包版本

命名变量、方法和类

在命名变量、方法或 类。这些包括属于 Apex 和 Lightning 平台的单词,例如 作为 、 或 以及保留 关键字。list test account

使用变量和表达式

Apex 是一种强类型语言,也就是说,您必须声明数据 首次引用变量时的类型。Apex 数据类型包括基本类型 例如 Integer、Date 和 Boolean,以及更高级的类型,例如列表、 maps、objects 和 sObjects。

变量使用名称和数据类型进行声明。您可以将值赋给 变量。您也可以稍后分配值。使用以下命令 声明变量时的语法:

datatypevariable_name [ = value];
 

提示

请注意,上述末尾的分号不是可选的。所有语句必须以分号结束。

以下是变量声明的示例:

// The following variable has the data type of Integer with the name Count, 
// and has the value of 0.
Integer Count = 0;
// The following variable has the data type of Decimal with the name Total. Note 
// that no value has been assigned to it.
Decimal Total;
// The following variable is an account, which is also referred to as an sObject.
Account MyAcct = new Account();

在 Apex 中,将传递所有原始数据类型参数,例如 Integer 或 String 按值进入方法。这一事实意味着对参数的任何更改都只存在 在方法的范围内。当该方法返回时,对 参数丢失。

非基元数据类型参数(如 sObjects)通过以下方式传递到方法中 参考。因此,当方法返回时,传入的参数仍然 引用与方法调用之前相同的对象。在方法中, 引用不能更改为指向另一个对象,但 对象的字段可以更改。

using 语句

语句是执行操作的任何编码指令。

在 Apex 中,语句必须以分号结尾,并且可以是以下类型之一:
  • 赋值,例如为变量赋值
  • 条件 (if-else)
  • 循环:
    • 同时做
  • 锁定
  • 数据操作语言 (DML)
  • 交易控制
  • 方法调用
  • 异常处理

是用 curly 组合在一起的一系列语句 大括号,可以在允许单个语句的任何地方使用。为 例:

if (true) {
    System.debug(1);
    System.debug(2);
} else {
    System.debug(3);
    System.debug(4);
}

如果一个块仅包含一个语句,则可以保留大括号 关闭。例如:

if (true) 
    System.debug(1);
else 
    System.debug(2);

使用集合

Apex 具有以下类型的集合:

  • 列表(数组)
  • 地图

列表是元素的集合,例如整数、字符串、对象或 其他集合。当元素的顺序很重要时,使用列表。你可以有 列表中的重复元素。

列表中的第一个索引位置始终为 0。

要创建列表:

  • 使用关键字new
  • 使用关键字后跟 包含在字符中的元素类型。List<>

使用以下语法创建列表:

List <datatype> list_name
   [= new List<datatype>();] |
   [=new List<datatype>{value [, value2. . .]};] |
   ;

下面的示例创建一个 Integer 列表,并将其分配给变量 。请记住,由于 Apex 是强类型的, 您必须将 的数据类型声明为 整数列表。My_ListMy_List

List<Integer> My_List = new List<Integer>();

有关详细信息,请参阅列表

集合是唯一的、无序元素的集合。它可以包含 基元数据类型,如 String、Integer、Date 等。它还可以包含更多 复杂数据类型,例如 sObjects。

要创建集合,请执行以下操作:

  • 使用关键字new
  • 使用关键字后跟 包含在字符中的原始数据类型Set<>

使用以下语法创建集:

Set<datatype> set_name 
   [= new Set<datatype>();] |
   [= new Set<datatype>{value [, value2. . .] };] |
   ;

下面的示例创建一组 String。集合的值是使用 大括号。{}

Set<String> My_String = new Set<String>{'a', 'b', 'c'};

有关详细信息,请参阅

映射是键值对的集合。键可以是任何原始数据 类型。值可以包括基元数据类型,以及对象和其他集合。 按关键事项查找内容时,请使用地图。地图中可以有重复的值, 但每个键必须是唯一的。

要创建地图:

  • 使用关键字new
  • 使用关键字后跟键值对 对,用逗号分隔并用字符括起来。Map<>

使用以下语法创建映射:

Map<key_datatype, value_datatype> map_name
   [=new map<key_datatype, value_datatype>();] | 
   [=new map<key_datatype, value_datatype>
   {key1_value => value1_value 
   [, key2_value => value2_value. . .]};] |
   ;

以下示例创建一个映射,该映射的数据类型为 Integer 的键和 值的字符串。在此示例中,将传入映射的值 在地图所在的大括号之间 创建。{}

Map<Integer, String> My_Map = new Map<Integer, String>{1 => 'a', 2 => 'b', 3 => 'c'};

有关详细信息,请参阅地图。

使用分支

语句是真假测试, 使应用程序能够根据条件执行不同的操作。基本 语法如下:if

if (Condition){
// Do this if the condition is true
} else {
// Do this if the condition is not true
}

有关更多信息,请参见条件 (If-Else) 语句。

使用循环

虽然该语句使你的 应用程序根据条件来做事,循环告诉你的应用程序做 基于条件一次又一次地做同样的事情。Apex 支持以下类型 循环数:if

  • 同时做

Do-while 循环在代码执行后检查条件。

While 循环在代码开始之前检查条件 执行。

For 循环使您能够更精细地控制 循环。此外,Apex 还支持传统的 For 循环,您可以在其中设置 条件,以及使用列表和 SOQL 查询作为 条件。

什么时候应该使用Apex?

Salesforce 预构建应用程序提供强大的 CRM 功能性。此外,Salesforce 还提供了自定义预构建的功能 适合您组织的应用程序。但是,您的组织可能具有复杂的 现有功能不支持的业务流程。在本例中, Lightning Platform 为高级管理员和开发人员提供了多种方式 构建自定义功能。

Apex

如果您想要执行以下操作,请使用 Apex:
  • 创建 Web 服务。
  • 创建电子邮件服务。
  • 对多个对象执行复杂的验证。
  • 创建工作流不支持的复杂业务流程。
  • 创建自定义事务逻辑(在整个 事务,而不仅仅是单个记录或对象)。
  • 将自定义逻辑附加到另一个操作,例如保存记录,以便 每当执行操作时,它都会发生,而不管它是否 源自用户界面、Visualforce 页面或 SOAP API。

闪电组件

开发 Lightning 组件以自定义 Lightning Experience、Salesforce 移动版 应用程序,或构建自己的独立应用程序。您也可以使用开箱即用的 组件以加快开发速度。

从 Spring ’19(API 版本 45.0)开始,您可以使用两个 编程模型:Lightning Web 组件模型和原始 Aura 组件模型。Lightning Web 组件是使用 HTML 构建的自定义 HTML 元素 和现代 JavaScript。Lightning Web 组件和 Aura 组件可以共存,并且 在页面上进行互操作。将 Lightning Web 组件和 Aura 组件配置为 在 Lightning App Builder 和 Experience Builder 中工作。管理员和最终用户不会 了解用于开发组件的编程模型。对他们来说,他们是 简单的闪电组件。

视觉力

Visualforce 由基于标签的标记语言组成 这为开发人员提供了一种更强大的构建应用程序和自定义方式 Salesforce 用户界面。借助 Visualforce,您可以:
  • 生成向导和其他多步骤过程。
  • 通过应用程序创建自己的自定义流控制。
  • 定义导航模式和特定于数据的规则,以实现最佳、高效 应用程序交互。

SOAP API

如果要将功能添加到 一次只处理一种类型的记录的复合应用程序,并且 不需要任何事务控制(例如设置保存点或回滚) 更改)。

Apex 是如何工作的?

所有 Apex 都完全在 Lightning 平台上按需运行。开发人员编写和保存 Apex 代码到平台,最终用户通过用户触发 Apex 代码的执行 接口。
Apex 完全编译、存储和运行 在闪电平台上

当开发人员编写 Apex 代码并将其保存到平台时,平台应用程序 服务器首先将代码编译成一组抽象的指令,这些指令可以 由 Apex 运行时解释器理解,然后将这些指令另存为 元数据。

当最终用户触发 Apex 的执行时,可能通过单击按钮或 访问 Visualforce 页面时,平台应用程序服务器会检索已编译的 来自元数据的指令,并在之前通过运行时解释器发送它们 返回结果。最终用户观察到执行时间与以下方面没有差异 标准平台请求。

在云中开发代码

Apex 编程语言保存并在云中运行,即多租户 平台。Apex 是为平台上的数据访问和数据操作量身定制的,它 使您能够将自定义业务逻辑添加到系统事件中。虽然它提供了许多好处 对于平台上的业务流程自动化,它不是通用编程 语言。
Apex 不能用于:
  • 在用户界面中呈现错误消息以外的元素
  • 更改标准功能 – Apex 只能阻止该功能 ,或添加其他功能
  • 创建临时文件
  • 生成线程

提示

所有 Apex 代码都在 Lightning 平台上运行,该平台是所有人使用的共享资源 其他组织。为了保证一致的性能和可伸缩性, Apex 的执行受调控器限制的约束,这些限制确保没有单个 Apex 执行 影响 Salesforce 的整体服务。这意味着所有 Apex 代码都受到以下限制 它可以在一个操作中执行的操作数(例如 DML 或 SOQL) 过程。

所有 Apex 请求都返回一个包含 1 到 50,000 条记录的集合。你 不能假定您的代码一次只适用于一条记录。因此,你 必须实现考虑批量处理的编程模式。如果你 不要,您可能会遇到调速器限制。

什么是 Apex 开发流程?

要开发 Apex,请获取一个 Developer Edition 帐户,编写并测试您的代码,然后 部署代码。
我们建议采用以程来开发 Apex:
  1. 获取 Developer Edition 帐户。
  2. 学习 更多关于 Apex.apex
  3. 写下你的 apex。
  4. 在编写 Apex 时,您还应该编写测试。
  5. (可选)将 Apex 部署到沙盒组织并执行最终单元 测试。
  6. 部署 您的 Apex 到 Salesforce 生产组织。

除了部署 Apex 之外,一旦编写和测试,您还可以 同时添加您的类和 触发器 AppExchange 应用程序包。

创建开发人员或沙盒组织

您可以在生产组织、开发人员组织或沙盒组织中运行 Apex。您可以 在开发人员组织或沙盒组织中开发 Apex,但不在生产组织中开发。
  • 生产组织 – 有实时用户访问您的 数据
  • 开发人员组织 – 使用 Developer Edition 创建的组织 帐户
  • 沙盒组织 – 在生产组织上创建的组织,它是 生产组织的副本
 

注意

Apex 触发器在 Salesforce 试用版中可用。但是,它们是 转换为任何其他版本时禁用。如果您新注册的组织包括 Apex,使用其中一种部署方法将代码部署到您的组织。

您无法在 Salesforce 中开发 Apex 生产组织。在开发过程中访问系统的实时用户可以 破坏数据稳定性或损坏应用程序。相反,做你所有的 在沙盒或 Developer Edition 组织中进行开发工作。

如果您还不是开发者社区的成员,请转到 https://developer.salesforce.com/signup 和 按照说明注册 Developer Edition 帐户。开发人员 通过 Edition 帐户,您可以访问免费的 Developer Edition 组织。即使你 已拥有 Professional、Enterprise、Unlimited 或 Performance Edition 组织,以及 用于创建 Apex 的沙盒,我们强烈建议您利用 开发人员社区中提供的资源。

 

注意

您无法使用 Salesforce 用户界面在 Salesforce 生产组织。

要创建沙盒组织,请执行以下操作:

  1. 在“设置”中,在“快速”中输入沙盒 查找框,然后选择沙盒
  2. 单击新建沙盒
  3. 输入沙盒的名称(不超过 10 个字符)和描述。

    我们建议您选择一个符合以下条件的名称:

    • 反映此沙盒的用途,例如 QA。
    • 只有几个字符,因为 Salesforce 将沙盒名称附加到 沙盒环境中用户记录的用户名。字符较少的名称使 沙盒登录更易于键入。
  4. 选择所需的沙盒类型。

    如果您没有看到沙盒选项或需要许可证以获取更多许可证,请联系 Salesforce 为您的组织订购沙盒。

    如果您减少了购买的沙盒数量,则需要匹配该数量 的沙盒数量为购买的数量。例如,如果有两个 Full 沙盒但只购买了一个,则无法创建完整沙盒。相反,将 将完整沙盒更改为较小的沙盒,例如 Developer Pro 或 Developer 沙盒,具体取决于 您有可用的类型。

  5. 选择要包含在“部分副本”或“完整”沙盒中的数据。
    • 对于“部分复制”沙盒,单击“下一步”,然后选择 您创建的模板,用于指定沙盒的数据。如果您尚未创建 模板,请参阅创建或编辑沙盒模板。
    • 对于“完整沙盒”,单击“下一步”,然后确定数据量 包括。
      • 要为完整沙盒包含基于模板的数据,请选择现有沙盒 模板。有关更多信息,请参阅创建或编辑沙盒模板
      • 要将所有数据包含在完整沙盒中,请选择是否字段以及字段大小 跟踪要包含的历史数据,以及是否复制 Chatter 数据。Chatter 数据 包括源、消息和主题,并用于影响 您的沙盒副本。减少复制的数据量可以显著加快速度 沙盒复制时间。
  6. 若要在每次创建和刷新此沙盒后运行脚本,请指定 Apex 类 您之前从 SandboxPostCopy 接口创建。
  7. 对于“沙盒访问”,选择“用户组”以选择公共用户 包含需要访问沙盒的用户的组,或选择“全部” 活跃用户
  8. 单击创建
     

    学习 Apex

    拥有开发者帐户后,有许多资源可供您使用 了解 Apex
    Apex Trailhead 内容
    初级和中级程序员
    多个 Trailhead 模块提供了有关学习 Apex 的教程。使用这些模块 了解 Apex 的基础知识以及如何在 Lightning 上使用它 平台。使用 Apex 通过触发器、单元测试、 异步 Apex、REST Web 服务和 Visualforce 控制器。
    快速入门:Apex
    Apex 基础知识 &数据库
    Apex 触发器
    Apex 集成 服务业
    Apex 测试
    异步 Apex
    Salesforce 开发人员 Apex 页面
    初级和高级程序员
    Salesforce Developers 上的 Apex 页面包含指向多个 资源,包括有关 Apex 编程语言的文章。这些 资源提供了对 Apex 的快速介绍,并包括 Apex开发。
    Lightning 平台代码示例和 SDK
    初级和高级程序员
    开源代码示例和 SDK、参考代码和最佳实践可以是 在代码示例和 软件开发工具包。一个简明、有意义的 Apex 代码示例库,用于 遵循最佳实践的常见用例可以在 Apex-recipes 中找到。
    开发生命周期:Lightning平台上的企业开发
    架构师和高级程序员
    应用程序生命周期和开发 Trailhead 上的模型模块可帮助您了解如何使用该应用程序 闪电平台上的生命周期和开发模型。
    培训课程
    Salesforce Trailhead Academy 还提供培训课程。发展和验证您的 具有 Salesforce 凭据的技能。
    在本书中 (Apex 开发人员指南)
    初级程序员可以查看以下内容:
    • 介绍 Apex,并在 特定:
      • 文档 约定
      • 核心概念
      • 快速上手 教程
    • 类、对象和接口
    • 测试 Apex
    • 执行调控器和限制
    此外,高级程序员可以查看:
    • 触发器和批量请求最佳实践
    • 高级 Apex 编程 例
    • 了解 Apex Describe 信息
    • 异步执行(@future注释)
    • Batch Apex 和 Apex 调度程序

    使用开发环境编写 Apex

    有几种开发环境可用于开发 Apex 代码。开发商 控制台和 Visual Studio Code 的 Salesforce 扩展允许您编写、测试和 调试您的 Apex 代码。用户界面中的代码编辑器仅允许编写代码和 不支持调试。

    开发者控制台

    Developer Console 是一个集成开发环境,其中包含 可用于在 Salesforce 中创建、调试和测试应用程序的工具 组织。

    Developer Console 支持以下任务:
    • 编写代码 – 您可以使用源代码编辑器添加代码。另外,你 可以浏览组织中的包。
    • 编译代码 – 保存触发器或类时,代码为 自动编译。任何编译错误都会被报告。
    • 调试 – 您可以查看调试日志并设置有助于 调试。
    • 测试 – 可以执行特定测试类或所有测试的测试 ,您可以查看测试结果。此外,您可以检查 代码覆盖率。
    • 检查性能 – 您可以检查调试日志以查找性能 瓶颈。
    • SOQL 查询 – 您可以查询组织中的数据并查看 使用查询编辑器的结果。
    • 颜色编码和自动完成 – 源代码编辑器使用颜色 方案,使代码元素更容易阅读,并提供自动完成功能 用于类和方法名称。

    适用于 Visual Studio Code 的 Salesforce 扩展

    适用于 Visual Studio Code 的 Salesforce 扩展包包括用于在 Salesforce 平台上以轻量级、 可扩展的 VS Code 编辑器。这些工具提供了用于开发的功能 orgs(临时组织、沙盒和 DE 组织)、Apex、Aura 组件和 视觉力。

    有关安装和使用的信息,请参阅 web网站。

     

    提示

    如果您想开发自己的 Apex IDE,SOAP API 包括 编译触发器和类以及执行测试方法的方法,而 元数据 API 包括用于将代码部署到生产环境的方法。为 有关更多信息,请参阅部署 Apex 和使用 SOAP API 部署 Apex。

    Salesforce 用户界面中的代码编辑器

    Salesforce 用户 接口。所有类和触发器在保存时都会被编译,任何语法 错误被标记。在代码编译完毕且没有错误之前,无法保存代码。这 Salesforce 用户界面还会对代码中的行进行编号,并使用颜色编码来 区分不同的元素,例如注释、关键字、文本字符串等。
    • 对于对象上的触发器,请从对象的管理设置中转到 触发器,单击“新建”,然后在“正文”文本框中输入代码。
    • 对于课程,请从“设置”中输入“快速查找”框,然后选择“Apex” 类。单击“新建”,然后输入你的 正文文本框中的代码。Apex Classes
     

    注意

    您无法使用 Salesforce 用户界面在 Salesforce 生产组织。

    或者,您可以使用任何文本编辑器(如记事本)来编写 Apex 代码。然后 将代码复制并粘贴到应用程序中,或使用 API 调用之一 部署它。

    编写测试

    测试是成功长期发展的关键,也是 开发过程。我们强烈建议您使用测试驱动的 开发过程,即与 代码开发。

    为了促进健壮、无错误的代码的开发,Apex 支持创建和 执行单元测试。单元测试是验证 特定代码段工作正常。单元测试方法不带任何参数, 不向数据库提交任何数据,也不发送电子邮件。此类方法在方法定义中使用注释进行标记。 单元测试方法必须在测试类中定义,即用 批注的类。@IsTest@IsTest

     

    注意

    上的注释 methods 等同于关键字。如 最佳做法,Salesforce 建议您使用 而不是 .关键字可以在 未来版本。@IsTesttestMethod@IsTesttestMethodtestMethod

    此外,在部署 Apex 或将其打包之前 AppExchange,则必须满足以下条件。

    • 单元测试必须至少覆盖 75% 的 Apex 代码,并且所有这些测试都必须 成功完成。

      请注意以下事项。

      • 将 Apex 部署到生产组织时,每个单元测试 默认情况下,将执行 Organization 命名空间。
      • 调用不计入 Apex 代码的一部分 覆盖。System.debug
      • 测试方法和测试类不计为 Apex 代码的一部分 覆盖。
      • 虽然只有 75% 的 Apex 代码必须被测试覆盖,但不要专注于 所覆盖代码的百分比。相反,请确保每次使用 涵盖您的申请案例,包括正面和负面案例, 以及批量和单条记录。这种方法可确保 75% 或更多 的代码包含在单元测试中。
    • 每个触发器都必须具有一定的测试覆盖率。
    • 所有类和触发器都必须成功编译。

    有关编写测试的详细信息,请参阅测试 Apex。

    将 Apex 部署到沙盒组织

    沙盒在单独的环境中创建 Salesforce 组织的副本。将它们用于 开发、测试和训练,而不会影响 生产组织。沙盒与您的生产组织隔离,因此您的 在沙盒中执行不会影响生产组织。

    将 Apex 从适用于 Visual Studio Code 的 Salesforce 扩展中的本地项目部署到 Salesforce 组织,请参阅 Salesforce Extensions for Visual Studio 代码。

    您还可以使用元数据 API 调用来 将 Apex 从开发人员组织部署到沙盒组织。deploy()

    一个有用的 API 调用是 。在开发中或 沙盒组织,可以对特定类运行单元测试,列表 类或命名空间。runTests()

    您还可以使用 Salesforce CLI。有关详细信息,请参阅针对任何组织进行开发。

    有关更多信息,请参阅部署 Apex。

    将 Apex 部署到 Salesforce 生产组织

    完成所有单元测试并验证 Apex 代码 正确执行,最后一步是将 Apex 部署到您的 Salesforce 生产中 组织。

    在 Visual Studio Code 编辑器中将 Apex 从本地项目部署到 Salesforce 组织,请参阅适用于 Visual Studio 的 Salesforce 扩展 代码。

    此外,您还可以通过 Salesforce 用户界面中的更改集来部署 Apex。

    有关更多信息和其他部署选项,请参阅部署 Apex 和构建和发布您的应用程序。

    将 Apex 代码添加到 AppExchange 应用程序

    您可以在为其创建的应用中包含 Apex 类或触发器 AppExchange。

    作为包的一部分包含的任何 Apex 必须至少具有 75% 的累积测试覆盖率。每个触发器还必须具有一定的测试覆盖率。当你 将您的软件包上传到 AppExchange,将运行所有测试以确保它们在没有 错误。此外,当包安装在 安装程序的组织。您可以指定在打包期间应运行哪些测试 通过用 注释它们来安装。包必须通过此测试子集 安装成功。@isTest(OnInstall=true)@isTest(OnInstall=true)

    创建自定义对象

    在此步骤中,您将创建一个名为 Book 的自定义对象,其中包含一个名为 价格。
    先决条件:

    沙盒 Professional 中的 Salesforce 帐户, Enterprise、Performance 或 Unlimited Edition 组织,或开发人员中的帐户 组织。

    有关创建沙盒组织的更多信息,请参阅 Salesforce 帮助中的“沙盒类型和模板”。要注册 免费的开发者组织,请参阅 Developer Edition 环境注册页面。

    1. 登录到您的沙盒或开发人员组织。
    2. 从自定义对象的管理设置中(如果您使用的是 Salesforce) “经典”,请单击“新建自定义对象”,或者如果您使用的是 Lightning Experience,选择“创建”|”自定义对象
    3. 输入“书籍”作为标签。
    4. 输入 Books 作为复数标签。
    5. 点击保存
      哒哒!现在,您已经创建了第一个自定义对象。现在让我们创建一个 自定义字段。
    6. “自定义字段和关系”部分中 图书详情页面,点击新建
    7. 选择“数字”作为数据类型,然后单击“下一步”。
    8. 输入字段标签的价格
    9. 在长度文本框中输入 16。
    10. 在小数位文本框中输入 2,然后单击下一步
    11. 单击“下一步”接受字段级的默认值 安全。
    12. 点击保存
    您刚刚创建了一个名为 Book 的自定义对象,并将自定义字段添加到 该自定义对象。自定义对象已经有一些标准字段,例如 Name 和 CreatedBy,并允许您添加更特定于 实现。在本教程中,Price 字段是 Book 对象的一部分,它是 由您将在下一步中编写的 Apex 类访问。

     

    添加 Apex 类

    在此步骤中,您将添加一个 Apex 类,该类包含用于更新书籍的方法 价格。此方法由将在下一个中添加的触发器调用 步。
    先决条件:
    • 沙盒中的 Salesforce 帐户 Professional、Enterprise、Performance 或 Unlimited Edition 组织,或开发人员组织中的帐户。
    • 这本书 自定义对象。
    1. 在“设置”中,在“快速查找”框中输入“Apex Classes”, 然后选择 Apex 类并单击新建
    2. 在类编辑器中,输入以下类定义:
      public class MyHelloWorld {
      
      }
      前面的代码是要向其添加一个的类定义 方法。Apex 代码通常包含在类中。此类定义为 ,其中 表示该类可供其他 Apex 类和触发器使用。查看更多 信息,请参阅类、对象和 接口。public
    3. 在类开始和结束之间添加此方法定义 括弧。
      public static void applyDiscount(Book__c[] books) {
         for (Book__c b :books){
            b.Price__c *= 0.9;
         }
      }

      此方法称为 , 它既是公共的,也是静态的。因为它是一个静态方法,所以你不需要 需要创建类的实例才能访问该方法,您可以 只需使用类的名称后跟点 (.) 和 方法。有关更多信息,请参见静态方法和实例方法。 变量和初始化代码。applyDiscount

      此方法采用一个参数,即 Book 记录列表,该参数分配给 变量 。请注意对象名称中的 。这表示它是您创建的自定义对象。标准对象 在 Salesforce 应用程序中提供的内容(例如帐户)不会以 this 结尾 后缀。books__cBook__c

      代码的下一部分包含方法定义的其余部分:

      for (Book__c b :books){
         b.Price__c *= 0.9;
      }

      请注意字段名称 后面的 。这表明它是 您创建的自定义字段。标准字段 默认情况下,Salesforce 中提供的点使用相同类型的点进行访问 符号,但没有 , for 示例,不以 .该语句采用旧值 的 ,乘以 0.9, 这意味着它的价值将打折 10%,然后存储新的 值添加到字段中。运算符是快捷方式。 写此语句的另一种方法是 。请参阅表达式运算符。__cPrice__c__cName__cBook__c.Nameb.Price__c *= 0.9;b.Price__cb.Price__c*=b.Price__c = b.Price__c * 0.9;

    4. 单击保存”以保存新类。你现在应该有 这个完整的类定义。
       
      public class MyHelloWorld {
         public static void applyDiscount(Book__c[] books) {
            for (Book__c b :books){
               b.Price__c *= 0.9;
            }
         }
      }
    现在,您有一个类,其中包含一些代码,这些代码遍历书籍列表和 更新每本书的“价格”字段。此代码是触发器调用的静态方法的一部分 您将在下一步中创建。applyDiscount

     

    添加 Apex 触发器

    在此步骤中,您将为自定义对象创建一个触发器,该对象调用您在上一步中创建的类的方法。Book__capplyDiscountMyHelloWorld
    先决条件:
    • 沙盒中的 Salesforce 帐户 Professional、Enterprise、Performance 或 Unlimited Edition 组织,或开发人员组织中的帐户。
    • MyHelloWorld(我的你好世界酒店) Apex类。

    触发器是在记录之前或之后执行的一段代码 从 Lightning 平台插入、更新或删除特定类型 数据库。每个触发器都使用一组上下文变量运行,这些变量提供 访问导致触发器触发的记录。所有触发器都批量运行; 也就是说,它们一次处理多条记录。

    1. 从书籍的对象管理设置中,转到“触发器”,然后单击“新建”。
    2. 在触发器编辑器中,删除默认模板代码并输入此触发器 定义:
       
      trigger HelloWorldTrigger on Book__c (before insert) {
      
         Book__c[] books = Trigger.new;
      
         MyHelloWorld.applyDiscount(books);
      }

      第一行代码定义触发器:

      trigger HelloWorldTrigger on Book__c (before insert) {

      它为触发器指定一个名称,指定其操作的对象,以及 定义导致它触发的事件。例如,此触发器是 称为 HelloWorldTrigger,它对对象进行操作,并在将新书籍插入到 数据库。Book__c

      触发器中的下一行将创建一个名为 触发名为 的上下文变量。触发上下文变量,例如在 所有触发器,并提供对导致触发器的记录的访问 火灾。在本例中,包含将要插入的所有新书。booksTrigger.newTrigger.newTrigger.new

       
      Book__c[] books = Trigger.new;

      代码中的下一行调用类中的方法。它传入了一系列新书。applyDiscountMyHelloWorld

      MyHelloWorld.applyDiscount(books);
    现在,您拥有了更新所有书籍价格所需的所有代码。 插入。然而,仍然缺少一块拼图。单元测试是一个 编写代码的重要部分,并且是必需的。在下一步中,您将看到为什么会这样 就是这样,您将能够添加一个测试类。

    添加测试类

    在此步骤中,您将添加一个具有一个测试方法的测试类。您还运行测试并 验证代码覆盖率。测试方法练习并验证触发器中的代码,以及 类。此外,它还使您能够达到触发器的 100% 代码覆盖率,并且 类。
    先决条件:
    • 沙盒中的 Salesforce 帐户 Professional、Enterprise、Performance 或 Unlimited Edition 组织,或开发人员组织中的帐户。
    • 这 HelloWorldTrigger Apex 触发器。
     

    注意

    测试是开发过程的重要组成部分。部署之前 Apex 或将其打包为 AppExchange,则必须满足以下条件。

    • 单元测试必须至少覆盖 75% 的 Apex 代码,并且所有这些测试 必须成功完成。
    • 每个触发器都必须具有一定的测试覆盖率。
    • 所有类和触发器都必须成功编译。

    请注意以下事项。

    • 将 Apex 部署到生产组织时,每个单元测试 默认情况下,将执行组织命名空间。
    • 调用不计算在内 作为 Apex 代码覆盖率的一部分。System.debug
    • 测试方法和测试类不计为 Apex 代码的一部分 覆盖。
    • 虽然只有 75% 的 Apex 代码必须被测试覆盖,但不要 重点关注所覆盖代码的百分比。相反,请确保 涵盖应用程序的每个用例,包括 阳性和阴性病例,以及批量和单条记录。 此方法可确保 75% 或更多的代码被 单元测试。
    1. 在“设置”中,在“快速”中输入 Apex 类 “查找”框,然后选择“Apex 类”和 单击“新建”。
    2. 在类编辑器中,添加此测试类定义,然后单击“保存”。
       
      @IsTest 
      private class HelloWorldTestClass {
          @IsTest
          static void validateHelloWorld() {
             Book__c b = new Book__c(Name='Behind the Cloud', Price__c=100);
             System.debug('Price before inserting new book: ' + b.Price__c);
      
             // Insert book
             insert b;
          
             // Retrieve the new book
             b = [SELECT Price__c FROM Book__c WHERE Id =:b.Id];
             System.debug('Price after trigger fired: ' + b.Price__c);
      
             // Test that the trigger correctly updated the price
             System.assertEquals(90, b.Price__c);
          }
      }

      此类是使用注释定义的。以这种方式定义的类应该只 包含测试方法以及支持这些测试方法所需的任何方法。 为测试创建单独的类的一个优点是类 使用 Don’t Count 定义 违反组织 6 MB 的 Apex 代码限制。您也可以将注释添加到单个 方法。有关更多信息,请参见@IsTest注释和执行 调速器和限制。@IsTest@IsTest@IsTest

      该方法是使用注释定义的。这 注解意味着如果对数据库进行了更改,则会滚动这些更改 执行完成后返回。您不必删除任何测试数据 在测试方法中创建。validateHelloWorld@IsTest

      注意

      上的注释 methods 等同于关键字。如 最佳做法,Salesforce 建议您使用 而不是 .关键字可以在 未来版本。@IsTesttestMethod@IsTesttestMethodtestMethod

      首先,测试方法创建一本书并将其插入数据库 暂时。该语句在调试中写入价格值 日志。System.debug

      Book__c b = new Book__c(Name='Behind the Cloud', Price__c=100);
      System.debug('Price before inserting new book: ' + b.Price__c);
      
      // Insert book
      insert b;

      插入书籍后,代码将检索新 插入的书籍,使用最初分配给书籍的 ID,当它 已插入。然后,该语句记录触发的新价格 改 性。System.debug

      // Retrieve the new book
      b = [SELECT Price__c FROM Book__c WHERE Id =:b.Id];
      System.debug('Price after trigger fired: ' + b.Price__c);

      当类运行时,它会更新字段并将其值减少 10%.以下测试验证该方法是否运行并生成了 预期 结果。MyHelloWorldPrice__capplyDiscount

      // Test that the trigger correctly updated the price
      System.assertEquals(90, b.Price__c);
    3. 若要运行此测试并查看代码覆盖率信息,请切换到“开发人员” 安慰。
    4. 在开发者控制台中,点击测试 |新运行
    5. 若要选择测试类,请单击“HelloWorldTestClass”。
    6. 若要将 HelloWorldTestClass 类中的所有方法添加到测试运行中,请单击“添加” 已选择
    7. 单击运行
      测试结果将显示在“测试”选项卡中。或者,您可以展开 “测试”选项卡中的测试类,用于查看运行了哪些方法。在本例中, 该类仅包含一个测试方法。
    8. “总体代码覆盖率”窗格显示此测试类的代码覆盖率。自 查看此测试涵盖的触发器中代码行的百分比,其中 为 100%,则双击 HelloWorldTrigger 的代码覆盖率行。因为触发器调用一个方法 来自 MyHelloWorld 类,此类 也有覆盖率(100%)。若要查看类覆盖率,请双击 MyHelloWorld
    9. 若要打开日志文件,请在“日志”选项卡中双击 日志列表。将显示执行日志,包括日志记录信息 关于触发器事件、对 applyDiscount 方法的调用以及 触发。
    到目前为止,您已经完成了使用 在开发环境中运行的测试。在现实世界中,在你 测试了您的代码并对此感到满意,您想要部署代码和任何 生产组织的必备组件。下一步将演示如何执行此操作 部署已创建的代码和自定义对象。

     

    将组件部署到生产环境

    在此步骤中,您将部署 Apex 代码和之前创建的自定义对象 使用更改集添加到您的生产组织。
    先决条件:
    • 沙盒 PerformanceUnlimited 或 Enterprise Edition 组织中的 Salesforce 帐户。
    • 这 HelloWorldTestClass Apex 测试类。
    • 沙盒与生产组织之间的部署连接,该连接 允许生产组织接收入站更改集。看 Salesforce 联机帮助中的“更改集”。
    • “创建和上传变更集”用户创建、编辑、 或上传出站更改集。

    此过程不适用于开发人员组织,因为更改集是 仅在 PerformanceUnlimitedEnterprise 或 Database.com Edition 组织。如果您拥有 Developer Edition 帐户,则可以 使用其他部署方法。有关更多信息,请参阅部署 Apex。

    1. 在“设置”中,在“快速查找”框中输入“出站变更集”,然后选择“出站 变更集
    2. 如果出现启动页面,请单击“继续”。
    3. 在“更改集”列表中,单击“新建”。
    4. 输入更改集的名称(例如 HelloWorldChangeSet)和描述(可选)。 点击保存
    5. 在“更改集组件”部分中,单击“添加”。
    6. 从组件类型下拉列表中选择 Apex Class,然后选择 MyHelloWorld 和列表中的 HelloWorldTestClass 类,然后单击添加到更改集
    7. 单击“查看/添加依赖项”以添加依赖项 组件。
    8. 选中顶部复选框以选择所有组件。单击“添加到” 更改集
    9. 在更改集页面的“更改集详细信息”部分中,单击“上传”。
    10. 选择目标组织(在本例中为生产),然后单击上传
    11. 更改集上传完成后,将其部署到生产环境中 组织。
      1. 登录到您的生产组织。
      2. 在“设置”中,在“快速查找”框中输入“入站更改集”,然后选择“入站” 更改集
      3. 如果出现启动页面,请单击“继续”。
      4. 在等待部署的更改集列表中,单击更改集的 名字。
      5. 单击 Deploy
    在本教程中,您学习了如何创建自定义对象,如何添加 Apex 触发器、类和测试类。最后,您还学习了如何测试代码,以及如何 以使用更改集上传代码和自定义对象。