Výukový program Salesforce Apex pro začátečníky
⚡ Chytré shrnutí
Programování v Apexu poskytuje vývojářům Salesforce objektově orientovaný jazyk se silnými typy pro přidávání vlastní obchodní logiky do CRM. Pomáhá třídám, triggerům a dávkovým úlohám, zatímco limity regulátorů udržují stabilitu sdílené multitenantní platformy.

Co je Apex v Salesforce?
Vrchol je objektově orientovaný a silně typovaný programovací jazyk vyvinutý společností Salesforce pro tvorbu aplikací typu Software as a Service (SaaS) a Customer Relationship Management (CRM). Apex pomáhá vývojářům vytvářet SaaS aplikace třetích stran a přidávat obchodní logiku k systémovým událostem tím, že poskytuje podporu pro back-end databáze a rozhraní klient-server.
Apex pomáhá vývojářům přidávat obchodní logiku k systémovým událostem, jako jsou kliknutí na tlačítka, aktualizace souvisejících záznamů a stránky Visualforce. Apex má syntaxi podobnou Java. Zaregistrujte se do Salesforce naučit se, jak funguje CRM.
Vlastnosti programovacího jazyka Apex
Zde jsou důležité funkce Salesforce Apex:
- Apex je jazyk, který nerozlišuje velká a malá písmena.
- Pomocí Apexu můžete na záznamech sObject provádět operace DML, jako je INSERT, UPDATE, UPSERT a DELETE.
- Záznamy sObject můžete v Apexu dotazovat pomocí jazyků SOQL (Salesforce Object Query Language) a SOSL (Salesforce Object Search Language).
- Umožňuje vytvořit a jednotkový test a spusťte jej pro ověření pokrytí kódem a efektivitu kódu v Apexu.
- Apex se spouští v prostředí s více nájemci a Salesforce má definované limity regulátorů, které brání uživateli v monopolizaci sdílených zdrojů. Jakýkoli kód, který překročí limit regulátorů Salesforce, selže a zobrazí se chyba.
- Objekt Salesforce lze v Apexu použít jako datový typ. Například:
Account acc = new Account();
V tomto případě je Account standardním objektem Salesforce.
- Apex se automaticky upgraduje s každou verzí Salesforce.
Kdy by si měl vývojář zvolit Apex?
Kód Apex by měl být psán pouze v případě, že je obchodní scénář příliš složitý na to, aby jej bylo možné implementovat pomocí předpřipravené funkce typu „point-and-click“, kterou poskytuje Salesforce.
Následuje několik scénářů, ve kterých je potřeba napsat kód pro Apex:
- Chcete-li vytvořit webové služby, které integrují Salesforce s jinými aplikacemi.
- Implementace vlastního ověřování na sObjects.
- Spuštění vlastní logiky Apexu při provedení operace DML.
- Implementovat funkce, které nelze vytvořit pomocí stávajících deklarativních automatizačních nástrojů, jako je Flow.
- Zřídit e-mailové služby které zpracovávají obsah, záhlaví a přílohy příchozích e-mailů.
Jakmile zjistíte, kdy je Apex tou správnou volbou, dalším krokem je pochopit, co se s vaším kódem stane po jeho uložení.
Pracovní struktura Apexu
Následuje postup akcí pro kód Apexu:
- Akce vývojáře: Když vývojář uloží kód na platformu, veškerý kód Apexu je zkompilován do sady instrukcí, kterým běhový interpret Apexu rozumí, a tyto instrukce jsou poté uloženy jako metadata na platformě.
- Akce koncového uživatele: Když uživatelská událost spustí kód Apexu, server platformy načte zkompilované instrukce z metadat a provede je interpretem Apexu, než vrátí výsledek.
Níže uvedený diagram znázorňuje, jak akce vývojáře a koncového uživatele interagují s aplikačním serverem platformy Lightning:
Vývojové prostředí Apex
Kód Apexu lze vyvíjet buď v sandboxu, nebo v organizaci Salesforce Developer Edition.
Nejlepším postupem je vyvíjet kód v sandboxovém prostředí a poté jej nasadit do produkčního prostředí, jak je znázorněno níže:
Nástroje pro vývoj kódu Apex: Následují tři nástroje dostupné pro vývoj kódu Apex ve všech edicích Salesforce:
- Konzole pro vývojáře
- Visual Studio Code s rozšiřujícím balíčkem Salesforce (tento balíček nahrazuje vyřazené vývojové prostředí Force.com)
- Code editor v uživatelském rozhraní Salesforce Setup
Jakmile je vaše prostředí připraveno, podívejme se na stavební kameny samotného jazyka, počínaje datovými typy.
Datové typy v Apexu
Apex podporuje následující datové typy:
Primitivní
Celé číslo, Double, Long, Date, Datetime, Decimal, Time, Blob, String, ID a Boolean jsou považovány za primitivní datové typy. Všechny primitivní datové typy se předávají hodnotou, nikoli odkazem.
Kolekce
V Apexu jsou k dispozici tři typy kolekcí:
- Seznam: Jedná se o uspořádanou kolekci primitiv, sObjectů, kolekcí nebo objektů Apex založených na indexech.
- Soubor: Neuspořádaná kolekce unikátních prvků, která neobsahuje duplikáty.
- Mapa: Je to kolekce unikátních klíčů, které se mapují na jednotlivé hodnoty, což mohou být primitiva, objekty sObject, kolekce nebo objekty Apex.
sObject
Toto je speciální datový typ v Salesforce. Je to podobné jako u stolu v SQL a obsahuje pole, která jsou podobná sloupcům v SQL.
Výčty
Výčet je abstracDatový typ t, který ukládá jednu hodnotu z konečné množiny zadaných identifikátorů.
Třídy, objekty a rozhraní
Uživatelsky definované třídy a rozhraní Apexu lze také použít jako datové typy. Objekt odkazuje na instanci libovolného datového typu, který je v Apexu podporován.
Syntaxe vrcholu
Proměnná deklarace
Protože Apex je silně typovaný jazyk, je v něm povinné deklarovat proměnnou s datovým typem.
Například:
Contact con = new Contact();
Zde je proměnná con deklarována s datovým typem Contact.
SOQL dotaz
SOQL je zkratka pro Salesforce Object Query Language. SOQL se používá k načítání záznamů sObject z databáze Salesforce. Například:
Account acc = [SELECT Id, Name FROM Account LIMIT 1];
Výše uvedený dotaz načte záznam účtu z databáze Salesforce.
Příkaz smyčky
Příkaz smyčky se používá k iteraci záznamů v seznamu. Počet iterací se rovná počtu záznamů v seznamu. Například:
List<Account> listOfAccounts = [SELECT Id, Name FROM Account LIMIT 100];
// iteration over the list of accounts
for(Account acc : listOfAccounts){
//your logic
}
Ve výše uvedeném úryvku kódu je listOfAccounts proměnná datového typu List.
Prohlášení o řízení toku
Příkaz pro řízení toku je užitečný, když chcete spustit několik řádků kódu na základě určitých podmínek.
Například:
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
}
Výše uvedený úryvek kódu dotazuje záznamy účtů z databáze a kontroluje velikost seznamu.
Příkaz DML
DML je zkratka pro Data Manipulation Language (jazyk pro manipulaci s daty). Příkazy DML se používají k manipulaci s daty v databázi Salesforce. Například:
Account acc = new Account(Name = 'Test Account'); insert acc; //DML statement to create account record.
Specifikátory přístupu Apex
Následují specifikátory přístupu podporované Apexem:
Veřejné
Tento specifikátor přístupu poskytuje přístup ke třídě, metodě nebo proměnné, kterou má Apex použít v rámci jmenného prostoru.
soukromý
Tento specifikátor přístupu poskytuje přístup ke třídě, metodě nebo proměnné, která má být použita lokálně nebo v rámci části kódu, kde je definována. Všechny metody a proměnné, které nemají definovaný specifikátor přístupu, mají výchozí specifikátor přístupu private.
Chráněný
Tento specifikátor přístupu poskytuje přístup k metodě nebo proměnné, kterou mohou používat jakékoli vnitřní třídy v rámci definující třídy Apex.
Globální
Tento specifikátor přístupu poskytuje přístup ke třídě, metodě nebo proměnné, kterou má Apex použít v rámci jmenného prostoru i mimo něj. Doporučuje se nepoužívat klíčové slovo global, pokud to není nezbytné.
Klíčová slova v Apexu
Se sdílením
Pokud je třída definována s tímto klíčovým slovem, pak jsou vynucena všechna pravidla sdílení, která platí pro aktuálního uživatele. Pokud toto klíčové slovo chybí, kód se provede v systémovém kontextu.
Například:
public with sharing class MyApexClass{
// sharing rules enforced when code in this class executes
}
Bez sdílení
Pokud je třída definována tímto klíčovým slovem, pak se pravidla sdílení, která platí pro aktuálního uživatele, nevynucují.
Například:
public without sharing class MyApexClass{
// sharing rules are not enforced when code in this class executes
}
statický
Proměnná nebo metoda definovaná klíčovým slovem static je inicializována jednou a asociována s třídou. Statické proměnné a metody lze volat přímo podle názvu třídy, aniž by se vytvářela instance třídy.
Poslední
Konstantu nebo metodu definovanou klíčovým slovem final nelze přepsat. Například:
public class myCls {
static final Integer INT_CONST = 10;
}
Pokud se pokusíte přepsat hodnotu této proměnné INT_CONST, dostanete výjimku – System.FinalException: Final variable has already been initialized.
Zpět
Toto klíčové slovo vrací hodnotu z metody. Například:
public String getName() {
return 'Test';
}
Null
Definuje nulovou konstantu a lze ji přiřadit proměnné. Například:
Boolean b = null;
Virtuální
Pokud je třída definována klíčovým slovem virtual, lze ji rozšířit a přepsat.
Abstract
Pokud je třída definována pomocí abstracklíčové slovo t, musí obsahovat alespoň jednu metodu s klíčovým slovem abstract a tato metoda by měla mít pouze podpis.
Například:
public abstract class MyAbstractClass {
abstract Integer myAbstractMethod1();
}
Apex String
Řetězec je sada znaků bez omezení počtu znaků. Například:
String name = 'Test';
Třída String v Salesforce nabízí několik vestavěných metod. Následuje několik často používaných metod:
zkrátit (maxWidth)
Tato metoda zkrátí řetězec na zadanou délku a vrátí ji, pokud je délka daného řetězce delší než zadaná délka; v opačném případě vrátí původní řetězec. Pokud je hodnota proměnné maxWidth menší než 4, tato metoda vyvolá běhovou výjimku – System.StringException: Minimální šířka zkratky je 4.
Například:
String s = 'Hello World';
String s2 = s.abbreviate(8);
System.debug('s2: ' + s2); //Hello...
velká písmena()
Tato metoda převede první písmeno řetězce na velikost písmen a vrátí je.
Například:
String s = 'hello';
String s2 = s.capitalize();
System.assertEquals('Hello', s2);
obsahuje (podřetězec)
Tato metoda vrací hodnotu true, pokud řetězec volající metodu obsahuje zadaný podřetězec.
String name1 = 'test1';
String name2 = 'test';
Boolean flag = name1.contains(name2);
System.debug('flag:: ' + flag); //true
rovná se(stringOrId)
Tato metoda vrací hodnotu true, pokud předaný parametr není null a představuje stejnou binární posloupnost znaků jako řetězec, který metodu volá.
Při porovnávání hodnot ID se délky ID nemusí rovnat. Pokud je například řetězec, který představuje 15místné ID, porovnán s objektem, který představuje 18místné ID, tato metoda stále vrací hodnotu true. Například:
String stringValue15 = '001D000000Ju1zH';
Id idValue18 = '001D000000Ju1zHIAR';
Boolean result = stringValue15.equals(idValue18);
System.debug('result: ' + result); //true
Ve výše uvedeném příkladu metoda equals porovnává 15místné ID objektu s 18místným ID objektu a pokud obě ID představují stejnou binární sekvenci, vrací hodnotu true.
Tuto metodu použijte k porovnání velikosti písmen.
escapeSingleQuotes(stringToEscape)
Tato metoda přidá escape znak (\) před jakoukoli jednoduchou uvozovku v řetězci a vrátí výsledek. Tato metoda zabraňuje vkládání SOQL kódu při vytváření dynamického SOQL dotazu. Zajišťuje, aby všechny jednoduché uvozovky byly považovány za uzavírající řetězce, nikoli za databázové příkazy.
Například:
String s = 'Hello \'Tom\''; String escapedStr = String.escapeSingleQuotes(s); System.debug(escapedStr); // Outputs Hello \'Tom\'
odstranit (podřetězec)
Tato metoda odstraní všechny výskyty uvedeného podřetězce z řetězce, který metodu volá, a vrátí výsledný řetězec.
Například:
String s1 = 'Salesforce and force.com';
String s2 = s1.remove('force');
System.debug('s2: ' + s2); // 'Sales and .com'
podřetězec (startIndex)
Tato metoda vrací podřetězec, který začíná znakem v indexu startIndex a sahá až do konce řetězce.
Například:
String s1 = 'hamburger';
String s2 = s1.substring(3);
System.debug('s2: ' + s2); //burger
zvrátit()
Tato metoda obrátí všechny znaky řetězce a vrátí ho. Například:
String s = 'Hello';
String s2 = s.reverse();
System.debug('s2:::: ' + s2); // olleH
výbava ()
Tato metoda odstraní z řetězce všechny úvodní a koncové mezery a vrátí jej.
valueOf(toConvert)
Tato metoda vrací řetězcovou reprezentaci předaného objektu.
Řetězce, třídy a klíčová slova se spojí, když začnete balit logiku do opakovaně použitelných jednotek, což je přesně to, k čemu třídy Apex slouží.
Třída Apex
Třída Apex je plán nebo šablona, ze které se vytvářejí objekty. Objekt je instancí třídy.
V Salesforce existují tři způsoby vytváření tříd Apex:
- Konzole pro vývojáře
- Visual Studio Code s rozšiřujícím balíčkem Salesforce
- Stránka s podrobnostmi o třídě Apex v Nastavení
V Apexu můžete definovat vnější třídu, nazývanou také třída nejvyšší úrovně, a také můžete definovat třídy uvnitř vnější třídy, nazývané vnitřní třídy.
V deklaraci vnější třídy je povinné použít modifikátor přístupu, jako je global nebo public.
V deklaraci vnitřních tříd není nutné používat modifikátor přístupu.
Třída Apex je definována pomocí klíčového slova class následovaného názvem třídy.
Klíčové slovo extends se používá k rozšíření existující třídy ve třídě Apex a klíčové slovo implements se používá k implementaci rozhraní ve třídě Apex.
Salesforce Apex nepodporuje vícenásobnou dědičnost; třída Apex může rozšiřovat pouze jednu existující třídu Apex, ale může implementovat více rozhraní.
Třída Apex může obsahovat uživatelem definovaný konstruktor a pokud uživatelem definovaný konstruktor není k dispozici, použije se výchozí konstruktor. Kód v konstruktoru se provede při vytvoření instance třídy.
Syntaxe třídy Apex:
public class myApexClass{
// variable declaration
//constructor
public myApexClass(){
}
//methods declaration
}
Klíčové slovo new se používá k vytvoření instance třídy Apex. Níže je uvedena syntaxe pro vytvoření instance třídy Apex:
myApexClass obj = new myApexClass();
Apex Getter a Setter
Vlastnost Apex je podobná proměnné Apex. Pro vlastnost Apex jsou nezbytné metody get a setter. Lze je použít ke spuštění kódu před přístupem k hodnotě vlastnosti nebo její změnou. Kód v přístupovém objektu get se provede při čtení hodnoty vlastnosti. Kód v přístupovém objektu set se provede při změně hodnoty vlastnosti. Jakákoli vlastnost, která má pouze přístupový objekt get, je považována za vlastnost pouze pro čtení, jakákoli vlastnost, která má pouze přístupový objekt set, je považována za vlastnost pouze pro zápis a jakákoli vlastnost, která má přístupové objekty get i set, je považována za vlastnost pro čtení i zápis. Syntaxe vlastnosti Apex:
public class myApexClass {
// Property declaration
access_modifier return_type property_name {
get {
//code
}
set{
//code
}
}
}
Zde je access_modifier modifikátor přístupu k vlastnosti, return_type je datový typ vlastnosti a property_name je název vlastnosti.
Níže je uveden příklad vlastnosti Apex, která má přístupové objekty get i set:
public class myApex{
public String name{
get{ return name; }
set{ name = value; }
}
}
Zde je název vlastnosti name, jedná se o veřejnou vlastnost a vrací datový typ String.
Není povinné mít kód v blocích get a set. Tyto bloky lze ponechat prázdné pro definování automatické vlastnosti. Například:
public double MyReadWriteProp{ get; set; }
Přístupové objekty Get a set lze také definovat s vlastními modifikátory přístupu. Pokud je přístupový objekt definován s modifikátorem, přepíše modifikátor přístupu vlastnosti. Například:
public String name{private get; set;}// name is private for read and public for write.
Třídy definují opakovaně použitelnou logiku, kterou voláte explicitně. Triggery, které budou popsány dále, se spouštějí automaticky při každé změně záznamů.
Apex Trigger
Triggery Apexu umožňují spustit vlastní Apex před a po provedení operace DML.
Apex podporuje následující dva typy spouštěčů:
Před spouštěči: Tyto triggery se používají k ověření a aktualizaci hodnoty pole před uložením záznamu do databáze.
Po spouštěčích: Tyto triggery se používají k přístupu k hodnotám polí (například ID záznamu a pole LastModifiedDate), které systém nastaví po potvrzení záznamu do databáze. Tyto hodnoty polí lze použít k úpravě jiných záznamů. Záznamy, které se spustí po triggerech, jsou pouze pro čtení.
Nejlepší praxí je psát hromadně generované triggery. Hromadně generovaný trigger dokáže zpracovat jeden záznam i více záznamů najednou.
Syntaxe spouštěče Apex:
trigger TriggerName on ObjectName (trigger_events) {
//Code_block
}
Zde je TriggerName název spouštěče, ObjectName název objektu, na kterém je spouštěč zapsán, a trigger_events je seznam událostí oddělených čárkami.
Následují události podporované triggery Apexu: před vložením, před aktualizací, před smazáním, po vložení, po aktualizaci, po smazání, po obnovení smazání.
Statická klíčová slova nelze použít v triggeru Apex. Všechna klíčová slova platná pro vnitřní třídy lze v triggeru Apex použít.
Každý trigger definuje implicitní proměnné, které vracejí kontext za běhu. Tyto proměnné jsou definovány ve třídě System.Trigger a nazývají se kontextové proměnné. Dva snímky obrazovky níže uvádějí kontextové proměnné podporované triggery Apexu:
Následují aspekty kontextových proměnných v triggerech Apexu:
- Nepoužívejte trigger.new a trigger.old v operacích DML.
- Soubor Trigger.new nelze smazat.
- Soubor Trigger.new je v after triggerech pouze pro čtení.
- Trigger.new lze použít ke změně hodnot polí na stejném objektu pouze v předcházejících triggerech.
Dva snímky obrazovky níže uvádějí aspekty specifických akcí v různých spouštěcích událostech:
Triggery zpracovávají logiku v reálném čase, ale některé úlohy jsou prostě příliš velké pro jednu transakci. A právě zde přichází na řadu dávkový Apex.
Batch Class v Apex
Třída Batch v Salesforce se používá ke zpracování velkého počtu záznamů, které by při normálním zpracování překročily limity regulátoru Apex. Třída Batch spouští kód asynchronně.
Následují výhody dávkové třídy:
- Dávková třída zpracovává data v blocích a pokud se jeden bloček úspěšně nezpracuje, úspěšně zpracované blocky se nevrací zpět.
- Každý blok dat v dávkové třídě je zpracován s novou sadou limitů regulátoru, což zajišťuje, že se kód provede v rámci limitů provádění regulátoru.
Rozhraní Database.Batchable musí být implementováno třídou Apex, aby mohlo být použito jako třída Batch. Poskytuje tři metody, které musí být implementovány třídou Batch:
1. start()
Tato metoda generuje rozsah záznamů nebo objektů, které mají být zpracovány metodou rozhraní execute. Je volána pouze jednou během provádění dávky. Tato metoda vrací buď objekt Database.QueryLocator, nebo Iterable. Počet záznamů, které lze načíst dotazem SOQL pomocí objektu Database.QueryLocator, je 50 milionů, ale s použitím Iterable je celkový počet záznamů, které lze načíst dotazem SOQL, pouze 50 000. Iterable se používá ke generování komplexního rozsahu pro třídu dávky.
Syntaxe metody start:
global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}
2. spustit()
Tato metoda se používá pro zpracování každého bloku dat. Metoda execute se volá pro každý blok záznamů. Výchozí velikost dávky pro spuštění je 200 záznamů. Metoda execute přijímá dva argumenty:
Odkaz na objekt Database.BatchableContext,
Seznam objektů sObject, například List , nebo seznam parametrizovaných typů. Syntaxe metody execute:
global void execute(Database.BatchableContext bc, List<P> records){}
3. dokončení()
Metoda finish je volána jednou během provádění třídy batch. V metodě finish lze provádět následné operace. Například: odeslání potvrzovacího e-mailu. Tato metoda je volána, když jsou zpracovány všechny dávky. Syntaxe metody finish:
global void finish(Database.BatchableContext bc){}
Objekt Database.BatchableContext
Každá metoda rozhraní Database.Batchable má odkaz na objekt Database.BatchableContext.
Tento objekt se používá k track průběh dávkové úlohy.
Následují metody instance poskytované BatchableContext:
- getChildJobId(): Tato metoda vrací ID dávkové úlohy, která se aktuálně zpracovává.
- getJobId(): Tato metoda vrací ID dávkové úlohy.
Níže je uvedena syntaxe třídy dávkového zpracování:
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 Method
Metoda Database.executeBatch se používá ke spuštění dávkové třídy.
Tato metoda přijímá dva parametry: instanci třídy batch, která má být zpracována, a volitelný parametr scope pro určení velikosti dávky. Pokud není zadán, použije se výchozí velikost 200.
Syntaxe Database.executeBatch:
Database.executeBatch(myBatchObject, scope)
Spuštění dávkové třídy s názvem MyBatchClass:
MyBatchClass myBatchObject = new MyBatchClass(); Id batchId = Database.executeBatch(myBatchObject, 100);
Databáze.Stavová
Třída typu batch je ve výchozím nastavení bezstavová. Pokaždé, když je volána metoda execute, je přijata nová kopie objektu a všechny proměnné třídy jsou inicializovány.
Database.Stateful je implementován tak, aby třída dávkového kódu byla stavová.
Pokud vaše dávková třída implementuje Databáze.Stavové rozhraní, všechny proměnné instance si zachovávají své hodnoty, ale statické proměnné se mezi transakcemi resetují.
Asynchronní Apex Beyond Batch
Batch Apex je pouze jedním z několika způsobů, jak asynchronně spouštět kód. Salesforce nabízí čtyři asynchronní možnosti a výběr té správné závisí na tom, kolik dat zpracováváte a zda je třeba úlohy řetězit nebo plánovat.
- Budoucí metody: Tyto prvky, označené jako @future, jsou nejvhodnější pro jednoduché operace typu „vystřel a zapomeň“, jako jsou například volání externích webových služeb.
- Apex, který lze zařadit do fronty: Implementuje rozhraní Queueable, přijímá komplexní typy objektů, vrací ID úlohy a podporuje řetězení jedné úlohy s druhou.
- Vrchol dávky: Zpracovává velmi velké objemy dat v blocích, jak je popsáno výše.
- Plánovaný Apex: Implementuje rozhraní Schedulable, takže třída běží v určitém čase, například při nočním čištění.
| Typ | nejlepší | Klíčová schopnost |
|---|---|---|
| Budoucí metoda | Jednoduché popisky | Vystřel a zapomeň |
| Apex, který lze zařadit do fronty | Sekvenční zpracování | Řetězení a monitorování úloh |
| Dávkový Apex | Miliony záznamů | Blokové zpracování |
| Plánovaný Apex | Opakující se úlohy | Časování založené na cronu |
Ať už si vyberete jakýkoli model provedení, každá transakce je stále porovnávána s níže uvedenými limity regulátoru platnými pro celou platformu.
Apex Governor Limits
Limity regulátorů Apexu jsou limity vynucované běhovým enginem Apexu, aby se zajistilo, že jakýkoli nekontrolovatelný kód a procesy Apexu nemonopolizují sdílené zdroje a nenarušují zpracování ostatních uživatelů v prostředí s více klienty. Tyto limity jsou ověřovány pro každou transakci Apexu. Následují limity regulátorů definované společností Salesforce pro každou transakci Apexu:
| Description | Omezit |
|---|---|
| SOQL dotazy, které lze provést v synchronní transakci | 100 |
| SOQL dotazy, které lze provést v asynchronní transakci | 200 |
| Záznamy, které lze získat dotazem SOQL | 50,000 |
| Záznamy, které lze načíst pomocí Database.getQueryLocator | 10,000 |
| Dotazy SOSL, které lze provést v transakci Apex | 20 |
| Záznamy, které lze získat dotazem SOSL | 2,000 |
| Příkazy DML, které lze provést v transakci Apex | 150 |
| Záznamy, které lze zpracovat jako výsledek příkazu DML, Approval.process nebo database.emptyRecycleBin | 10,000 |
| Volání, která lze provést v transakci Apex | 100 |
| Kumulativní časový limit pro všechna volání prováděná v transakci Apex | 120 sekund |
| Omezení počtu úloh Apex, které lze přidat do fronty pomocí System.enqueueJob | 50 |
| Časový limit pro každou transakci Apex | 10 minut |
| Omezení počtu znaků, které lze použít ve třídě a triggeru Apexu | 1 milionu |
| Časový limit CPU pro synchronní transakci | 10,000 milisekund |
| Časový limit CPU pro asynchronní transakci | 60,000 milisekund |
| Celková velikost haldy | 6 MB (synchronní) / 12 MB (asynchronní) |
Jak napsat testovací třídu v Apexu
Salesforce vyžaduje, aby alespoň 75 procent kódu Apexu bylo pokryto jednotkovými testy, než jej budete moci nasadit do produkčního prostředí, a každý trigger musí mít nějaké pokrytí. Psaní testovacích tříd je proto základní dovedností Apexu, nikoli volitelným doplňkem.
Testovací třída je anotována pomocí @isTest a každá testovací metoda je také označena pomocí @isTest. Testovací metody neukládají data do databáze a nevidí většinu existujících organizačních dat, takže každý test vytváří své vlastní záznamy. Metody Test.startTest() a Test.stopTest() dávají testovanému kódu novou sadu limitů regulátoru a aserce ověřují, zda se logika chovala podle očekávání.
Zde je jednoduchá testovací třída pro logiku vytváření účtů:
@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);
}
}
Při psaní testů dodržujte tato pravidla:
- Pomocí metody @testSetup vytvořte sdílená testovací data jednou pro všechny testovací metody ve třídě.
- Otestujte chování hromadného vložením 200 záznamů, ne jen jednoho.
- Zahrňte pozitivní, negativní a omezené uživatelské scénáře.
- Vždy uvádějte smysluplné příkazy System.assert; pokrytí bez assertů nic nedokazuje.
Nejlepší postupy Apexu
Začátečníci často píší Apex, který funguje pro jeden záznam, ale selhává v reálných hromadných operacích. Níže uvedené postupy udržují váš kód v rámci limitů regulátoru a snáze se udržuje:
- Všechno hromadně zkopírujte: Napište logiku, která zpracovává kolekce záznamů, protože triggery mohou v jedné dávce přijímat až 200 záznamů.
- Udržujte SOQL a DML mimo smyčky: Dotaz před smyčkou, shromažďování změn v seznamu a provádění jednoho DML příkazu po smyčce.
- Jeden spouštěč na objekt: Udržujte triggery bez logiky a delegujte práci na třídy obslužných rutin, což umožňuje předvídatelné pořadí provádění.
- Používejte se sdílením: Vynucujte zabezpečení na úrovni záznamů, pokud neexistuje zdokumentovaný důvod pro spuštění v kontextu systému.
- Vyhněte se pevně zadávaným ID: ID záznamů se liší mezi sandboxy a produkčním prostředím, proto je dotazujte nebo použijte vlastní metadata.
- Sledování limitů v kódu: Metody třídy Limits, jako například Limits.getQueries(), umožňují kontrolovat spotřebu zdrojů za běhu.
👍 Tip: Před nasazením spusťte kód na 200 záznamech v sandboxu. Většina selhání limitů regulátorů se objevuje pouze při hromadném načítání a jejich včasné odhalení je mnohem levnější než jejich ladění v produkčním prostředí.






