APEX Tutorial: Apex Programare curs și Exemple de Codificare

Ce este Apex în Salesforce?

Apex este un limbaj de programare orientat pe obiecte și puternic tastat dezvoltat de Salesforce pentru construirea Software-ului ca serviciu (SaaS) și managementul relațiilor cu clienții (CRM). Apex ajută dezvoltatorii să creeze aplicații SaaS terțe și să adauge logica de afaceri la evenimentele de sistem, oferind suport pentru baze de date back-end și interfețe client-server., Apex ajută dezvoltatorii să adauge logica de afaceri la evenimentele din sistem, cum ar fi clicurile pe butoane, actualizările de înregistrări asociate și paginile Visualforce. Apex are o sintaxă similară cu Java.

În acest tutorial pentru începători Salesforce Apex, veți învăța elementele de bază Apex cum ar fi –

  • ce este Apex?,ge
  • atunci Când ar Trebui să Producător Alege Apex
  • Structură de Lucru De Apex
  • Apex Sintaxa
  • Apex Mediu de Dezvoltare
  • Tipul de Date în Apex
  • Apex Specificator de Acces
  • cuvinte Cheie în Apex
  • Apex String
  • Apex Guvernatorul Limite
  • Apex Getter și Setter
  • Apex Clasa
  • Apex Declanșa
  • Lot de Clasă în Apex

Caracteristici de Apex Limbaj de Programare

Aici sunt cele mai importante caracteristici ale Salesforce Apex:

  • Apex este un caz insensibil limba.,
  • puteți efectua operații DML precum inserare, actualizare, UPSERT, ștergere pe înregistrările 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 să le executați pentru a verifica acoperirea codului și eficiența codului în apex.
  • Apex execută într-un mediu multi-chiriaș, iar Salesforce a definit anumite limite ale guvernatorului care împiedică un utilizator să controleze resursele partajate., Orice cod care traversează limita guvernatorului salesforce eșuează, apare o eroare.
  • obiectul Salesforce poate fi folosit ca tip de date în apex. De exemplu –
    Account acc = new Account(); 

    , aici Contul este un obiect standard salesforce.

  • Apex actualizează automat cu fiecare lansare Salesforce.

când trebuie să aleagă dezvoltatorul Apex

Codul Apex trebuie scris numai dacă un scenariu de afaceri este prea complex și nu poate fi implementat folosind funcționalitatea pre-construită furnizată de Salesforce.,

următoarele sunt câteva scenarii în care trebuie să scriem apex code:

  • pentru a crea servicii web care integrează Salesforce cu alte aplicații.
  • pentru a implementa validarea personalizată pe sobjects.
  • pentru a executa logica apex personalizată atunci când se efectuează o operație DML.
  • pentru a implementa funcționalități care nu pot fi implementate utilizând fluxurile de lucru existente și funcționalitatea constructorilor de procese.
  • pentru a configura serviciile de e-mail, trebuie să includeți procesarea conținutului, anteturilor și atașamentelor de e-mail folosind codul apex.,

Structură de Lucru De Apex

Acum, în acest Apex tutorial, vom învăța despre structura de lucru de Apex:

sunt Următoarele fluxul de acțiuni pentru un apex cod:

  • Producător de Acțiune: Toate apex codul scris de un producător este compilat într-un set de instrucțiuni care pot fi înțelese de către apex runtime interpret atunci când dezvoltatorul salvează codul de la platforma și aceste instrucțiuni apoi salvați ca metadate pentru platforma.,
  • acțiune utilizator final: când evenimentul utilizator execută un cod apex, serverul platformei primește instrucțiunile compilate din metadate și le rulează prin interpretul apex înainte de a returna rezultatul.

Structură de Lucru De Apex

Apex Sintaxa

Declarație de variabilă:

Ca apex este limbaj puternic tipizat, este obligatoriu să se declare o variabilă cu tip de date în apex.,

de exemplu

contact con = new contact(); 

aici variabila con este declarată cu contact ca tip de date.

SOQL Query:

SOQL standuri pentru salesforce obiect query language. SOQL este folosit pentru a prelua înregistrările sObject din Baza de date Salesforce. De exemplu –

Account acc = ; 

interogarea de mai sus preia înregistrarea Contului din Baza de date salesforce.

buclă declarație:

buclă declarație este folosit 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:

în fragmentul de cod de mai sus, listOfAccounts este o variabilă a tipului de date al listei.

Flow Control Statement:

Flow control statement este benefic atunci când doriți să execute unele linii de cod bazate pe anumite condiții.

de exemplu:

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

declarație DML:

DML standuri pentru limbajul de manipulare a datelor. Declarațiile 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.

Apex Mediu de Dezvoltare

Acum, în acest Apex tutorial de programare, vom învăța despre Apex Mediu de Dezvoltare:

Apex cod poate fi elaborat fie în sandbox și developer edition de Salesforce. este o bună practică să dezvolți codul în mediul sandbox și apoi să îl implementezi în mediul de producție.

Apex instrumente de dezvoltare cod: Următoarele sunt cele trei instrumente disponibile pentru a dezvolta apex cod în toate edițiile de Salesforce.,

  • Force.com Consola pentru Dezvoltatori
  • Force.com IDE
  • Editor de Cod în Salesforce Utilizator InterfaceYou

Tip de Date în Apex

sunt Următoarele tipuri de date acceptate de apex:

Primitiv:

Integer, Double, Timp, Data, Data, String, ID, și Boolean sunt considerate a fi 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

  • Lista: este o colecție ordonată de primitivi, sObjects, colecții, sau Apex obiecte bazate pe indici.
  • Set: o colecție neordonată de primitive unice.
  • hartă: este o colecție de chei unice, primitive, care mapează la valori unice care pot fi primitive, sObjects, colecții sau obiecte Apex.

sObject:

acesta este un tip special de date în Salesforce. Este similar cu un tabel în SQL și conține câmpuri care sunt similare cu coloanele din SQL.,

Enum

Enumerare este un tip abstract de date care stochează o valoare de un set finit de specificat identificatori

Cursuri

Obiecte :

Se referă la orice tip de date care este susținută în Apex.

interfețe

Apex access Specifier

următoarele sunt specificatorul de acces acceptat de apex:

Public:

acest specificator de acces oferă acces la o clasă, metodă, variabilă care trebuie utilizată de un apex într-un spațiu de nume.,

privat:

acest specificator de acces oferă acces la o clasă, metodă, variabilă care va fi utilizată local sau în secțiunea de cod, este definită. Toate tehnica, variabilele care nu au nici un specificator de acces definit au specificatorul de acces implicit privat.

protejat:

acest specificator de acces oferă acces la o metodă, variabilă pentru a fi utilizată de orice clase interioare din cadrul definirii clasei Apex.,

Global:

acest specificator de acces oferă acces la o clasă, metodă, variabilă pentru a fi utilizată de un vârf într-un spațiu de nume, precum și în afara spațiului de nume. Este o bună practică să nu folosiți cuvinte cheie globale până când este necesar.

cuvinte cheie în Apex

cu partajare:

dacă o clasă este definită cu acest cuvânt cheie, atunci toate regulile de partajare se aplică utilizatorului curent și dacă acest cuvânt cheie este absent, atunci codul se execută în contextul sistemului.,

de exemplu:

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

fără partajare:

dacă o clasă este definită cu acest cuvânt cheie, atunci toate regulile de partajare se aplică utilizatorului curent nu este aplicată.

de exemplu:

public without sharing class MyApexClass{// sharing rules is not enforced when code in this class execute}

Static:

o variabilă, metoda este definită cu cuvântul cheie static este inițializată o dată și asociată cu clasa. Variabile statice, metodele pot fi apelate direct după numele clasei fără a crea instanța unei clase.

Final:

o constantă, metoda este definită cu cuvântul cheie final nu poate fi înlocuită., De exemplu:

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

Dacă încercați să suprascrieți valoarea pentru această variabilă INT_CONST, atunci veți obține un sistem de excepție.FinalException: variabila finală a fost deja inițializată.

Return:

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 un cuvânt cheie virtual, aceasta poate fi extinsă și înlocuită.,

rezumat:

dacă o clasă este definită cu cuvânt cheie abstract, aceasta trebuie să conțină cel puțin o metodă cu cuvânt cheie abstract, iar acea metodă trebuie să aibă doar o semnătură.

de exemplu:

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

Apex String

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

String name = 'Test';

Există mai multe construit în-metode oferă de clasa String în salesforce., Următoarele sunt câteva frecvent și mai utilizate funcții:

abrevierea(maxWidth):

Această metodă trunchiază un șir de caractere de lungime specificată și returnează dacă lungimea șirul dat este mai apoi lungimea specificată; în caz contrar, returnează șirul original. Dacă valoarea pentru variabila maxWidth este mai mică de 4, această metodă returnează un sistem de excepție runtime.StringException: Minim abreviere lățime este de 4

De exemplu:

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

valorifica():

Această metodă transformă prima literă a unui șir de caractere pentru titlu caz și se întoarce.,

De exemplu:

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

conține(subșir):

Această metodă returnează adevărat dacă Șirul de asteptare metodă conține subșir specificat.

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

este egal cu(stringOrId):

Această metodă returnează true dacă parametrul trecut nu este nulă și indică aceeași secvență binară de caractere ca șir de caractere care este de asteptare metoda.

în timp ce comparăm valorile Id, lungimea ID-ului poate să nu fie egală., De exemplu: dacă un șir care reprezintă 15 caractere id este comparat cu un obiect care reprezintă 18 caractere ID această metodă returnează true. De exemplu:

în exemplul de mai sus metoda egals compară 15 caractere object Id cu 18 caractere object Id și dacă ambele aceste id reprezintă aceeași secvență binară se va întoarce true. utilizați această metodă pentru a face comparații sensibile la litere mari și mici.

escapeSingleQuotes(stringToEscape):

Această metodă adaugă un caracter escape (\) înainte de orice un singur citat într-un șir și returnează., Această metodă previne injectarea SOQL în timp ce crearea unei interogări SOQL dinamic. Această metodă asigură că toate ghilimelele unice sunt considerate ca șiruri de închidere, în loc de comenzile bazei de date.

De exemplu:

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

remove(subșir):

Această metodă elimină toate apariție a menționat subșir din Șir care solicită metodă și se întoarce șirul rezultat.,

de exemplu:

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

substring(startIndex):

această metodă returnează un substring pornește de la caracterul de la startIndex se extinde la ultimul șir.

de exemplu:

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

reverse():

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

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

trim(): această metodă elimină toate spațiile albe principale dintr-un șir și o returnează.

valueOf (toConvert):

această metodă returnează reprezentarea șir a trecut în obiect.,

Apex Guvernatorul Limitele

Apex guvernatorul limite sunt limitele impuse de apex motor de execuție pentru a se asigura că orice pistă apex codul de procese și nu de a controla resursele partajate și nu încalcă prelucrare pentru alți utilizatori de pe multitenant mediu. Aceste limite sunt verificate pentru fiecare tranzacție apex., Următoarele sunt guvernatorul limitele definite de salesforce pe fiecare apex tranzacție:

Descriere Limita
SOQL interogări care poate fi făcut într-un sincron de tranzacție 100
SOQL interogări care poate fi făcut într-un Asincrone tranzacție 200
Înregistrări care pot fi preluate de către un SOQL interogare 50000
Înregistrări care pot fi preluate de Date.,getQueryLocator 10000
SOSL interogări care poate fi făcut într-un vârf de tranzacție 20
Înregistrări care pot fi preluate de către un SOSL interogare 2000
DML declarații care poate fi făcut într-un vârf de tranzacție 150
Înregistrări care pot fi prelucrate ca urmare a unei DML, Aprobare.proces sau bază de date.emptyRecycleBin 10000
explicații care se poate face într-o tranzacție apex., 100
limita de expirare cumulativă pe toate explicațiile care sunt efectuate într-o tranzacție apex 120 secunde
limita de locuri de muncă apex care pot fi adăugate la coada cu sistem.,enqueueJob 50
Execution time limit for each Apex transaction 10 minutes
Limit on characters that can be used in an apex class and trigger 1 million
CPU time limit for synchronous transaction 10,000 milliseconds
CPU time limit for asynchronous transaction 60,000 milliseconds

Apex Getter and Setter

Apex property is similar to apex variable. Getter and setter are necessary to an apex property., Getter și setter pot fi folosite pentru a executa codul înainte ca valoarea proprietății să fie accesată sau modificată. Codul din get accessor se execută atunci când se citește o valoare de proprietate. Codul din accesoriul setat rulează atunci când o valoare a proprietății este modificată. Orice proprietate care are Accessor get este considerată read-only, orice proprietate care are set accessor este considerată a scrie numai orice proprietate care are atât get, cât și set accessor este considerată a fi read-write. Sintaxa unei proprietăți apex:

public class myApexClass {// Property declarationaccess_modifierreturn_typeproperty_name {get {//code }set{//code}}

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

mai jos este un exemplu de proprietate apex având atât get și set accessor.

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

aici, numele de proprietate este nume, și este proprietate publică, și se întoarce un șir de datatype.

nu este obligatoriu să aveți un cod în blocul get și set. Aceste bloc pot fi lăsate goale pentru a defini o proprietate automată. De exemplu:

public double MyReadWriteProp{ get; set; } 

Get and set accessor poate fi, de asemenea, definit cu modificatorul lor de acces., Dacă un Accesor este definit cu un modificator, atunci acesta înlocuiește modificatorul de acces pentru proprietate. De exemplu:

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

clasa Apex

o clasă apex este un plan sau un șablon din care sunt create obiecte. Un obiect este instanța unei clase. există trei moduri de a crea clase apex în Salesforce:

Consola pentru dezvoltatori

Force.com IDE

Apex pagina de detaliu clasa.

în apex, puteți defini o clasă exterioară numită și clasă de nivel superior și puteți defini, de asemenea, clase într-o clasă exterioară numită clase interioare.,

este obligatoriu să utilizați modificatorul de acces CA global sau public în declarația clasei exterioare.

nu este necesar să utilizați modificatorul de acces în declarația claselor interioare.

o clasă apex este definită folosind cuvântul cheie clasă urmat de numele clasei.

extinde cuvântul cheie este utilizat pentru a extinde o clasă existentă printr-o clasă apex și implementează cuvântul cheie este utilizat pentru a implementa o interfață printr-o clasă apex.

Salesforce Apex nu acceptă moșteniri multiple, o clasă apex poate extinde doar o clasă apex existentă, dar poate implementa mai multe interfețe.,

o clasă apex poate conține 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 clasei Apex exemplu:

public class myApexClass{// variable declaration//constructorpublic myApexClass{}//methods declaration}

noul cuvânt cheie este folosit 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 Trigger

Apex triggers vă permite să executați apex personalizat înainte și după o operație DML este efectuată., suport Apex următoarele două tipuri de declanșatoare:

înainte de declanșatoare: aceste declanșatoare sunt utilizate pentru a valida și actualiza valoarea câmpului înainte de a salva înregistrarea în baza de date.

după declanșatoare: aceste declanșatoare sunt utilizate pentru a accesa câmpurile(ID înregistrare, câmpul LastModifiedDate) stabilite de sistem după o înregistrare angajată în baza de date. Valoarea acestor câmpuri poate fi utilizată pentru a modifica alte înregistrări. Înregistrările care incendii după declanșatoare sunt read-only.

este cea mai bună practică de a scrie declanșatoare voluminoase. Un declanșator voluminos poate procesa o singură înregistrare, precum și mai multe înregistrări simultan.,

Sintaxa de un apex de declanșare:

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

Aici, TriggerName este numele pe trăgaci, ObjectName este numele obiectului pe care declanșator pentru a fi scris, trigger_events este o listă separată prin virgulă de evenimente.

următoarele sunt evenimentele susținute de declanșatoarele apex: înainte de inserare, înainte de actualizare, înainte de ștergere, după inserare, după o actualizare, după ștergere, după anulare.

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

există variabile implicite definesc de fiecare declanșator care returnează contextul run-time. Aceste variabile sunt definite în sistem. Clasa de declanșare. Aceste variabile sunt numite variabile de context. Imaginea de mai jos prezintă variabila context acceptată de Apex trigger.

sunt Următoarele luarea în considerare a contextului variabilă în vârful de declanșare:

  • nu folosi pe trăgaci.nou și declanșator.vechi în operațiunile DML.
  • declanșator.noul nu poate fi șters.,
  • declanșator.noul este doar pentru citire.
  • declanșator.nou poate fi folosit pentru a modifica valorile câmpurilor de pe același obiect înainte de declanșare numai.

mai jos screenshots lista considerațiile despre acțiuni specifice în diferite evenimente de declanșare.

Lot de Clasă în Apex

Lot de clasă în salesforce este utilizat pentru a procesa un număr mare de înregistrări care ar depăși apex guvernatorul limite dacă prelucrate în mod normal. Clasa lot execută codul asincron.,

următoarele sunt avantajele clasei batch:

  • clasa Batch procesează datele în bucăți și dacă o bucată nu reușește să proceseze cu succes, toate bucățile procesate cu succes nu se rostogolesc înapoi.
  • fiecare bucată de date într-o clasă de lot prelucrate cu un nou set de limite guvernator care asigură că codul execută în limitele de execuție guvernator.
  • baza de date. Interfața Batchable trebuie implementată de o clasă apex pentru a fi utilizată ca clasă batch. Acesta oferă trei metode care trebuie să fie puse în aplicare de către clasa lot.,

următoarele sunt cele trei metode furnizate de baza de date. Interfață Batchable:

1.start ():

această metodă generează domeniul de aplicare al înregistrărilor sau obiectelor care urmează să fie procesate de metoda interface execute. În timpul executării lotului, se numește o singură dată. Această metodă returnează fie o bază de date.Obiect QueryLocator sau un Iterabil. Numărul de înregistrări preluate de interogare SQL folosind baza de date.Obiectul QueryLocator este de 50 de milioane de înregistrări, dar folosind un iterabil, numărul total de înregistrări care pot fi preluate de interogarea SQL este de numai 50000., Iterable este utilizat pentru a genera un domeniu complex pentru clasa batch.

sintaxa metodei de pornire:

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

2.execute ():

această metodă este utilizată pentru prelucrarea fiecărei bucăți de date. Pentru fiecare bucată de înregistrări executa metoda este numit. Dimensiunea implicită a lotului pentru execuție este de 200 de înregistrări. Executa metoda are două argumente:

o referință la baza de date.BatchableContext obiect,

O listă de sObjects, cum ar fi Lista<sObject>, sau o listă de tipuri parametrizate., Sintaxa metodei de executare:

global void execute(Database.BatchableContext BC, list<P>){}

3.finish ():

metoda finish se numește o dată în timpul executării clasei batch. Operațiunile de Post-procesare pot fi efectuate în metoda de finisare. De exemplu: trimiterea e-mailului de confirmare. Această metodă se numește atunci când tot lotul se procesează. Sintaxa metodei de finisare:

global void finish(Database.BatchableContext BC){}

baza de date.BatchableContext object:

Fiecare metodă a bazei de date. Interfața Batchable are o referință la baza de date.Obiect BatchableContext.

acest obiect este folosit pentru a urmări progresul lucrării lot.,

sunt Următoarele exemplu metode oferite de BatchableContext :

  • getChildJobId(): Această metodă returnează ID-ul de locuri de muncă lot, care este în prezent procesate.
  • getJobId(): această metodă returnează ID-ul lotului de locuri de muncă.

mai jos este sintaxa unei clase de lot :

baza de date.metoda executeBatch:

baza de date.metoda executeBatch este utilizat pentru executarea unei clase de lot.

această metodă are doi parametri: instanță a clasei de lot care urmează să fie procesate, parametru de opțiuni pentru a specifica dimensiunea lotului, dacă nu este specificat este nevoie de dimensiunea implicită de 200.,

sintaxa bazei de date.executeBatch :

Database.executeBatch(myBatchObject,scope)

de Executare un lot nume de clasă MyBatchClass :

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

baza de Date.stateful:

clasa lot este apatrid în mod implicit. De fiecare dată când metoda de executare se numește o nouă copie a unui obiect este primit, toate variabilele clasei este inițializată.

baza de date.stateful este implementat pentru a face o clasă de lot stateful.

dacă clasa batch implementat baza de date, interfață stateful toate variabila instanță păstrează valorile lor, dar variabilele statice obține resetat între tranzacție.,

Rezumat:

  • Apex este un puternic tastat, orientat-obiect limbaj de programare care compilează și rula pe force.com platforma
  • Apex limbaj de programare este un caz insensibil limba
  • Două tipuri de flux de acțiuni în Apex sunt: 1) Producător de acțiune 2) utilizatorul Final de acțiune
  • Apex vă ajută să vă pentru a crea servicii web care se integrează Salesforce cu alte aplicații.
  • tipurile de date acceptate de apex sunt: 1).,ublic, privat, protejat și Global sunt specificate suport de Apex
  • cuvinte cheie folosind în Apex sunt : 1) cu Partajare, 2) fără partajare, 3) Static, 4) Final 5)întoarcere, 6)Null, 7) Virtual, 8) Abstract
  • un șir este un set de caractere fără limite de caractere
  • limitele guvernatorului Apex sunt limitele impuse de apex runtime engine pentru a se asigura că orice valoarea este accesată sau modificată
  • există trei moduri de a crea clase Apex în Salesforce: 1)consola pentru dezvoltatori 2)forță.,com IDE și, 3) Pagina de detaliu clasa Apex.
  • Apex triggers vă permite să executați apex personalizat înainte și după efectuarea unei operații DML.
  • clasa lot în salesforce este utilizat pentru a procesa un număr mare de înregistrări care ar depăși limitele Apex guvernator dacă prelucrate în mod normal.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *