Lesson 5 of 5 18 min read
Apex and SOQL basics
Extend Salesforce with code. Query data with SOQL, write a simple Apex trigger, respect governor limits and write a test.
In this lesson you will
- Write SOQL queries to read Salesforce data
- Write a bulk-safe Apex trigger
- Explain governor limits and why Apex must be tested
When to write code
Choose clicks before code: configuration and Flow are faster to build and easier to maintain. Use Apex when you need complex logic, large data volumes, integrations or behaviour that Flow cannot express.
Apex is Salesforce's programming language. It looks like Java, is strongly typed, and runs on Salesforce's servers inside your org.
SOQL: querying data
SOQL (Salesforce Object Query Language) reads records. It looks like SQL SELECT, but always queries one object (with related fields) and has no SELECT *.
List<Account> accounts = [
SELECT Id, Name, Industry
FROM Account
WHERE Industry = 'Education'
ORDER BY Name
LIMIT 10
];
for (Account acc : accounts) {
System.debug(acc.Name);
}You can traverse relationships, for example SELECT Name, Account.Name FROM Contact, and run SOQL in the Developer Console query editor to try queries.
Your first trigger
A trigger runs Apex before or after records are inserted, updated or deleted. Triggers always receive records in batches of up to 200, available in Trigger.new.
trigger LeadTrigger on Lead (before insert) {
for (Lead l : Trigger.new) {
if (l.LeadSource == null) {
l.LeadSource = 'Web';
}
}
}Because this is a before trigger, changing fields on Trigger.new is enough; no DML statement is needed to save them.
Governor limits and bulkification
Because many customers share the same servers, Salesforce enforces governor limits on each transaction:
| Limit (synchronous transaction) | Value |
|---|---|
| SOQL queries | 100 |
| Records retrieved by SOQL | 50,000 |
| DML statements | 150 |
| CPU time | 10 seconds |
Code must therefore be bulkified: never run a query or DML statement inside a loop. Query once, collect the results in a Set or Map, and update all records in one statement.
// Bad: one query per contact, fails for 200 records
for (Contact c : Trigger.new) {
Account a = [SELECT Name FROM Account WHERE Id = :c.AccountId];
}
// Good: one query for the whole batch
Set<Id> accountIds = new Set<Id>();
for (Contact c : Trigger.new) {
accountIds.add(c.AccountId);
}
Map<Id, Account> accounts = new Map<Id, Account>(
[SELECT Id, Name FROM Account WHERE Id IN :accountIds]
);Data Loader sends to Salesforce: insert 200 contacts. Salesforce sends to Trigger: Trigger.new (200 records). Trigger sends to Database: one SOQL query for all their accounts. Database replies to Trigger: the accounts, kept in one Map. Trigger replies to Salesforce: done, well within the limits
Tests are required
Apex is written in a sandbox or Developer Edition org, never directly in production. Before you can deploy it, at least 75% of your Apex code must be covered by tests, and every trigger needs some coverage. Tests create their own data and check results with assertions:
@isTest
private class LeadTriggerTest {
@isTest
static void setsDefaultLeadSource() {
Lead l = new Lead(LastName = 'Menon', Company = 'DevCrest');
insert l;
Lead saved = [SELECT LeadSource FROM Lead WHERE Id = :l.Id];
Assert.areEqual('Web', saved.LeadSource);
}
}Hands-on exercise
In your Developer Edition org, open the Developer Console and run a SOQL query that lists your five most recently created contacts with their account names. Then create the LeadTrigger and LeadTriggerTest above, run the test from the Test menu, and check the code coverage. Finally, add a second test that inserts 200 leads in one statement to prove the trigger is bulk-safe.
Knowledge check
3 questions • 70% to pass • Practice only, no certificate
Key concepts
- Use clicks first; write Apex for complex logic, volume or integrations.
- SOQL reads records from one object at a time, with related fields, and has no SELECT *.
- Triggers receive up to 200 records at once, so code must be bulkified.
- Governor limits cap queries, DML and CPU time; deploying Apex needs 75% test coverage.
Optional next step: DevCrest Academy
Salesforce Administration & Platform Development
Ready for the full journey? The academy's Salesforce course takes you from these fundamentals to data modelling, security design, advanced Flow, Apex triggers and tests, Lightning Web Components and integrations, with a capstone CRM project and live mentoring.
- Beginner to Intermediate
- 12 weeks • 90 hours
- Online Live
- From ₹7,500 per student
Fees and batch dates are sample data pending confirmation
Or keep learning for free with Programming Fundamentals.
