Tutorial Salesforce Apex pentru începători

⚡ Rezumat inteligent

Programarea Apex oferă dezvoltatorilor Salesforce un limbaj orientat pe obiecte, puternic tipizat, pentru adăugarea de logică de business personalizată în CRM. Acesta alimentează clasele, declanșatoarele și joburile batch, în timp ce limitele guvernatorului mențin platforma multi-tenant partajată stabilă.

  • 🧱 Foundation: Apex este un limbaj care nu ține cont de majuscule/minuscule, cu Java- sintaxă asemănătoare cu cea care rulează nativ pe platforma Salesforce Lightning.
  • 🗃️ Acces la date: Interogările SOQL și instrucțiunile DML permit codului dvs. să citească și să scrie înregistrări sObject direct în baza de date Salesforce.
  • 🛠️ Implementare: Clasele, proprietățile și declanșatoarele atașează logică personalizată pentru inserări, actualizări, ștergeri și alte evenimente de sistem înregistrări.
  • 📦 Scară: Batch Apex și alte opțiuni asincrone procesează milioane de înregistrări în blocuri fără a încălca limitele platformei.
  • 🚦 Limitele guvernatorului: Limitele per tranzacție, cum ar fi 100 de interogări SOQL sincrone și 150 de instrucțiuni DML, protejează resursele partajate.
  • Calitate: Testele unitare trebuie să acopere cel puțin 75% din codul Apex înainte de implementarea în producție.

Prezentare generală a programării APEX Salesforce

Ce este Apex în Salesforce?

Apex este un limbaj de programare orientat pe obiecte și puternic tipizat, dezvoltat de Salesforce pentru construirea de aplicații Software as a Service (SaaS) și Customer Relationship Management (CRM). Apex ajută dezvoltatorii să creeze aplicații SaaS terțe și să adauge logică de business evenimentelor de sistem, oferind suport pentru baze de date back-end și interfețe client-server.

Apex îi ajută pe dezvoltatori să adauge logică de business evenimentelor de sistem, cum ar fi clicurile pe butoane, actualizările de înregistrări aferente și paginile Visualforce. Apex are o sintaxă similară cu Java. Înregistrați-vă pentru Salesforce pentru a afla cum funcționează CRM-ul.

Caracteristicile limbajului de programare Apex

Iată care sunt caracteristicile importante ale Salesforce Apex:

  • Apex este un limbaj care nu ține cont de majuscule/minuscule.
  • Puteți efectua operațiuni DML precum INSERT, UPDATE, UPSERT și DELETE asupra înregistrărilor sObject folosind Apex.
  • Puteți interoga înregistrări sObject folosind SOQL (Salesforce Object Query Language) și SOSL (Salesforce Object Search Language) în Apex.
  • Vă permite să creați un test de unitate și executați-l pentru a verifica acoperire cod și eficiența codului în Apex.
  • Apex se execută într-un mediu cu mai mulți chiriași și Salesforce are limite definite ale guvernatorului care împiedică un utilizator să monopolizeze resursele partajate. Orice cod care depășește o limită a guvernatorului Salesforce eșuează și apare o eroare.
  • Un obiect Salesforce poate fi utilizat ca tip de date în Apex. De exemplu:
    Account acc = new Account();

    Aici, Account este un obiect Salesforce standard.

  • Apex se actualizează automat cu fiecare lansare Salesforce.

Când ar trebui un dezvoltator să aleagă Apex?

Codul Apex ar trebui scris doar dacă un scenariu de afaceri este prea complex pentru a fi implementat folosind funcționalitatea predefinită, point-and-click, oferită de Salesforce.

Următoarele sunt câteva scenarii în care trebuie să scrieți cod Apex:

  • Pentru a crea servicii web care integrează Salesforce cu alte aplicații.
  • Pentru a implementa validare personalizată pe sObjects.
  • Pentru a executa o logică Apex personalizată atunci când se efectuează o operațiune DML.
  • Pentru a implementa funcționalități care nu pot fi construite cu instrumentele de automatizare declarativă existente, cum ar fi Flow.
  • A înscena servicii de e-mail care procesează conținutul, anteturile și atașamentele e-mailurilor primite.

Odată ce știi când Apex este alegerea potrivită, următorul pas este să înțelegi ce se întâmplă cu codul tău după ce îl salvezi.

Structura de lucru a Apex

Următorul este fluxul de acțiuni pentru codul Apex:

  • Acțiunea dezvoltatorului: Când dezvoltatorul salvează cod pe platformă, tot codul Apex este compilat într-un set de instrucțiuni pe care interpretorul de execuție Apex le poate înțelege, iar aceste instrucțiuni sunt apoi salvate ca metadate pe platformă.
  • Acțiunea utilizatorului final: Când un eveniment al utilizatorului execută cod Apex, serverul platformei preia instrucțiunile compilate din metadate și le rulează prin interpretorul Apex înainte de a returna rezultatul.

Diagrama de mai jos arată cum acțiunile dezvoltatorului și ale utilizatorului final interacționează cu serverul de aplicații Lightning Platform:

Structura de lucru a Apex

Mediul de dezvoltare Apex

Codul Apex poate fi dezvoltat fie într-un sandbox, fie într-o organizație Salesforce Developer Edition.

Este o practică recomandată să dezvoltați codul într-un mediu sandbox și apoi să îl implementați în mediul de producție, așa cum este ilustrat mai jos:

Mediul de dezvoltare Apex

Instrumente de dezvoltare a codului Apex: Următoarele sunt cele trei instrumente disponibile pentru dezvoltarea codului Apex în toate edițiile Salesforce:

  • Consola pentru dezvoltatori
  • Visual Studio Code cu Salesforce Extension Pack (acesta înlocuiește IDE-ul Force.com retras)
  • Code editor în interfața utilizator Salesforce Setup

Odată ce mediul dumneavoastră este pregătit, să analizăm elementele constitutive ale limbajului în sine, începând cu tipurile de date.

Tipuri de date în Apex

Următoarele sunt tipurile de date acceptate de Apex:

Primitiv

Întreg, Double, Long, Date, Datetime, Decimal, Time, Blob, String, ID și Boolean sunt considerate tipuri de date primitive. Toate tipurile de date primitive sunt transmise prin valoare, nu prin referință.

Colecţii

Trei tipuri de colecții sunt disponibile în Apex:

  • Listă: Este o colecție ordonată de primitive, sObjects, colecții sau obiecte Apex bazate pe indici.
  • Set: O colecție neordonată de elemente unice care nu conține duplicate.
  • Hartă: Este o colecție de chei unice care se mapează la valori individuale, care pot fi primitive, sObjects, colecții sau obiecte Apex.

sObiect

Acesta este un tip de date special în Salesforce. Este asemănător cu o masă în SQL și conține câmpuri similare cu coloanele din SQL.

Enumere

O enumerare este un abdomentracTipul de date t care stochează o valoare dintr-un set finit de identificatori specificați.

Clase, obiecte și interfețe

Clasele și interfețele Apex definite de utilizator pot fi, de asemenea, utilizate ca tipuri de date. Un obiect se referă la o instanță a oricărui tip de date acceptat în Apex.

Sintaxa Apex

Declarație variabilă

Deoarece Apex este un limbaj puternic tipizat, este obligatorie declararea unei variabile cu un tip de date în Apex.

De exemplu:

Contact con = new Contact();

Aici variabila con este declarată cu tipul de date Contact.

Interogare SOQL

SOQL este prescurtarea de la Salesforce Object Query Language. SOQL este utilizat pentru a prelua înregistrări sObject din baza de date Salesforce. De exemplu:

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

Interogarea de mai sus preia o înregistrare de cont din baza de date Salesforce.

Declarație de buclă

O instrucțiune de tip buclă este utilizată pentru a itera peste înregistrările dintr-o listă. Numărul de iterații este egal cu numărul de înregistrări din listă. De exemplu:

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

În fragmentul de cod de mai sus, listOfAccounts este o variabilă de tipul de date List.

Declarație de control al fluxului

O instrucțiune de control al fluxului este benefică atunci când doriți să executați anumite linii de cod pe baza anumitor condiții.

De exemplu:

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
}

Fragmentul de cod de mai sus interoghează înregistrările contului din baza de date și verifică dimensiunea listei.

Declarație DML

DML este prescurtarea de la Data Manipulation Language (Limbaj de Manipulare a Datelor). Instrucțiunile DML sunt utilizate pentru a manipula datele din baza de date Salesforce. De exemplu:

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

Specificatori de acces Apex

Următorii sunt specificatorii de acces acceptați de Apex:

Public

Acest specificator de acces oferă acces la o clasă, metodă sau variabilă care va fi utilizată de Apex într-un spațiu de nume.

Privat

Acest specificator de acces oferă acces la o clasă, metodă sau variabilă care poate fi utilizată local sau în secțiunea de cod în care este definită. Toate metodele și variabilele care nu au un specificator de acces definit preiau specificatorul de acces implicit, private.

Protejat

Acest specificator de acces oferă acces la o metodă sau o variabilă care poate fi utilizată de orice clase interne din cadrul clasei Apex definitorii.

Caritate

Acest specificator de acces oferă acces la o clasă, metodă sau variabilă care poate fi utilizată de Apex atât în ​​cadrul unui spațiu de nume, cât și în afara acestuia. Se recomandă utilizarea cuvântului cheie global decât dacă este necesar.

Cuvinte cheie în Apex

Cu partajare

Dacă o clasă este definită cu acest cuvânt cheie, atunci sunt aplicate toate regulile de partajare care se aplică utilizatorului curent. Dacă acest cuvânt cheie lipsește, codul se execută în contextul sistemului.

De exemplu:

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

Fără a împărtăși

Dacă o clasă este definită cu acest cuvânt cheie, atunci regulile de partajare care se aplică utilizatorului curent nu sunt aplicate.

De exemplu:

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

Static

O variabilă sau o metodă definită cu cuvântul cheie static este inițializată o singură dată și asociată clasei. Variabilele și metodele statice pot fi apelate direct prin numele clasei, fără a crea o instanță a acesteia.

Final

O constantă sau o metodă definită cu cuvântul cheie final nu poate fi suprascrisă. De exemplu:

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

Dacă încercați să suprascrieți valoarea acestei variabile INT_CONST, veți primi excepția – System.FinalException: Variabila finală a fost deja inițializată.

Retur

Acest cuvânt cheie returnează o valoare dintr-o metodă. De exemplu:

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

Null

Definește o constantă nulă și poate fi atribuită unei variabile. De exemplu:

Boolean b = null;

Virtual

Dacă o clasă este definită cu cuvântul cheie virtual, aceasta poate fi extinsă și suprascrisă.

Abstract

Dacă o clasă este definită cu abstraccuvântul cheie t, acesta trebuie să conțină cel puțin o metodă cu cuvântul cheie abstract, iar metoda respectivă ar trebui să aibă doar o semnătură.

De exemplu:

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

String Apex

Un șir de caractere este un set de caractere fără limită de caractere. De exemplu:

String name = 'Test';

Există mai multe metode încorporate oferite de clasa String în Salesforce. Următoarele sunt câteva metode utilizate frecvent:

abreviat(maxWidth)

Această metodă trunchiază un șir la lungimea specificată și îl returnează dacă lungimea șirului dat este mai mare decât lungimea specificată; în caz contrar, returnează șirul original. Dacă valoarea variabilei maxWidth este mai mică de 4, această metodă generează o excepție de execuție – System.StringException: Lățimea minimă a abrevierii este 4.

De exemplu:

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

valorifica()

Această metodă convertește prima literă a unui șir în majuscule și o returnează.

De exemplu:

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

conține (subșir)

Această metodă returnează valoarea „true” dacă șirul care apelează metoda conține subșirul specificat.

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

equals(stringOrId)

Această metodă returnează valoarea „true” dacă parametrul transmis nu este nul și reprezintă aceeași secvență binară de caractere ca și șirul care apelează metoda.

Când se compară valorile ID-urilor, este posibil ca lungimile ID-urilor să nu fie egale. De exemplu, dacă un șir care reprezintă un ID de 15 caractere este comparat cu un obiect care reprezintă un ID de 18 caractere, această metodă returnează în continuare valoarea true. De exemplu:

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

În exemplul de mai sus, metoda „equals” compară un ID de obiect de 15 caractere cu un ID de obiect de 18 caractere, iar dacă ambele ID-uri reprezintă aceeași secvență binară, returnează valoarea „true”.

Utilizați această metodă pentru a face comparații sensibile la majuscule și minuscule.

escapeSingleQuotes(stringToEscape)

Această metodă adaugă un caracter de escape (\) înaintea oricărui ghilimele dintr-un șir și returnează rezultatul. Această metodă previne injectarea SOQL în timpul creării unei interogări SOQL dinamice. Se asigură că toate ghilimelele sunt tratate ca șiruri de caractere care încadrează și nu ca comenzi de bază de date.

De exemplu:

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

elimina (subșir)

Această metodă elimină toate aparițiile subșirului menționat din șirul care apelează metoda și returnează șirul rezultat.

De exemplu:

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

subșir (startIndex)

Această metodă returnează un subșir care începe de la caracterul de la startIndex și se extinde până la sfârșitul șirului.

De exemplu:

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

verso()

Această metodă inversează toate caracterele unui șir de caractere și îl returnează. De exemplu:

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

tunde()

Această metodă elimină toate spațiile albe de la început și de la sfârșit dintr-un șir de caractere și îl returnează.

valueOf(pentru a converti)

Această metodă returnează reprezentarea sub formă de șir de caractere a obiectului transmis.

Șirurile de caractere, clasele și cuvintele cheie se reunesc atunci când începi să împachetezi logica în unități reutilizabile, exact pentru care sunt folosite clasele Apex.

Clasa Apex

O clasă Apex este un plan sau un șablon din care sunt create obiecte. Un obiect este o instanță a unei clase.

Există trei modalități de a crea clase Apex în Salesforce:

  • Consola pentru dezvoltatori
  • Visual Studio Code cu pachetul de extensie Salesforce
  • Pagina cu detalii despre clasa Apex în secțiunea Configurare

În Apex, puteți defini o clasă externă, numită și clasă de nivel superior, și puteți defini, de asemenea, clase în cadrul unei clase externe, numite clase interne.

Este obligatorie utilizarea unui modificator de acces precum global sau public în declararea unei clase externe.

Nu este necesar să se utilizeze un modificator de acces în declararea claselor interne.

O clasă Apex este definită folosind cuvântul cheie class urmat de numele clasei.

Cuvântul cheie extends este utilizat pentru a extinde o clasă existentă într-o clasă Apex, iar cuvântul cheie implements este utilizat pentru a implementa o interfață într-o clasă Apex.

Salesforce Apex nu acceptă moștenirea multiplă; o clasă Apex poate extinde doar o clasă Apex existentă, dar poate implementa mai multe interfețe.

O clasă Apex poate conține un constructor definit de utilizator, iar dacă un constructor definit de utilizator nu este disponibil, se utilizează un constructor implicit. Codul dintr-un constructor se execută atunci când este creată o instanță a unei clase.

Sintaxa unei clase Apex:

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

Cuvântul cheie new este utilizat pentru a crea o instanță a unei clase Apex. Mai jos este sintaxa pentru crearea unei instanțe a unei clase Apex:

myApexClass obj = new myApexClass();

Apex Getter și Setter

O proprietate Apex este similară cu o variabilă Apex. Un getter și un setter sunt necesare pentru o proprietate Apex. Acestea pot fi utilizate pentru a executa cod înainte ca valoarea proprietății să fie accesată sau modificată. Codul din accesorul get se execută atunci când este citită valoarea unei proprietăți. Codul din accesorul set se execută atunci când este modificată valoarea unei proprietăți. Orice proprietate care are doar un accesor get este considerată doar pentru citire, orice proprietate care are doar un accesor set este considerată doar pentru scriere, iar orice proprietate care are atât accesori get, cât și set este considerată pentru citire-scriere. Sintaxa unei proprietăți Apex:

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

Aici, access_modifier este modificatorul de acces al proprietății, return_type este tipul de date al proprietății, iar property_name este numele proprietății.

Mai jos este un exemplu de proprietate Apex care are atât accesori get, cât și set:

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

Aici, numele proprietății este name, este o proprietate publică și returnează un tip de date String.

Nu este obligatoriu să existe cod în blocurile get și set. Aceste blocuri pot fi lăsate goale pentru a defini o proprietate automată. De exemplu:

public double MyReadWriteProp{ get; set; }

Accesorii de tip „get” și „set” pot fi, de asemenea, definiți cu propriii modificatori de acces. Dacă un accesor este definit cu un modificator, acesta are prioritate față de modificatorul de acces al proprietății. De exemplu:

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

Clasele definesc o logică reutilizabilă pe care o apelați explicit. Declanșatoarele, prezentate în continuare, se execută automat de fiecare dată când înregistrările se modifică.

Apex Trigger

Declanșatoarele Apex vă permit să executați Apex personalizat înainte și după efectuarea unei operațiuni DML.

Apex acceptă următoarele două tipuri de declanșatoare:

Înainte de declanșatoare: Aceste declanșatoare sunt utilizate pentru a valida și actualiza valoarea unui câmp înainte ca înregistrarea să fie salvată în baza de date.

După declanșatoare: Aceste declanșatoare sunt utilizate pentru a accesa valorile câmpurilor (cum ar fi ID-ul înregistrării și câmpul LastModifiedDate) care sunt setate de sistem după ce o înregistrare este salvată în baza de date. Aceste valori ale câmpurilor pot fi utilizate pentru a modifica alte înregistrări. Înregistrările care se declanșează după declanșatoare sunt doar pentru citire.

Este o practică recomandată să scrieți declanșatoare grupate în bloc. Un declanșator grupat în bloc poate procesa atât o singură înregistrare, cât și mai multe înregistrări simultan.

Sintaxa unui declanșator Apex:

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

Aici, TriggerName este numele declanșatorului, ObjectName este numele obiectului pe care este scris declanșatorul, iar trigger_events este o listă de evenimente separate prin virgulă.

Următoarele sunt evenimentele acceptate de declanșatoarele Apex: înainte de inserare, înainte de actualizare, înainte de ștergere, după inserare, după actualizare, după ștergere, după anularea ștergerii.

Cuvintele cheie statice nu pot fi utilizate într-un declanșator Apex. Toate cuvintele cheie aplicabile claselor interne pot fi utilizate într-un declanșator Apex.

Există variabile implicite definite de fiecare declanșator care returnează contextul de execuție. Aceste variabile sunt definite în clasa System.Trigger și se numesc variabile de context. Cele două capturi de ecran de mai jos listează variabilele de context acceptate de declanșatoarele Apex:

Variabile de context ale declanșatorului Apex

Variabile de context ale declanșatorului Apex (continuare)

Următoarele sunt considerațiile pentru variabilele de context din declanșatoarele Apex:

  • Nu utilizați trigger.new și trigger.old în operațiunile DML.
  • Fișierul Trigger.new nu poate fi șters.
  • Trigger.new este doar pentru citire în declanșatoarele de după.
  • Trigger.new poate fi folosit pentru a modifica valorile câmpurilor de pe același obiect doar în declanșatoarele anterioare.

Cele două capturi de ecran de mai jos prezintă considerațiile privind acțiunile specifice în diferite evenimente declanșatoare:

Considerații privind evenimentele declanșatoare Apex

Considerații privind evenimentele declanșatoare Apex (continuare)

Declanșatoarele gestionează logica în timp real, dar unele joburi sunt pur și simplu prea mari pentru o singură tranzacție. Aici intervine Apex în batch.

Clasa lot în Apex

O clasă batch în Salesforce este utilizată pentru a procesa un număr mare de înregistrări care ar depăși limitele guvernatorului Apex dacă ar fi procesate normal. O clasă batch execută codul asincron.

Următoarele sunt avantajele unei clase batch:

  • O clasă batch procesează datele în blocuri, iar dacă un bloc eșuează în procesarea cu succes, blocurile procesate cu succes nu sunt anulate.
  • Fiecare fragment de date dintr-o clasă batch este procesată cu un nou set de limite de execuție ale guvernatorului, ceea ce asigură că codul se execută în limitele de execuție ale guvernatorului.

Interfața Database.Batchable trebuie implementată de o clasă Apex pentru a fi utilizată ca o clasă batch. Aceasta oferă trei metode care trebuie implementate de clasa batch:

1. start()

Această metodă generează domeniul de aplicare al înregistrărilor sau obiectelor care vor fi procesate de metoda de interfață execute. Este apelată o singură dată în timpul execuției batch-ului. Această metodă returnează fie un obiect Database.QueryLocator, fie un Iterable. Numărul de înregistrări care pot fi recuperate de o interogare SOQL utilizând obiectul Database.QueryLocator este de 50 de milioane, dar utilizând un Iterable, numărul total de înregistrări care pot fi recuperate de interogarea SOQL este de numai 50,000. Un Iterable este utilizat pentru a genera un domeniu de aplicare complex pentru clasa batch.

Sintaxa metodei de pornire:

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

2. executare()

Această metodă este utilizată pentru procesarea fiecărui bloc de date. Metoda execute este apelată pentru fiecare bloc de înregistrări. Dimensiunea implicită a lotului pentru execuție este de 200 de înregistrări. Metoda execute primește două argumente:

O referință la obiectul Database.BatchableContext,

O listă de sObjects, cum ar fi List , sau o listă de tipuri parametrizate. Sintaxa metodei execute:

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

3. finish()

Metoda finish este apelată o singură dată în timpul execuției clasei batch. Operațiunile de post-procesare pot fi efectuate în metoda finish. De exemplu: trimiterea unui e-mail de confirmare. Această metodă este apelată atunci când toate batch-urile sunt procesate. Sintaxa metodei finish:

global void finish(Database.BatchableContext bc){}

Obiect Database.BatchableContext

Fiecare metodă a interfeței Database.Batchable are o referință la un obiect Database.BatchableContext.

Acest obiect este folosit pentru a track progresul lucrării în lot.

Următoarele sunt metodele de instanță furnizate de BatchableContext:

  • getChildJobId(): Această metodă returnează ID-ul jobului batch care este procesat în prezent.
  • getJobId(): Această metodă returnează ID-ul jobului batch.

Mai jos este sintaxa unei clase batch:

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
}
}

Metoda Database.executeBatch

Metoda Database.executeBatch este utilizată pentru executarea unei clase batch.

Această metodă acceptă doi parametri: o instanță a clasei batch care urmează să fie procesată și un parametru opțional de tip scope pentru a specifica dimensiunea batch-ului. Dacă nu este specificat, se utilizează dimensiunea implicită de 200.

Sintaxa funcției Database.executeBatch:

Database.executeBatch(myBatchObject, scope)

Executarea unei clase batch numită MyBatchClass:

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

Bază de date.Stateful

O clasă batch este implicit fără stare. De fiecare dată când este apelată metoda execute, este primită o nouă copie a obiectului și toate variabilele clasei sunt inițializate.

Database.Stateful este implementat pentru a face o clasă batch cu stare.

Dacă clasa ta batch implementează Baza de dateInterfață cu stări, toate variabilele de instanță își păstrează valorile, dar variabilele statice sunt resetate între tranzacții.

Apex asincron dincolo de lot

Batch Apex este doar una dintre numeroasele modalități de a rula cod în mod asincron. Salesforce oferă patru opțiuni asincrone, iar alegerea celei potrivite depinde de cantitatea de date pe care o procesați și dacă joburile trebuie înlănțuite sau programate.

  • Metode viitoare: Adnotate cu @future, acestea sunt ideale pentru operațiuni simple, de tip „declanșare și uitare”, cum ar fi apelurile către servicii web externe.
  • Apex în coadă: Implementează interfața Queueable, acceptă tipuri de obiecte complexe, returnează un ID de job și permite legarea unui job la altul.
  • Apexul lotului: Procesează volume foarte mari de date în blocuri, așa cum este descris mai sus.
  • Apex programat: Implementează interfața Schedulable astfel încât o clasă să ruleze la o anumită oră, cum ar fi o sarcină de curățare nocturnă.
Tip Cele mai bune Capacitate cheie
Metoda viitoare Apeluri simple Foc și uită
Apex la coadă Prelucrare secvențială Lanțul de joburi și monitorizarea
Apex de lot Milioane de înregistrări Procesare în blocuri
Apex programat Locuri de muncă recurente Cronizare bazată pe cron

Indiferent de modelul de execuție ales, fiecare tranzacție este măsurată în continuare în raport cu limitele guvernatorului la nivel de platformă enumerate mai jos.

Limitele guvernatorului Apex

Limitele guvernatorului Apex sunt limitele impuse de motorul de execuție Apex pentru a se asigura că orice cod și procese Apex care scapă de sub control nu monopolizează resursele partajate și nu perturbă procesarea altor utilizatori în mediul multi-tenant. Aceste limite sunt verificate pentru fiecare tranzacție Apex. În continuare sunt prezentate limitele guvernatorului definite de Salesforce pentru fiecare tranzacție Apex:

Descriere Limita
Interogări SOQL care pot fi efectuate într-o tranzacție sincronă 100
Interogări SOQL care pot fi efectuate într-o tranzacție asincronă 200
Înregistrări care pot fi preluate printr-o interogare SOQL 50,000
Înregistrări care pot fi preluate de Database.getQueryLocator 10,000
Interogări SOSL care pot fi efectuate într-o tranzacție Apex 20
Înregistrări care pot fi preluate printr-o interogare SOSL 2,000
Instrucțiuni DML care pot fi executate într-o tranzacție Apex 150
Înregistrări care pot fi procesate ca urmare a unei instrucțiuni DML, Approval.process sau database.emptyRecycleBin 10,000
Apeluri care pot fi efectuate într-o tranzacție Apex 100
Limită de timeout cumulativă pentru toate apelurile efectuate într-o tranzacție Apex 120 secunde
Limită de joburi Apex care pot fi adăugate la coadă cu System.enqueueJob 50
Limită de timp de execuție pentru fiecare tranzacție Apex 10 minute
Limită de caractere care pot fi utilizate într-o clasă și un declanșator Apex 1 milioane de euro
Limita de timp CPU pentru o tranzacție sincronă XISUM milisecunde
Limita de timp CPU pentru o tranzacție asincronă XISUM milisecunde
Dimensiunea totală a heap-ului 6 MB (sincron) / 12 MB (asincron)

Cum se scrie o clasă de test în Apex

Salesforce necesită ca cel puțin 75% din codul Apex să fie acoperit de teste unitare înainte de a-l putea implementa în producție, iar fiecare declanșator trebuie să aibă o anumită acoperire. Prin urmare, scrierea claselor de testare este o abilitate de bază în Apex, nu un extra opțional.

O clasă de testare este adnotată cu @isTest, iar fiecare metodă de testare este, de asemenea, marcată cu @isTest. Metodele de testare nu salvează date în baza de date și nu văd majoritatea datelor organizaționale existente, așa că fiecare test își creează propriile înregistrări. Metodele Test.startTest() și Test.stopTest() oferă codului testat un set nou de limite guvernatoare, iar aserțiunile verifică dacă logica s-a comportat conform așteptărilor.

Iată o clasă de test simplă pentru logica de creare a contului:

@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);
    }
}

Urmați aceste instrucțiuni atunci când scrieți teste:

  • Folosește metoda @testSetup pentru a crea date de testare partajate o singură dată pentru toate metodele de testare din clasă.
  • Testați comportamentul în bloc prin inserarea a 200 de înregistrări, nu doar a uneia.
  • Acoperiți scenarii pozitive, negative și cu utilizatori restricționați.
  • Includeți întotdeauna instrucțiuni System.assert semnificative; acoperirea fără aserțiuni nu dovedește nimic.

Cele mai bune practici Apex

Începătorii scriu adesea Apex care funcționează pentru o singură înregistrare, dar eșuează în operațiunile în bloc din lumea reală. Practicile de mai jos mențin codul în limitele guvernatorului și îl fac mai ușor de întreținut:

  • Converți totul în vrac: Scrieți o logică care gestionează colecții de înregistrări, deoarece declanșatoarele pot primi până la 200 de înregistrări într-un singur lot.
  • Păstrați SOQL și DML în afara buclelor: Interogare înainte de buclă, colectare a modificărilor într-o listă și executare a unei instrucțiuni DML după buclă.
  • Un declanșator per obiect: Păstrați declanșatoarele fără logică și delegați munca către clasele de gestionare, ceea ce face ca ordinea de execuție să fie previzibilă.
  • Utilizare cu partajare: Aplicați securitatea la nivel de înregistrare, cu excepția cazului în care există un motiv documentat pentru a rula în contextul sistemului.
  • Evitați codarea hardcoding a ID-urilor: ID-urile înregistrărilor diferă între sandbox-uri și producție, așa că interogați-le sau utilizați metadate personalizate.
  • Monitorizați limitele în cod: Metodele clasei Limits, cum ar fi Limits.getQueries(), vă permit să verificați consumul de resurse în timpul execuției.

👍 Sfat: Rulați codul pe 200 de înregistrări într-un sandbox înainte de implementare. Majoritatea erorilor de limitare a guvernatorului apar doar la volumul în bloc, iar detectarea lor din timp este mult mai ieftină decât depanarea lor în producție.

Întrebări frecvente

Nu. Apex împrumută Java-asemănătoare sintaxei, dar nu ține cont de majuscule/minuscule, rulează doar pe platforma Salesforce Lightning, integrează SOQL direct în limbaj și este guvernată de limite per tranzacție care Java nu are.

Înregistrați-vă pentru o organizație gratuită Salesforce Developer Edition, care include Developer Console și urmați exerciții practice pe Cap de traseu, platforma oficială de învățare de la Salesforce.

Visualforce este un limbaj de marcare pentru construirea paginilor de interfață utilizator, în timp ce Apex este limbajul server-side care furnizează logica din spatele acestora. Paginile Visualforce apelează adesea la clasele de controler Apex pentru a interoga și actualiza datele.

Da. Agentforce pentru dezvoltatori, asistentul AI de la Salesforce pentru Visual Studio Code, generează și explică Apex din solicitări în limbaj natural. Revizuiți și testați întotdeauna codul generat de inteligența artificială în raport cu limitele guvernatorului înainte de implementare.

Clasele Apex marcate cu adnotarea @InvocableMethod pot fi expuse ca acțiuni personalizate, permițând boților Einstein și agenților Agentforce să apeleze logica dvs. de business, în timp ce Apex poate invoca, de asemenea, șabloane de prompturi Einstein și modele de inteligență artificială prin intermediul API-urilor platformei.

Rezumați această postare cu: