Salesforce Apex-handleiding voor beginners

⚡ Slimme samenvatting

Apex-programmering biedt Salesforce-ontwikkelaars een objectgeoriënteerde, sterk getypeerde taal voor het toevoegen van aangepaste bedrijfslogica aan het CRM. Het vormt de basis voor klassen, triggers en batchtaken, terwijl governor-limieten de stabiliteit van het gedeelde multi-tenantplatform waarborgen.

  • 🧱 Foundation: Apex is een hoofdletterongevoelige taal met Java-achtige syntaxis die native draait op het Salesforce Lightning Platform.
  • 🗃️ Toegang tot data: Met SOQL-query's en DML-instructies kunt u met uw code sObject-records rechtstreeks in de Salesforce-database lezen en schrijven.
  • Implementatie: Klassen, eigenschappen en triggers koppelen aangepaste logica aan het invoegen, bijwerken, verwijderen en andere systeemgebeurtenissen van records.
  • ???? Schaal: Batch Apex en andere asynchrone opties verwerken miljoenen records in batches zonder de platformlimieten te overschrijden.
  • 🚦 Gouverneur Grenzen: Limieten per transactie, zoals 100 synchrone SOQL-query's en 150 DML-instructies, beschermen gedeelde resources.
  • Kwaliteit: Unit tests moeten minstens 75 procent van de Apex-code dekken voordat de applicatie in productie wordt genomen.

Overzicht van APEX Salesforce-programmering

Wat is Apex in Salesforce?

Top Apex is een objectgeoriënteerde en sterk getypeerde programmeertaal, ontwikkeld door Salesforce voor het bouwen van Software as a Service (SaaS) en Customer Relationship Management (CRM)-applicaties. Apex helpt ontwikkelaars bij het creëren van SaaS-applicaties van derden en het toevoegen van bedrijfslogica aan systeemgebeurtenissen door middel van back-end databaseondersteuning en client-serverinterfaces.

Apex helpt ontwikkelaars om bedrijfslogica toe te voegen aan systeemgebeurtenissen zoals muisklikken, updates van gerelateerde records en Visualforce-pagina's. Apex heeft een syntaxis die vergelijkbaar is met... Java. Registreer voor Salesforce om te leren hoe het CRM-systeem werkt.

Kenmerken van Apex-programmeertaal

Dit zijn de belangrijke kenmerken van Salesforce Apex:

  • Apex is een taal die geen onderscheid maakt tussen hoofdletters en kleine letters.
  • Met Apex kunt u DML-bewerkingen zoals INSERT, UPDATE, UPSERT en DELETE uitvoeren op sObject-records.
  • In Apex kunt u sObject-records opvragen met behulp van SOQL (Salesforce Object Query Language) en SOSL (Salesforce Object Search Language).
  • Hiermee kunt u een hoofdstuk toets en voer het uit om te verifiëren code dekking en de efficiëntie van de code in Apex.
  • Apex wordt uitgevoerd in een omgeving met meerdere tenants, en Salesforce Salesforce heeft governor-limieten ingesteld die voorkomen dat een gebruiker de gedeelde resources monopoliseert. Code die een Salesforce governor-limiet overschrijdt, mislukt en er verschijnt een foutmelding.
  • Een Salesforce-object kan als gegevenstype in Apex worden gebruikt. Bijvoorbeeld:
    Account acc = new Account();

    Account is hier een standaard Salesforce-object.

  • Apex wordt automatisch geüpgraded bij elke Salesforce-release.

Wanneer moet een ontwikkelaar voor Apex kiezen?

Apex-code moet alleen worden geschreven als een bedrijfsscenario te complex is om te implementeren met behulp van de vooraf gebouwde, gebruiksvriendelijke functionaliteit van Salesforce.

Hieronder volgen enkele scenario's waarin u Apex-code moet schrijven:

  • Om webservices te creëren die Salesforce integreren met andere applicaties.
  • Om aangepaste validatie op sObjects te implementeren.
  • Om aangepaste Apex-logica uit te voeren wanneer een DML-bewerking wordt uitgevoerd.
  • Om functionaliteit te implementeren die niet mogelijk is met bestaande declaratieve automatiseringstools zoals Flow.
  • Opzetten e-maildiensten die de inhoud, kopteksten en bijlagen van inkomende e-mails verwerken.

Als je eenmaal weet wanneer Apex de juiste keuze is, is de volgende stap begrijpen wat er met je code gebeurt nadat je deze hebt opgeslagen.

Werkstructuur van Apex

Hieronder volgt de stappenreeks voor Apex-code:

  • Actie van de ontwikkelaar: Wanneer de ontwikkelaar code opslaat op het platform, wordt alle Apex-code gecompileerd tot een set instructies die de Apex-runtime-interpreter kan begrijpen. Deze instructies worden vervolgens als metadata op het platform opgeslagen.
  • Actie van de eindgebruiker: Wanneer een gebruikersgebeurtenis Apex-code uitvoert, haalt de platformserver de gecompileerde instructies uit de metadata op en voert deze door de Apex-interpreter voordat het resultaat wordt teruggestuurd.

Het onderstaande diagram laat zien hoe de acties van de ontwikkelaar en de eindgebruiker interageren met de applicatieserver van het Lightning Platform:

Werkstructuur van Apex

Apex-ontwikkelomgeving

Apex-code kan worden ontwikkeld in een sandbox-omgeving of in een Developer Edition-organisatie van Salesforce.

Het is een goede gewoonte om de code eerst in een testomgeving te ontwikkelen en deze vervolgens in de productieomgeving te implementeren, zoals hieronder wordt geïllustreerd:

Apex-ontwikkelomgeving

Apex-codeontwikkeltools: Hieronder staan ​​de drie tools die beschikbaar zijn voor het ontwikkelen van Apex-code in alle edities van Salesforce:

  • Developer Console
  • Visual Studio Code met het Salesforce Extension Pack (dit vervangt de niet meer gebruikte Force.com IDE)
  • Code editor in de gebruikersinterface van Salesforce Setup

Nu je omgeving gereed is, laten we eens kijken naar de bouwstenen van de taal zelf, te beginnen met gegevenstypen.

Gegevenstypen in Apex

Hieronder vindt u de gegevenstypen die door Apex worden ondersteund:

Primitief

Geheel getal, DoubleLong, Date, Datetime, Decimal, Time, Blob, String, ID en Boolean worden beschouwd als primitieve gegevenstypen. Alle primitieve gegevenstypen worden doorgegeven via waarde, niet via referentie.

Collecties

In Apex zijn drie soorten collecties beschikbaar:

  • Lijst: Het is een geordende verzameling van primitieve gegevenstypen, sObjects, collecties of Apex-objecten op basis van indexen.
  • Set: Een ongeordende verzameling unieke elementen die geen duplicaten bevat.
  • Kaart: Het is een verzameling unieke sleutels die gekoppeld zijn aan afzonderlijke waarden, die primitieve gegevenstypen, sObjects, verzamelingen of Apex-objecten kunnen zijn.

sObject

Dit is een speciaal gegevenstype in Salesforce. Het is vergelijkbaar met een tabel in SQL en bevat velden die vergelijkbaar zijn met kolommen in SQL.

enums

Een Enum is een abstracEen gegevenstype dat één waarde opslaat uit een eindige verzameling van gespecificeerde identificatoren.

Klassen, objecten en interfaces

Door de gebruiker gedefinieerde Apex-klassen en -interfaces kunnen ook als gegevenstypen worden gebruikt. Een object verwijst naar een instantie van elk gegevenstype dat in Apex wordt ondersteund.

Apex-syntaxis

Variabele declaratie

Omdat Apex een sterk getypeerde taal is, is het verplicht om een ​​variabele met een gegevenstype te declareren in Apex.

Bijvoorbeeld:

Contact con = new Contact();

Hier wordt de variabele con gedeclareerd met Contact als gegevenstype.

SOQL-query

SOQL staat voor Salesforce Object Query Language. SOQL wordt gebruikt om sObject-records uit de Salesforce-database op te halen. Bijvoorbeeld:

Account acc = [SELECT Id, Name FROM Account LIMIT 1];

De bovenstaande query haalt een accountrecord op uit de Salesforce-database.

Loop-verklaring

Een lus wordt gebruikt om de elementen in een lijst te doorlopen. Het aantal iteraties is gelijk aan het aantal elementen in de lijst. Bijvoorbeeld:

List<Account> listOfAccounts = [SELECT Id, Name FROM Account LIMIT 100];
// iteration over the list of accounts
for(Account acc : listOfAccounts){
	//your logic
}

In het bovenstaande codefragment is listOfAccounts een variabele van het gegevenstype List.

Verklaring inzake stroombeheersing

Een stroombesturingsinstructie is handig wanneer u bepaalde regels code wilt uitvoeren op basis van specifieke voorwaarden.

Bijvoorbeeld:

List<Account> listOfAccounts = [SELECT Id, Name FROM Account LIMIT 100];
// execute the logic if the size of the account list is greater than zero
if(listOfAccounts.size() > 0){
	//your logic
}

Bovenstaand codefragment haalt accountgegevens uit de database op en controleert de grootte van de lijst.

DML-verklaring

DML staat voor Data Manipulation Language. DML-instructies worden gebruikt om gegevens in de Salesforce-database te manipuleren. Bijvoorbeeld:

Account acc = new Account(Name = 'Test Account');
insert acc; //DML statement to create account record.

Apex Access Specificaties

Hieronder vindt u de toegangsspecificaties die door Apex worden ondersteund:

Publieke

Deze toegangsspecificatie geeft toegang tot een klasse, methode of variabele die door Apex binnen een namespace kan worden gebruikt.

Privé

Deze toegangsspecificatie geeft toegang tot een klasse, methode of variabele voor lokaal gebruik, oftewel binnen het gedeelte van de code waar deze is gedefinieerd. Alle methoden en variabelen waarvoor geen toegangsspecificatie is gedefinieerd, krijgen de standaard toegangsspecificatie 'private'.

Beschermd

Deze toegangsspecificatie geeft toegang tot een methode of variabele die gebruikt kan worden door alle interne klassen binnen de definiërende Apex-klasse.

Globaal

Deze toegangsspecificatie geeft toegang tot een klasse, methode of variabele die door Apex binnen en buiten een namespace gebruikt kan worden. Het is raadzaam om het sleutelwoord `global` alleen te gebruiken als dat echt nodig is.

Trefwoorden in Apex

Met delen

Als een klasse met dit trefwoord is gedefinieerd, worden alle deelregels die van toepassing zijn op de huidige gebruiker afgedwongen. Als dit trefwoord ontbreekt, wordt de code uitgevoerd in de systeemcontext.

Bijvoorbeeld:

public with sharing class MyApexClass{
// sharing rules enforced when code in this class executes
}

Zonder te delen

Als een klasse met dit trefwoord wordt gedefinieerd, worden de deelregels die voor de huidige gebruiker gelden niet afgedwongen.

Bijvoorbeeld:

public without sharing class MyApexClass{
// sharing rules are not enforced when code in this class executes
}

Statisch

Een variabele of methode die is gedefinieerd met het sleutelwoord `static` wordt eenmalig geïnitialiseerd en gekoppeld aan de klasse. Statische variabelen en methoden kunnen rechtstreeks worden aangeroepen met de klassenaam, zonder dat er een instantie van de klasse hoeft te worden aangemaakt.

uiteinde

Een constante of methode die is gedefinieerd met het sleutelwoord `final` kan niet worden overschreven. Bijvoorbeeld:

public class myCls {
static final Integer INT_CONST = 10;
}

Als u probeert de waarde van deze INT_CONST-variabele te overschrijven, krijgt u de uitzondering System.FinalException: Final-variabele is al geïnitialiseerd.

Retourneren

Dit trefwoord retourneert een waarde uit een methode. Bijvoorbeeld:

public String getName() {
return 'Test';
}

Null

Het definieert een null-constante en kan aan een variabele worden toegewezen. Bijvoorbeeld:

Boolean b = null;

Virtueel

Als een klasse is gedefinieerd met het sleutelwoord virtual, kan deze worden uitgebreid en overschreven.

Abstract

Als een klasse is gedefinieerd met de abstracAls het trefwoord `t` aanwezig is, moet het ten minste één methode bevatten met het trefwoord `abs`.tract, en die methode zou alleen een handtekening moeten hebben.

Bijvoorbeeld:

public abstract class MyAbstractClass {
abstract Integer myAbstractMethod1();
}

Apex-reeks

Een tekenreeks is een verzameling tekens zonder tekenlimiet. Bijvoorbeeld:

String name = 'Test';

De String-klasse in Salesforce biedt verschillende ingebouwde methoden. Hieronder volgen enkele veelgebruikte methoden:

afkorten(max.breedte)

Deze methode kort een tekenreeks in tot de opgegeven lengte en retourneert deze als de lengte van de gegeven tekenreeks langer is dan de opgegeven lengte; anders retourneert de methode de oorspronkelijke tekenreeks. Als de waarde van de variabele maxWidth kleiner is dan 4, genereert deze methode een runtimefout – System.StringException: Minimum abbreviation width is 4.

Bijvoorbeeld:

String s = 'Hello World';
String s2 = s.abbreviate(8);
System.debug('s2: ' + s2); //Hello...

hoofdletter ()

Deze methode converteert de eerste letter van een string naar hoofdletters en retourneert deze.

Bijvoorbeeld:

String s = 'hello';
String s2 = s.capitalize();
System.assertEquals('Hello', s2);

bevat(subtekenreeks)

Deze methode retourneert true als de tekenreeks die de methode aanroept de opgegeven subtekenreeks bevat.

String name1 = 'test1';
String name2 = 'test';
Boolean flag = name1.contains(name2);
System.debug('flag:: ' + flag); //true

is gelijk aan(stringOrId)

Deze methode retourneert true als de doorgegeven parameter niet null is en dezelfde binaire tekenreeks vertegenwoordigt als de tekenreeks waarmee de methode wordt aangeroepen.

Bij het vergelijken van ID-waarden is het mogelijk dat de lengtes van de ID's niet gelijk zijn. Als bijvoorbeeld een tekenreeks die een ID van 15 tekens vertegenwoordigt, wordt vergeleken met een object dat een ID van 18 tekens vertegenwoordigt, retourneert deze methode nog steeds true. Bijvoorbeeld:

String stringValue15 = '001D000000Ju1zH';
Id idValue18 = '001D000000Ju1zHIAR';
Boolean result = stringValue15.equals(idValue18);
System.debug('result: ' + result); //true

In het bovenstaande voorbeeld vergelijkt de equals-methode een object-ID van 15 tekens met een object-ID van 18 tekens. Als beide ID's dezelfde binaire reeks vertegenwoordigen, retourneert de methode true.

Gebruik deze methode om hoofdlettergevoelige vergelijkingen te maken.

escapeSingleQuotes(stringToEscape)

Deze methode voegt een escape-teken (\) toe vóór elk enkel aanhalingsteken in een tekenreeks en retourneert het resultaat. Deze methode voorkomt SOQL-injectie bij het maken van een dynamische SOQL-query. Het zorgt ervoor dat alle enkele aanhalingstekens worden behandeld als omringende tekenreeksen in plaats van databaseopdrachten.

Bijvoorbeeld:

String s = 'Hello \'Tom\'';
String escapedStr = String.escapeSingleQuotes(s);
System.debug(escapedStr); // Outputs Hello \'Tom\'

verwijder(subtekenreeks)

Deze methode verwijdert alle voorkomende instanties van de genoemde substring uit de string die de methode aanroept en retourneert de resulterende string.

Bijvoorbeeld:

String s1 = 'Salesforce and force.com';
String s2 = s1.remove('force');
System.debug('s2: ' + s2); // 'Sales and .com'

subtekenreeks(startIndex)

Deze methode retourneert een substring die begint bij het teken op startIndex en doorloopt tot het einde van de string.

Bijvoorbeeld:

String s1 = 'hamburger';
String s2 = s1.substring(3);
System.debug('s2: ' + s2); //burger

omgekeerde()

Deze methode keert alle tekens van een tekenreeks om en retourneert deze. Bijvoorbeeld:

String s = 'Hello';
String s2 = s.reverse();
System.debug('s2:::: ' + s2); // olleH

trimmen ()

Deze methode verwijdert alle spaties aan het begin en einde van een tekenreeks en retourneert de tekenreeks.

waardeVan(naarConverteren)

Deze methode retourneert de tekenreeksweergave van het doorgegeven object.

Strings, klassen en trefwoorden komen samen wanneer je logica verpakt in herbruikbare eenheden, en dat is precies waar Apex-klassen voor bedoeld zijn.

Apex-klasse

Een Apex-klasse is een blauwdruk of sjabloon waarmee objecten worden gemaakt. Een object is een instantie van een klasse.

Er zijn drie manieren om Apex-klassen in Salesforce te maken:

  • Developer Console
  • Visual Studio Code met het Salesforce-uitbreidingspakket
  • Apex-klasse detailpagina in Instellingen

In Apex kun je een buitenste klasse definiëren, ook wel een top-level klasse genoemd, en je kunt ook klassen binnen een buitenste klasse definiëren, die innerlijke klassen worden genoemd.

Het is verplicht om een ​​toegangsaanpasser zoals 'global' of 'public' te gebruiken bij de declaratie van een buitenste klasse.

Het is niet nodig om een ​​toegangsaanpasser te gebruiken bij de declaratie van innerlijke klassen.

Een Apex-klasse wordt gedefinieerd met het trefwoord `class`, gevolgd door de klassenaam.

Het sleutelwoord `extends` wordt gebruikt om een ​​bestaande klasse uit te breiden in een Apex-klasse, en het sleutelwoord `implements` wordt gebruikt om een ​​interface te implementeren in een Apex-klasse.

Salesforce Apex ondersteunt geen meervoudige overerving; een Apex-klasse kan slechts één bestaande Apex-klasse uitbreiden, maar kan wel meerdere interfaces implementeren.

Een Apex-klasse kan een door de gebruiker gedefinieerde constructor bevatten. Als er geen door de gebruiker gedefinieerde constructor beschikbaar is, wordt een standaardconstructor gebruikt. De code in een constructor wordt uitgevoerd wanneer een instantie van een klasse wordt aangemaakt.

Syntaxis van een Apex-klasse:

public class myApexClass{
// variable declaration
//constructor
	public myApexClass(){
	}
//methods declaration
}

Het nieuwe trefwoord wordt gebruikt om een ​​instantie van een Apex-klasse te creëren. Hieronder staat de syntax voor het creëren van een instantie van een Apex-klasse:

myApexClass obj = new myApexClass();

Apex-getter en setter

Een Apex-eigenschap is vergelijkbaar met een Apex-variabele. Een getter en een setter zijn noodzakelijk voor een Apex-eigenschap. Deze kunnen worden gebruikt om code uit te voeren voordat de waarde van de eigenschap wordt opgevraagd of gewijzigd. De code in de get-accessor wordt uitgevoerd wanneer een eigenschapswaarde wordt gelezen. De code in de set-accessor wordt uitgevoerd wanneer een eigenschapswaarde wordt gewijzigd. Een eigenschap met alleen een get-accessor wordt beschouwd als alleen-lezen, een eigenschap met alleen een set-accessor wordt beschouwd als alleen-schrijven en een eigenschap met zowel een get- als een set-accessor wordt beschouwd als lees-schrijfbaar. Syntaxis van een Apex-eigenschap:

public class myApexClass {
// Property declaration
	access_modifier return_type property_name {
	get {
			//code
		}
		set{
			//code
		}
	}
}

Hier is access_modifier de toegangsaanpasser van de eigenschap, return_type het gegevenstype van de eigenschap en property_name de naam van de eigenschap.

Hieronder een voorbeeld van een Apex-eigenschap met zowel get- als set-accessors:

public class myApex{
	public String name{
		get{ return name; }
		set{ name = value; }
	}
}

Hier is de eigenschapsnaam 'name', het is een openbare eigenschap en deze retourneert een String-datatype.

Het is niet verplicht om code in de get- en set-blokken te plaatsen. Deze blokken kunnen leeg gelaten worden om een ​​automatische eigenschap te definiëren. Bijvoorbeeld:

public double MyReadWriteProp{ get; set; }

Get- en set-accessors kunnen ook worden gedefinieerd met hun eigen toegangsmodifiers. Als een accessor is gedefinieerd met een modifier, overschrijft deze de toegangsmodifier van de eigenschap. Bijvoorbeeld:

public String name{private get; set;}// name is private for read and public for write.

Klassen definiëren herbruikbare logica die je expliciet aanroept. Triggers, die hierna aan bod komen, worden automatisch uitgevoerd wanneer records wijzigen.

Apex-trigger

Met Apex-triggers kunt u aangepaste Apex-code uitvoeren vóór en na een DML-bewerking.

Apex ondersteunt de volgende twee typen triggers:

Vóór de triggers: Deze triggers worden gebruikt om de waarde van een veld te valideren en bij te werken voordat de record in de database wordt opgeslagen.

Na de triggers: Deze triggers worden gebruikt om toegang te krijgen tot veldwaarden (zoals de record-ID en het veld LastModifiedDate) die door het systeem worden ingesteld nadat een record in de database is opgeslagen. Deze veldwaarden kunnen worden gebruikt om andere records te wijzigen. Records die worden geactiveerd na een trigger zijn alleen-lezen.

Het is aan te raden om bulktriggers te schrijven. Een bulktrigger kan zowel één record als meerdere records tegelijk verwerken.

Syntaxis van een Apex-trigger:

trigger TriggerName on ObjectName (trigger_events) {
	//Code_block
 }

Hier is TriggerName de naam van de trigger, ObjectName de naam van het object waarop de trigger is geschreven, en trigger_events een door komma's gescheiden lijst van gebeurtenissen.

De volgende gebeurtenissen worden ondersteund door Apex-triggers: voor invoegen, voor bijwerken, voor verwijderen, na invoegen, na bijwerken, na verwijderen, na ongedaan maken.

Statische trefwoorden kunnen niet worden gebruikt in een Apex-trigger. Alle trefwoorden die van toepassing zijn op innerlijke klassen kunnen wel worden gebruikt in een Apex-trigger.

Elke trigger heeft impliciete variabelen die de runtime-context retourneren. Deze variabelen zijn gedefinieerd in de klasse System.Trigger en worden contextvariabelen genoemd. De twee onderstaande schermafbeeldingen tonen de contextvariabelen die door Apex-triggers worden ondersteund:

Apex Trigger Context Variabelen

Apex Trigger Context Variabelen (Vervolg)

Hieronder volgen de aandachtspunten voor contextvariabelen in Apex-triggers:

  • Gebruik trigger.new en trigger.old niet in DML-bewerkingen.
  • Trigger.new kan niet worden verwijderd.
  • Trigger.new is alleen-lezen in de aftertriggers.
  • Trigger.new kan alleen in before-triggers worden gebruikt om de waarden van velden op hetzelfde object te wijzigen.

De twee onderstaande schermafbeeldingen tonen de aandachtspunten met betrekking tot specifieke acties bij verschillende triggergebeurtenissen:

Overwegingen met betrekking tot Apex-triggergebeurtenissen

Overwegingen met betrekking tot Apex-triggergebeurtenissen (vervolg)

Triggers verwerken realtime logica, maar sommige taken zijn simpelweg te groot voor één enkele transactie. Dat is waar batch Apex van pas komt.

Batchklasse in Apex

Een batchklasse in Salesforce wordt gebruikt om een ​​groot aantal records te verwerken dat de limieten van de Apex governor zou overschrijden als het op de normale manier verwerkt zou worden. Een batchklasse voert de code asynchroon uit.

Hieronder volgen de voordelen van een groepsles:

  • Een batchklasse verwerkt de gegevens in stukken, en als een stuk niet succesvol verwerkt kan worden, worden de succesvol verwerkte stukken niet teruggedraaid.
  • Elk gegevensblok in een batchklasse wordt verwerkt met een nieuwe set governor-limieten, wat ervoor zorgt dat de code binnen de governor-uitvoeringslimieten wordt uitgevoerd.

De Database.Batchable-interface moet door een Apex-klasse worden geïmplementeerd om als batchklasse te kunnen worden gebruikt. Deze interface biedt drie methoden die door de batchklasse moeten worden geïmplementeerd:

1. start()

Deze methode genereert de scope van records of objecten die door de interfacemethode execute verwerkt moeten worden. Deze methode wordt slechts één keer aangeroepen tijdens de uitvoering van de batch. De methode retourneert een Database.QueryLocator-object of een Iterable. Het aantal records dat kan worden opgehaald met een SOQL-query met behulp van een Database.QueryLocator-object is 50 miljoen, maar met een Iterable is het totale aantal records dat kan worden opgehaald slechts 50,000. Een Iterable wordt gebruikt om een ​​complexe scope te genereren voor de batchklasse.

Syntaxis van de startmethode:

global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}

2. uitvoeren()

Deze methode wordt gebruikt voor het verwerken van elk gegevensblok. De `execute`-methode wordt aangeroepen voor elk blok records. De standaard batchgrootte voor de uitvoering is 200 records. De `execute`-methode accepteert twee argumenten:

Een verwijzing naar het Database.BatchableContext-object,

Een lijst met sObjects, zoals List , of een lijst met geparameteriseerde typen. Syntaxis van de execute-methode:

global void execute(Database.BatchableContext bc, List<P> records){}

3. finish()

De finish-methode wordt eenmaal aangeroepen tijdens de uitvoering van de batchklasse. Nabewerkingen kunnen in de finish-methode worden uitgevoerd, bijvoorbeeld het verzenden van een bevestigingsmail. Deze methode wordt aangeroepen wanneer alle batches zijn verwerkt. Syntaxis van de finish-methode:

global void finish(Database.BatchableContext bc){}

Database.BatchableContext-object

Elke methode van de Database.Batchable-interface heeft een verwijzing naar een Database.BatchableContext-object.

Dit object wordt gebruikt om track de voortgang van de batchtaak.

Hieronder volgen de instantie-methoden die door BatchableContext worden aangeboden:

  • getChildJobId(): Deze methode retourneert de ID van de batchtaak die momenteel wordt verwerkt.
  • getJobId(): Deze methode retourneert de ID van de batchtaak.

Hieronder staat de syntaxis van een batchklasse:

global class MyBatchClass implements Database.Batchable<sObject> {
	global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {
// collect the batches of records or objects to be passed to execute
}
global void execute(Database.BatchableContext bc, List<P> records){
// process each batch of records
}
global void finish(Database.BatchableContext bc){
// execute any post-processing operations
}
}

Database.executeBatch-methode

De Database.executeBatch-methode wordt gebruikt om een ​​batchklasse uit te voeren.

Deze methode vereist twee parameters: een instantie van de batchklasse die verwerkt moet worden, en een optionele scope-parameter om de batchgrootte te specificeren. Indien deze niet is gespecificeerd, wordt de standaardgrootte van 200 gebruikt.

Syntaxis van Database.executeBatch:

Database.executeBatch(myBatchObject, scope)

Een batchklasse met de naam MyBatchClass uitvoeren:

MyBatchClass myBatchObject = new MyBatchClass();
Id batchId = Database.executeBatch(myBatchObject, 100);

Database.Stateful

Een batchklasse is standaard stateless. Telkens wanneer de execute-methode wordt aangeroepen, wordt een nieuwe kopie van het object ontvangen en worden alle variabelen van de klasse geïnitialiseerd.

Database.Stateful is geïmplementeerd om een ​​batchklasse stateful te maken.

Als uw batchklasse de interface implementeert Database.Stateful interface: alle instantievariabelen behouden hun waarden, maar statische variabelen worden gereset tussen transacties.

Asynchrone Apex Beyond Batch

Batch Apex is slechts één van de vele manieren om code asynchroon uit te voeren. Salesforce biedt vier asynchrone opties, en de juiste keuze hangt af van de hoeveelheid data die u verwerkt en of taken aan elkaar gekoppeld of gepland moeten worden.

  • Toekomstige methoden: Deze zijn gemarkeerd met @future en zijn het meest geschikt voor eenvoudige, eenmalige bewerkingen, zoals het aanroepen van externe webservices.
  • Apex die in de wachtrij kan worden geplaatst: Implementeert de Queueable-interface, accepteert complexe objecttypen, retourneert een taak-ID en ondersteunt het koppelen van taken aan elkaar.
  • Batch Apex: Verwerkt zeer grote hoeveelheden data in stukken, zoals hierboven beschreven.
  • Geplande piek: Implementeert de Schedulable-interface, zodat een klasse op een specifiek tijdstip wordt uitgevoerd, bijvoorbeeld een nachtelijke opschoontaak.
Type beste voor Belangrijkste capaciteit
Toekomstige methode Eenvoudige aanwijzingen Insteken en vergeten
Queueable Apex Opeenvolgende verwerking Taakketen en monitoring
Batch Apex Miljoenen records Chunked processing
Geplande Apex Terugkerende opdrachten Cron-gebaseerde timing

Welk uitvoeringsmodel u ook kiest, elke transactie wordt nog steeds gemeten aan de hand van de platformbrede governor-limieten die hieronder worden vermeld.

Limieten voor Apex-gouverneur

Apex governor-limieten zijn de limieten die door de Apex runtime-engine worden afgedwongen om ervoor te zorgen dat Apex-code en -processen die buiten controle raken, de gedeelde resources niet monopoliseren en de verwerking van andere gebruikers in de multi-tenantomgeving niet verstoren. Deze limieten worden gecontroleerd voor elke Apex-transactie. Hieronder staan ​​de governor-limieten die Salesforce voor elke Apex-transactie heeft gedefinieerd:

Beschrijving Beperken
SOQL-query's die in een synchrone transactie kunnen worden uitgevoerd 100
SOQL-query's die in een asynchrone transactie kunnen worden uitgevoerd. 200
Records die kunnen worden opgehaald door een SOQL-query 50,000
Records die kunnen worden opgehaald door Database.getQueryLocator 10,000
SOSL-query's kunnen worden uitgevoerd in een Apex-transactie. 20
Records die kunnen worden opgehaald met een SOSL-query 2,000
DML-instructies die in een Apex-transactie kunnen worden uitgevoerd 150
Records die kunnen worden verwerkt als resultaat van een DML-instructie, Approval.process of database.emptyRecycleBin 10,000
Aanroepen die in een Apex-transactie kunnen worden gedaan 100
Cumulatieve time-outlimiet voor alle aanroepen die worden uitgevoerd in een Apex-transactie. 120 seconden
Beperking van het aantal Apex-taken dat aan de wachtrij kan worden toegevoegd met System.enqueueJob. 50
Uitvoeringstermijn voor elke Apex-transactie 10 minuten
Beperking van het aantal tekens dat in een Apex-klasse kan worden gebruikt en triggers. 1 miljoen
CPU-tijdslimiet voor een synchrone transactie 10,000 milliseconden
CPU-tijdslimiet voor een asynchrone transactie 60,000 milliseconden
Totale heapgrootte 6 MB (synchroon) / 12 MB (asynchroon)

Hoe schrijf je een testklasse in Apex?

Salesforce vereist dat minstens 75 procent van je Apex-code gedekt is door unit tests voordat je deze in productie kunt nemen, en elke trigger moet een testdekking hebben. Het schrijven van testklassen is daarom een ​​essentiële Apex-vaardigheid, geen optionele extra.

Een testklasse is geannoteerd met @isTest, en elke testmethode is ook gemarkeerd met @isTest. Testmethoden slaan geen gegevens op in de database en hebben geen toegang tot de meeste bestaande organisatiegegevens, dus elke test maakt zijn eigen records aan. De methoden Test.startTest() en Test.stopTest() geven de te testen code een nieuwe set governor-limieten, en beweringen verifiëren of de logica zich zoals verwacht heeft gedragen.

Hier is een eenvoudige testklasse voor de logica achter het aanmaken van accounts:

@isTest
private class AccountHandlerTest {
    @isTest
    static void testCreateAccount() {
        Account acc = new Account(Name = 'Test Account');
        Test.startTest();
        insert acc;
        Test.stopTest();
        Account result = [SELECT Id, Name FROM Account WHERE Id = :acc.Id];
        System.assertEquals('Test Account', result.Name);
    }
}

Volg deze richtlijnen bij het schrijven van toetsen:

  • Gebruik de `@testSetup`-methode om eenmalig gedeelde testgegevens aan te maken voor alle testmethoden in de klasse.
  • Test het bulkgedrag door 200 records in te voegen, niet slechts één.
  • Behandel scenario's met positieve, negatieve en beperkte gebruikers.
  • Voeg altijd zinvolle System.assert-statements toe; code coverage zonder beweringen bewijst niets.

Apex-best practices

Beginners schrijven vaak Apex-code die werkt voor één record, maar faalt bij grootschalige bewerkingen in de praktijk. De onderstaande werkwijzen zorgen ervoor dat uw code binnen de limieten van de governor blijft en gemakkelijker te onderhouden is:

  • Alles in bulk opslaan: Schrijf logica die collecties van records verwerkt, omdat triggers tot wel 200 records in één batch kunnen ontvangen.
  • Houd SOQL en DML buiten lussen: Voer vóór de lus een query uit, verzamel de wijzigingen in een lijst en voer na de lus één DML-instructie uit.
  • Eén trigger per object: Houd triggers vrij van logica en delegeer het werk aan handlerklassen, zodat de uitvoeringsvolgorde voorspelbaar is.
  • Gebruik in combinatie met delen: Handhaaf beveiliging op recordniveau, tenzij er een gedocumenteerde reden is om deze in de systeemcontext uit te voeren.
  • Vermijd het hardcoderen van ID's: Record-ID's verschillen tussen sandbox- en productieomgevingen, dus zoek ernaar of gebruik in plaats daarvan aangepaste metadata.
  • Monitorlimieten in de code: Met de methoden van de Limits-klasse, zoals Limits.getQueries(), kunt u het resourceverbruik tijdens de uitvoering controleren.

👏 Tip: Test je code eerst met 200 records in een sandbox voordat je deze implementeert. De meeste governor-limietfouten treden pas op bij grote volumes, en het vroegtijdig opsporen ervan is veel goedkoper dan het debuggen ervan in de productieomgeving.

Veelgestelde vragen

Nee. Apex leent. Java-achtige syntaxis, maar is niet hoofdlettergevoelig, werkt alleen op het Salesforce Lightning Platform, integreert SOQL direct in de taal en is onderworpen aan limieten per transactie. Java heeft niet.

Meld je aan voor een gratis Salesforce Developer Edition-organisatie, inclusief de Developer Console, en volg praktische oefeningen op Trailhead, het officiële leerplatform van Salesforce.

Visualforce is een opmaaktaal voor het bouwen van gebruikersinterfacepagina's, terwijl Apex de servertaal is die de logica erachter levert. Visualforce-pagina's roepen vaak Apex-controllerklassen aan om gegevens op te vragen en bij te werken.

Ja. Agentforce voor ontwikkelaars, de AI-assistent van Salesforce voor Visual Studio CodeGenereert en legt Apex uit op basis van prompts in natuurlijke taal. Controleer en test door AI gegenereerde code altijd op de governor-limieten voordat u deze implementeert.

Apex-klassen die zijn gemarkeerd met de annotatie @InvocableMethod kunnen worden blootgesteld als aangepaste acties, waardoor Einstein-bots en Agentforce-agents uw bedrijfslogica kunnen aanroepen. Daarnaast kan Apex ook Einstein-prompttemplates en AI-modellen aanroepen via platform-API's.

Vat dit bericht samen met: