执行匿名块(01 Execute Anonymous Blocks)
本单元搭建开发环境:启动 Trailhead Playground,编写并执行你的第一个匿名 Apex 代码块,然后创建项目后续要用到的自定义对象、选项卡和字段。
学习目标 — 完成本项目后,你将能够:
- 编写并执行匿名 Apex 代码块
- 创建带有方法的 Apex 类
- 实例化对象并调用方法
- 使用列表和 FOR 循环
- 使用 DML 保存记录
- 编写 SOQL 查询
- 创建 Apex 触发器
简介(Introduction)
Apex 是一种面向对象的编程语言,语法与 Java 非常相似。当声明式工具力不从心时,它让开发者能够构建复杂的业务流程、定制化的用户界面,以及与第三方系统的集成。
作为一名 Salesforce 管理员,你已经会用声明式工具做很多事情。随着你完成这个项目,你会逐渐看到如何用 Apex 代码让事情在你的组织里发生——也许你会因此受到启发,自己动手写点代码。
在这个项目中,你将通过执行匿名块(anonymous block)来快速评估 Apex 代码,还会编写一些逻辑来创建"银行账户(Bank Account)"功能,并编写一个 Apex 触发器,在每次保存 Candidate(候选人)记录时自动创建一个新的联系人(Contact)。
整个学习路径循序渐进:匿名块 → 类 → 对象 → 列表 → 循环 → DML → SOQL → 触发器。从一行 System.debug 开始,到最后写出一个完整的触发器——全程动手实践,全程在 Trailhead Playground 中完成,无需任何外部工具。
启动 Trailhead Playground(Launch Your Trailhead Playground)
你将在自己的个人 Salesforce 环境——Trailhead Playground——中完成这个动手项目。先登录 Trailhead,然后点击本页底部的 Launch,你的 Playground 会在新的浏览器标签页或窗口中打开。做项目时请保持 Playground 窗口打开;在 Playground 中完成项目步骤后,回到本页点击底部的 Verify step 验证。
Trailhead Playground 提供一个干净、隔离的编码环境,可以防止对生产组织造成意外更改,也让所有学习者拥有统一的标准设置。启动后打开开发者控制台(Developer Console)——它将成为你整个项目的 Apex 开发环境。
编写并执行匿名块(Write and Execute an Anonymous Block)
执行匿名(Execute Anonymous) 能让你立即运行 Apex 代码,无需类或应用程序——它是学习 Apex 语法、测试代码片段、做一次性数据修复的理想工具。
- 在 Trailhead Playground 中,点击设置齿轮,选择 Developer Console。
- 在开发者控制台中,点击 Debug | Open Execute Anonymous Window(调试 | 打开执行匿名窗口)。
- 在 Enter Apex Code 窗口中,输入以下代码:
string tempvar = 'Enter_your_name_here';System.debug('Hello World!');System.debug('My name is ' + tempvar); - 把 Enter_your_name_here 替换成你的名字(不要删掉两边的单引号)。
- 勾选 Open Log(打开日志),点击 Execute(执行)。执行日志会打开,显示运行代码的结果。
- 选择 Debug Only(仅调试),Details 列会显示代码中调试语句的内容。
- 检查两条 USER_DEBUG 事件——它们对应匿名块中的两条
System.debug语句,其中一条 DEBUG 消息应该包含你的名字。
System.debug() 会把内容打印到调试日志中,确认你的代码确实运行了。这是学习 Apex 最快的反馈回路——你在这个项目中写的每一段代码,都可以先在执行匿名里测试,再提交到类文件里。
创建自定义对象(Create a Custom Object)
在写更多代码之前,我们需要数据来操作。创建一个自定义对象,用于存储申请你公司职位的候选人信息(后面会用到)。
- 返回浏览器中的 Trailhead Playground。
- 点击设置齿轮,选择 Setup。
- 点击 Object Manager(对象管理器)。
- 点击 Create | Custom Object(创建 | 自定义对象)。
- 按如下定义对象:
- Label(标签):
Candidate - Plural Label(复数标签):
Candidates - Object Name(对象名):
Candidate - Record Name(记录名):
Candidate Number - Data Type(数据类型):Auto Number(自动编号)
- Display Format(显示格式):
C-{0000} - Starting Number(起始编号):
1
在"Object Creation Options(对象创建选项)"(仅在首次创建自定义对象时可用)下,勾选 Launch New Custom Tab Wizard after saving this custom object(保存后启动新建自定义选项卡向导),点击 Save。这样会带你进入"新建自定义对象选项卡"页面,接下来我们来创建选项卡。
创建自定义选项卡与自定义字段(Create a Custom Tab | Create Custom Fields)
如果选项卡向导没有自动启动也没关系:点击 Home,在 Quick Find 框中输入 Tabs,选择 Tabs,在 Custom Object Tabs 部分点击 New。为自定义对象创建选项卡的步骤:
- 如果未选中,先选择 Candidate 对象。
- 点击 Tab Style(选项卡样式),任选一张图片。
- 点击 Next、Next、Save。
接着为候选人创建名(First Name)、姓(Last Name)和邮箱(Email)三个自定义字段:
- 在 Candidate 对象中,点击 Fields & Relationships,然后点击 New。
- 选择 Text,点击 Next。字段标签输入
First Name,长度50,其余保持默认,点击 Next、Next、Save & New。 - 再定义一个 Text 字段:
Last Name,长度50,保存并新建。 - 再定义一个 Email 字段:
Email,其余保持默认,点击 Next、Next、Save。
这些字段构成了你的 Apex 代码将要操作的数据结构,也为后面的触发器做好了准备。
创建 BankAcct 和 CreateContactFromCan 类(02 Create a BankAcct and CreateContactFromCan Class)
本单元创建我们的第一批 Apex 类,以及执行真正操作(创建银行账户与联系人)的方法。
创建 Apex 类(Create Apex Classes)
创建一个名为 BankAcct 的 Apex 类,给它三个属性:balance、acctName 和 acctType,并包含一个名为 makeDeposit 的方法来设置账户余额。
- 在开发者控制台中,点击 File | New | Apex Class。
- 类名输入
BankAcct,点击 OK。 - 用以下代码替换编辑器中的内容:
public class BankAcct {
private integer balance=0;
public string acctName;
public string accttype;
public void makeDeposit (integer deposit) {
balance = balance + deposit;
}
public integer getBalance() {
return balance;
}
}
- 点击 File | Save。
再创建一个名为 CreateContactFromCan 的类和一个名为 createContact 的方法:
- 点击 File | New | Apex Class,类名输入
CreateContactFromCan,点击 OK。 - 用以下代码替换编辑器内容并保存:
public with sharing class CreateContactFromCan {
public void createContact(){
}
}
这两个类演示了根本的模式:创建实例、设置字段、用 DML 保存。类结构统一为 public class 类名 { }——这是你今后写的每个 Apex 类都会用到的结构。
实例化对象并从执行匿名中调用方法(03 Instantiate an Object and Invoke a Method from Execute Anonymous)
本单元学习如何从类创建对象实例,并调用其上的方法。
创建对象(Create an Object)
这里你基于 BankAcct 类创建一个"支票账户"对象。严格来说,这叫做实例化(instantiation):创建由类定义的对象的一个具体实例。然后调用 makeDeposit 方法,运行向账户余额加钱的代码。
- 在开发者控制台中打开执行匿名窗口(Debug | Open Execute Anonymous Window)。
- 用以下代码替换现有代码:
BankAcct chkAcct = new BankAcct(); chkAcct.accttype = 'Checking'; chkAcct.acctName = 'D.Castillo-Chk'; chkAcct.makeDeposit(150); System.debug(chkAcct.getBalance());
- 确认勾选了 Open Log,点击 Execute,执行日志打开。
- 选择 Debug Only,查看调试消息后关闭日志。
关键概念:new 关键字创建实例;类名 变量名 = new 类名(); 是实例化语法;变量.方法名() 调用实例方法;类名.方法名() 则直接调用静态方法(无需 new)。类是一张蓝图,对象是一座建筑——一个类可以创建出很多个对象。
创建列表(04 Create a List)
本单元学习如何创建和使用 Apex 列表——一种有序的、能容纳多条记录的集合。
创建并调整列表(Create and Adjust the List)
实例化一个名为 bankAccts 的列表,并把两个 BankAcct 对象添加进去。
- 打开执行匿名窗口,用以下代码替换现有代码:
BankAcct chkAcct = new BankAcct();
chkAcct.accttype = 'Checking';
chkAcct.acctName = 'D.Castillo-Chk ';
chkAcct.makeDeposit(150);
BankAcct savAcct = new BankAcct();
savAcct.accttype = 'Savings';
savAcct.acctName = 'D.Castillo–Sav';
savAcct.makeDeposit(220);
List<BankAcct> bankAccts = new List<BankAcct>();
System.debug('The BankAcct List has ' + bankAccts.size() + ' bank accounts.');
bankAccts.add(chkAcct);
bankAccts.add(savAcct);
System.debug('The BankAcct List has ' + bankAccts.size() + ' bank accounts.');
System.debug('Here is the list: ' + bankAccts);
- 确认勾选 Open Log,点击 Execute,选择 Debug Only 查看消息。
在 createContact 方法中,实例化一个 Contact 列表对象,并接受一个名为 candsFromTrigger 的 Candidate 列表作为参数。打开 CreateContactFromCan 类,替换为:
public with sharing class CreateContactFromCan {
public void createContact (List<Candidate__c> candsFromTrigger){
List<Contact> conList = new List<Contact>();
}
}
列表是 Apex 中最常用的集合类型。用 List<类型> 创建,用 .add() 追加,用下标 [index](从 0 开始)访问。Salesforce 的 DML 操作都是基于集合的——一次插入或更新一个列表的记录,而不是一条一条地来。这种批量处理既更高效(更少的 DML 语句),也是调控限制(governor limits)所要求的。
创建列表 FOR 循环(05 Create a List FOR Loop)
本单元学习 FOR 循环,用它遍历列表并对每个元素执行操作。
调整循环(Adjust the Loop)
给 bankAccts 列表添加一个列表 FOR 循环来遍历它。
- 在开发者控制台中打开执行匿名窗口,用以下代码替换现有代码(在上一步基础上追加循环部分):
// ...(前面的 chkAcct、savAcct 与 bankAccts 代码)...
for (BankAcct tempacct:bankAccts){
system.debug(tempacct.acctName + ' is a ' + tempacct.accttype +
' account with a balance of $'+ tempacct.getBalance());
}
- 确认勾选 Open Log,点击 Execute,选择 Debug Only 查看消息。
在 createContact 方法中,也添加一个列表 FOR 循环来遍历 Candidate 列表。打开 CreateContactFromCan 类,替换为:
public with sharing class CreateContactFromCan {
public void createContact (List<Candidate__c> candsFromTrigger){
List<Contact> conList = new List<Contact>();
for(Candidate__c currentCandidate:candsFromTrigger){
}
}
}
FOR-EACH 循环是最常见的模式:语法更干净(无需索引变量)、更不易出错(不会出现 off-by-one 错误)、每次迭代直接给你元素本身。循环 + 列表,就能用几行代码处理成千上万条记录。
使用 DML 将 sObject 保存到数据库(06 Use DML to Save sObjects to the Database)
本单元使用 DML 语句持久化我们的 sObject——把记录创建并保存到 Salesforce 数据库中。
创建并调整 sObject(Create and Adjust the sObjects)
创建一个名为 Recruiting 的 Account sObject,并保存到数据库。
- 打开执行匿名窗口,用以下代码替换现有代码:
Account acct = new Account();
acct.name='Recruiting';
Database.insert(acct);
System.debug('A new account named ' + acct.name + ' was added ');
- 确认勾选 Open Log,点击 Execute,选择 Debug Only 查看消息。
在 createContact 方法中,创建一个 Contact sObject,填充其属性,加入 conList,再把列表保存到数据库。替换 CreateContactFromCan 类为:
public with sharing class CreateContactFromCan {
public static void createContact (List<Candidate__c> candsFromTrigger) {
List<Contact> conList = new List<Contact>();
for(Candidate__c currentCandidate:candsFromTrigger) {
conList.add(new Contact(
FirstName = currentCandidate.First_Name__c,
LastName = currentCandidate.Last_Name__c,
Email = currentCandidate.Email__c)
);
}
Database.insert(conList);
}
}
DML(数据操作语言) 是 Apex 中把 sObject 保存到数据库的语句:insert 创建记录、update 保存修改、delete 把记录移入回收站、upsert 按 ID 或外部键智能地插入或更新、undelete 从回收站恢复。关键最佳实践:始终对列表做批量 DML,而不是对单条记录——一次插入 100 条记录只需 1 条 DML 语句,而非 100 条。
创建 SOQL 向 Apex 返回数据(07 Create SOQL to Return Data to Apex)
本单元编写 SOQL 查询,从 Salesforce 对象中检索数据并在 Apex 代码中使用。
创建查询(Create a Query)
创建一条 SOQL 查询,检索你刚创建的 Recruiting Account 记录。
- 在开发者控制台中,点击 File | Open Resource。
- 选择 Account.obj,点击 Open。
- 勾选 Id 和 Name(用 CTRL 或 CMD 多选字段)。
- 点击 Query(如果查询编辑器显示了构建说明,再点一次 Query)。
- 在查询末尾输入
WHERE Name = 'Recruiting'。 - 确认 SOQL 查询为:
SELECT Id, Name FROM Account WHERE Name = 'Recruiting'。 - 点击 Execute 执行查询并显示结果。
要把新建的 Contact 与 Recruiting Account 关联起来,需要把这条 SOQL 查询加到 createContact 方法中。替换 CreateContactFromCan 类为:
public with sharing class CreateContactFromCan {
public static void createContact (List<Candidate__c> candsFromTrigger) {
List<Account> candAccts = [SELECT Id, Name FROM Account WHERE Name = 'Recruiting'];
List<Contact> conList = new List<Contact>();
for(Candidate__c currentCandidate:candsFromTrigger) {
conList.add(new Contact(
AccountId = candAccts[0].Id,
FirstName = currentCandidate.First_Name__c,
LastName = currentCandidate.Last_Name__c,
Email = currentCandidate.Email__c)
);
}
Database.insert(conList);
}
}
SOQL(Salesforce 对象查询语言) 语法类似 SQL:SELECT 字段 FROM 对象 WHERE 条件。方括号 [ ] 把 SOQL 直接嵌入 Apex 代码,结果总是一个列表,可直接交给 FOR 循环处理。注意:这里假设存在名为 Recruiting 的 Account——如果不存在,代码会抛出异常,这是添加异常处理的好地方。
创建触发器(08 Create a Trigger)
本单元创建 Apex 触发器——当记录发生变化时自动执行的代码。
添加触发器(Add the Trigger)
由于触发器中的代码受 Apex 事务约束,因而要受调控限制(governor limits)约束。为减少调控限制异常,Salesforce 的最佳实践是避免在触发器中实例化对象,而是从触发器调用"触发器处理器(trigger handler)",在处理器中实例化对象——并使用 static 关键字调用处理器中的方法,从而避免把类实例化成对象。
创建 CreateContact 触发器来调用 createContact 方法:
- 在开发者控制台中,点击 File | New | Apex Trigger。
- Name 输入
CreateContact。 - sObject 选择 Candidate__c。
- 点击 Submit。
- 用以下代码替换现有代码:
trigger CreateContact on Candidate__c (after insert){
CreateContactFromCan.createContact(Trigger.new);
}
- 保存触发器。
创建一个新候选人测试触发器:
- 从 App Launcher 找到并打开 Candidates。
- 点击 New,创建候选人记录:First Name
Gina、Last NameSimmons、Emailgsimmons@test.com,点击 Save。 - 再从 App Launcher 找到并打开 Contacts,选择 All Contacts 列表视图,确认一个名为 Gina Simmons 的联系人被创建了。
触发器让 Apex 变得真正强大——代码在数据变化时自动运行。Trigger.new 提供正在处理的记录列表;在 before 触发器中修改字段无需显式 DML,修改会随触发操作自动保存。模式始终是:遍历 Trigger.new → 检查条件 → 修改记录。
总结(Summary)
恭喜!你写下了第一段 Apex 代码,并用开发者控制台评估了代码片段。你已通过动手实践构建起完整的 Apex 开发工具包:
- 执行匿名(Execute Anonymous)——即时测试和运行代码
- 自定义对象与字段——为代码准备数据
- Apex 类——组织良好的、可复用的代码容器
- 对象实例化——从类创建实例
- 列表——用于批量处理的有序集合
- FOR 循环——遍历每条记录
- DML——以编程方式插入、更新、删除记录
- SOQL——把数据查询回代码中
- 触发器——记录变化时自动执行
你已从 System.debug('Hello World') 一路走到构建一个完整的数据驱动应用——这是真正的 Apex 开发。你不再只是一个"知道 Apex 存在"的管理员,而是一个能写出创建、查询、更新并自动化数据的 Apex 代码的管理员。接下来,你可以进一步探索 Apex 测试、高级 SOQL 和集成模式。想了解更多,可以查看 Apex Basics for Admins 模块。





















