Apex 快速入门
本教程将通过一个分步实战项目,带你从头构建一个完整的、可运行的 Apex 应用。你将创建一个自定义 Book 对象,编写 Apex 类和触发器来实现自动折扣逻辑,创建测试类达到 100% 代码覆盖率,并最终使用变更集将整个应用部署到生产环境。
由于 Apex 与 Java 非常相似,你会发现很多功能都很熟悉。本教程基于一个名为 Book 的自定义对象,该对象通过触发器来更新价格。
前提条件:需要一个 Developer Edition 或 Sandbox 组织。你也可以从 AppExchange 安装 Apex Tutorials Package 来获取预构建的示例资源。
教程概览:五步构建你的第一个 Apex 应用
- 创建自定义对象 —— 创建 Book 对象并添加 Price 自定义字段
- 添加 Apex 类 —— 编写 MyHelloWorld 类,包含 applyDiscount 静态方法
- 添加 Apex 触发器 —— 创建 HelloWorldTrigger,在新书插入前自动调用折扣方法
- 添加测试类 —— 编写 HelloWorldTestClass,运行测试并达到 100% 代码覆盖率
- 部署到生产环境 —— 使用变更集(Change Set)将代码和自定义对象部署到生产组织
第一步:创建自定义对象 Book
在这一步中,你将创建一个名为 Book 的自定义对象,并为其添加一个名为 Price 的自定义字段。
前提条件:需要一个 Professional、Enterprise、Performance 或 Unlimited Edition 的 Sandbox 组织,或一个 Developer 组织账户。
创建 Book 对象(步骤 1-5)
- 登录到你的 Sandbox 或 Developer 组织
- 进入自定义对象管理设置:Salesforce Classic:点击 New Custom Object;Lightning Experience:选择 Create → Custom Object
- 在 Label 字段输入
Book - 在 Plural Label 字段输入
Books - 点击 Save
恭喜!你已经创建了第一个自定义对象。现在让我们添加 Price 自定义字段。
添加 Price 自定义字段(步骤 6-12)
- 在 Book 详情页的 Custom Fields & Relationships 区域,点击 New
- 选择 Number 作为数据类型,点击 Next
- 在 Field Label 输入
Price - 在 Length 文本框输入
16 - 在 Decimal Places 文本框输入
2,点击 Next - 点击 Next 接受字段级安全的默认值
- 点击 Save
你已经创建了 Book 自定义对象并添加了 Price 自定义字段。自定义对象已经有一些标准字段(如 Name 和 CreatedBy),你可以根据需要添加更多业务特定字段。在本教程中,你接下来编写的 Apex 类将访问这个 Price 字段。
第二步:添加 Apex 类
在这一步中,你将添加一个 Apex 类,其中包含一个用于更新图书价格的方法。该方法将在下一步中由触发器调用。
前提条件:已创建 Book 自定义对象。
创建 MyHelloWorld 类
- 在 Setup 的 Quick Find 框中输入
Apex Classes,选择 Apex Classes 并点击 New - 在类编辑器中,输入以下类定义:
public class MyHelloWorld {
}
该类被定义为 public,这意味着该类对其他 Apex 类和触发器可见。
- 在类的大括号之间添加
applyDiscount方法:
public static void applyDiscount(Book__c[] books) {
for (Book__c b : books) {
b.Price__c *= 0.9;
}
}
理解 applyDiscount 方法
让我们逐行分析这段代码:
public static void applyDiscount(Book__c[] books)—— 该方法声明为 public 和 static。因为是静态方法,你不需要创建类的实例就能访问它——可以使用MyHelloWorld.applyDiscount()直接调用。参数Book__c[]是一个 Book 自定义对象数组。注意__c后缀表示这是一个自定义对象(Custom Object)。标准对象(如 Account)没有此后缀。for (Book__c b : books)—— 循环遍历所有传入的 Book 记录。由于触发器是批量运行的,此循环确保每条记录都得到处理。b.Price__c *= 0.9;—— 将 Price 字段的值乘以 0.9,即应用 10% 的折扣。注意__c后缀同样表示这是一个自定义字段(Custom Field)。这是复合赋值运算符的简写形式,等效于b.Price__c = b.Price__c * 0.9;。标准字段(如 Name)通过点符号直接访问,不需要__c后缀。
- 点击 Save 保存新类
现在你拥有了一个完整的类,它遍历一组图书并为每本书的 Price 字段应用 10% 的折扣。
第三步:添加 Apex 触发器
在这一步中,你将创建一个触发器,在 Book 记录插入数据库之前自动调用 MyHelloWorld 类的 applyDiscount 方法。
什么是触发器?触发器是一段在特定类型记录被插入、更新或删除之前(before)或之后(after)执行的 Apex 代码。每个触发器都有一组上下文变量(如 Trigger.New),用于访问导致触发器触发的记录。所有触发器都是批量运行的——它们一次处理多条记录。
创建 HelloWorldTrigger
- 从 Book 的对象管理设置中,进入 Triggers,然后点击 New
- 在触发器编辑器中,删除默认模板代码,输入以下触发器定义:
trigger HelloWorldTrigger on Book__c (before insert) {
Book__c[] books = Trigger.New;
MyHelloWorld.applyDiscount(books);
}
触发器代码逐行解析
第 1 行 —— 触发器声明:
trigger HelloWorldTrigger on Book__c (before insert) {
HelloWorldTrigger—— 触发器的名称on Book__c—— 指定触发器操作的对象(Book 自定义对象)(before insert)—— 定义触发事件:在新记录插入数据库之前触发
第 2 行 —— 访问触发器上下文变量:
Book__c[] books = Trigger.New;
Trigger.New—— 一个隐式定义的上下文变量,包含所有即将被插入的新记录Book__c[] books—— 声明一个强类型的 Book 记录列表来保存这些新记录
第 3 行 —— 调用业务逻辑:
MyHelloWorld.applyDiscount(books);
- 调用 MyHelloWorld 类的静态方法 applyDiscount
- 将新 Book 记录数组作为参数传入
现在,所有插入的 Book 记录都会自动获得 10% 的价格折扣!但还有最后一块拼图——单元测试。接下来你将为这段代码添加测试。
第四步:添加测试类
在这一步中,你将添加一个包含测试方法的测试类,运行测试并验证代码覆盖率。测试方法会执行并验证触发器和类中的代码,帮助你达到 100% 的代码覆盖率。
重要提示:在部署 Apex 或将 Apex 打包到 AppExchange 之前,必须满足以下条件:单元测试必须覆盖至少 75% 的 Apex 代码;每个触发器都必须有测试覆盖率;所有类和触发器必须成功编译。
创建 HelloWorldTestClass
- 在 Setup 的 Quick Find 框中输入
Apex Classes,选择 Apex Classes 并点击 New - 在类编辑器中,输入以下测试类定义:
@isTest
private class HelloWorldTestClass {
@isTest
static void testHelloWorld() {
Book__c b = new Book__c(Price__c = 100);
insert b;
// 获取更新后的图书
b = [SELECT Price__c FROM Book__c WHERE Id = :b.Id];
// 验证 10% 折扣已应用
System.assertEquals(90, b.Price__c);
}
}
- 点击 Save
关于注解的重要说明:
@isTest类注解 —— 使用此注解定义的类只应包含测试方法。一个好处是:带有 @isTest 的类不计入组织 6 MB Apex 代码的限制@isTest方法注解 —— 表示方法为测试方法,对数据库的任何更改在测试完成后都会自动回滚,你不需要手动删除任何测试数据- Salesforce 建议使用
@isTest而非testMethod关键字(后者可能在未来的版本中被弃用)
理解测试方法的执行流程
- 创建测试数据:
Book__c b = new Book__c(Price__c = 100);—— 创建一本价格为 100 的 Book 记录,然后insert b;将其插入数据库 - 触发器自动触发:插入操作触发 HelloWorldTrigger(before insert),该触发器调用 MyHelloWorld.applyDiscount(),将价格乘以 0.9,价格变为 90
- 检索更新后的记录:使用 SOQL 查询
[SELECT Price__c FROM Book__c WHERE Id = :b.Id]重新获取刚刚插入的 Book 记录 - 断言验证结果:
System.assertEquals(90, b.Price__c);—— 验证 Price__c 等于 90,确认 10% 折扣已正确应用。如果实际值与期望值不匹配,测试将失败
运行测试与查看代码覆盖率
- 切换到 Developer Console
- 点击 Test → New Run
- 选择 HelloWorldTestClass
- 点击 Add Selected 将类中的所有方法添加到测试运行中
- 点击 Run
- 在 Tests 选项卡中查看测试结果——你可以展开测试类来查看哪些方法已运行
- Overall Code Coverage 窗格显示代码覆盖率:双击 HelloWorldTrigger 查看 100% 覆盖率;双击 MyHelloWorld 同样查看 100% 覆盖率(因为触发器调用了该类的方法)
- 在 Logs 选项卡中双击最近的日志行,查看执行日志——包括触发器事件、方法调用以及触发前后的价格信息
第五步:部署组件到生产环境
在最后一步中,你将使用变更集(Change Set)将之前创建的 Apex 代码和自定义对象部署到生产组织。
前提条件:
- 一个 Performance、Unlimited 或 Enterprise Edition 的 Sandbox 组织
- Sandbox 与生产组织之间已建立允许入站变更集的部署连接
- 拥有"创建和上传变更集"的用户权限
注意:变更集仅适用于 Performance、Unlimited、Enterprise 或 Database.com Edition 组织。如果你使用 Developer Edition 账户,可以使用其他部署方法(如 VS Code 扩展、Metadata API 或 Salesforce CLI)。
创建和上传出站变更集(步骤 1-11)
- 在 Setup 的 Quick Find 框中输入
Change Sets,选择 Outbound Change Sets - 如果出现启动页面,点击 Continue
- 在变更集列表中,点击 New
- 输入变更集名称(例如
BookApp)和可选描述,点击 Save - 在 Change Set Components 区域,点击 Add
- 从组件类型下拉列表中选择 Apex Class,选择 MyHelloWorld 和 HelloWorldTestClass,点击 Add to Change Set
- 点击 View/Add Dependencies 添加依赖组件
- 选中顶部复选框选择所有组件,点击 Add To Change Set
- 在变更集详情区域,点击 Upload
- 选择目标组织(生产环境),点击 Upload
- 上传完成后,在生产组织中进行部署
在生产组织中部署入站变更集
- 登录到你的生产组织
- 在 Setup 的 Quick Find 框中输入
Change Sets,选择 Inbound Change Sets - 如果出现启动页面,点击 Continue
- 在等待部署的变更集列表中,点击你的变更集名称
- 点击 Deploy
部署完成后:
- Apex 代码(MyHelloWorld 类和 HelloWorldTrigger)已在生产环境中上线运行
- Book 自定义对象和 Price 字段已作为依赖组件随同部署
- HelloWorldTestClass 在部署过程中验证了代码的正确性
教程总结
在本快速入门教程中,你完整地体验了 Apex 开发的全生命周期:
- 创建自定义对象:创建了 Book 对象和 Price 自定义字段,掌握了在 Setup 中导航和创建字段的方法
- 编写 Apex 类:编写了 public 类 MyHelloWorld,包含静态方法 applyDiscount,学习了自定义对象(__c)和自定义字段(__c)的命名约定以及批量处理模式
- 编写 Apex 触发器:创建了在 Book__c 上 before insert 时触发的 HelloWorldTrigger,使用了 Trigger.New 上下文变量,学会了从触发器中调用类方法
- 编写和运行测试类:使用 @isTest 注解创建了 HelloWorldTestClass,编写了创建测试数据、执行代码、断言结果的完整测试流程,达到了 100% 的代码覆盖率
- 部署到生产环境:使用变更集完成了出站/入站部署流程,包括添加组件和依赖项
这个 Hello World 示例为你后续深入学习 Apex 开发奠定了实践基础——你可以在 Apex 开发者指南的后续章节中探索更复杂的编程模式。
感谢完成本教程。如需更详细的信息,请参阅 Apex 开发者指南后续章节。