Apex - Panduan Cepat

Apa itu Apex?

Apex adalah bahasa kepemilikan yang dikembangkan oleh Salesforce.com. Sesuai definisi resminya, Apex adalah bahasa pemrograman berorientasi objek yang diketik dengan kuat yang memungkinkan pengembang untuk mengeksekusi aliran dan pernyataan kontrol transaksi di server platform Force.com dalam hubungannya dengan panggilan ke API Force.com.

Ini memiliki sintaks seperti Java dan bertindak seperti prosedur yang disimpan database. Ini memungkinkan pengembang untuk menambahkan logika bisnis ke sebagian besar peristiwa sistem, termasuk klik tombol, pembaruan catatan terkait, dan Visualforcepages.Apexkode dapat dimulai oleh permintaan layanan Web dan dari pemicu pada objek. Apex disertakan dalam Edisi Kinerja, Edisi Tak Terbatas, Edisi Perusahaan, dan Edisi Pengembang.

Fitur Apex sebagai Bahasa

Sekarang mari kita bahas fitur Apex sebagai Bahasa -

Terintegrasi

Apex telah membangun dukungan untuk operasi DML seperti INSERT, UPDATE, DELETE dan juga penanganan DML Exception. Ini memiliki dukungan untuk SOQL dan penanganan kueri SOSL sebaris yang mengembalikan kumpulan catatan sObject. Kami akan mempelajari sObject, SOQL, SOSL secara rinci di bab-bab selanjutnya.

Java menyukai sintaks dan mudah digunakan

Apex mudah digunakan karena menggunakan sintaks seperti Java. Misalnya, deklarasi variabel, sintaks loop, dan pernyataan bersyarat.

Sangat Terintegrasi Dengan Data

Apex adalah data yang difokuskan dan dirancang untuk menjalankan beberapa kueri dan pernyataan DML secara bersamaan. Ini mengeluarkan beberapa pernyataan transaksi pada Database.

Sangat Diketik

Apex adalah bahasa yang diketik dengan kuat. Ini menggunakan referensi langsung ke objek skema seperti sObject dan referensi yang tidak valid dengan cepat gagal jika dihapus atau jika tipe datanya salah.

Lingkungan Multitenant

Apex berjalan di lingkungan multitenant. Akibatnya, mesin runtime Apex dirancang untuk melindungi dari kode runaway, mencegahnya memonopoli sumber daya bersama. Kode apa pun yang melanggar batas gagal dengan pesan kesalahan yang mudah dipahami.

Meningkatkan Secara Otomatis

Apex ditingkatkan sebagai bagian dari rilis Salesforce. Kami tidak harus meningkatkannya secara manual.

Pengujian Mudah

Apex menyediakan dukungan bawaan untuk pembuatan dan eksekusi pengujian unit, termasuk hasil pengujian yang menunjukkan seberapa banyak kode yang dicakup, dan bagian mana dari kode Anda yang bisa lebih efisien.

Kapan Pengembang Harus Memilih Apex?

Apex harus digunakan ketika kita tidak dapat mengimplementasikan fungsionalitas bisnis yang kompleks menggunakan fungsionalitas yang sudah ada dan sudah ada sebelumnya. Di bawah ini adalah kasus di mana kami perlu menggunakan apex di atas konfigurasi Salesforce.

Aplikasi Apex

Kita dapat menggunakan Apex saat kita ingin -

  • Buat layanan Web dengan mengintegrasikan sistem lain.

  • Buat layanan email untuk ledakan email atau penyiapan email.

  • Lakukan validasi kompleks pada beberapa objek secara bersamaan dan juga implementasi validasi kustom.

  • Buat proses bisnis kompleks yang tidak didukung oleh fungsionalitas atau alur alur kerja yang sudah ada.

  • Buat logika transaksional kustom (logika yang terjadi di seluruh transaksi, tidak hanya dengan satu record atau objek) seperti menggunakan metode Database untuk mengupdate record.

  • Lakukan beberapa logika saat rekaman diubah atau modifikasi rekaman objek terkait saat ada beberapa peristiwa yang menyebabkan pemicu diaktifkan.

Struktur Kerja Apex

Seperti yang ditunjukkan pada diagram di bawah ini (Referensi: Dokumentasi Pengembang Salesforce), Apex berjalan sepenuhnya di platform demand Force.com

Alur Tindakan

Ada dua urutan tindakan ketika pengembang menyimpan kode dan ketika pengguna akhir melakukan beberapa tindakan yang memanggil kode Apex seperti yang ditunjukkan di bawah ini -

Tindakan Pengembang

Saat pengembang menulis dan menyimpan kode Apex ke platform, server aplikasi platform pertama-tama mengompilasi kode ke dalam satu set instruksi yang dapat dipahami oleh juru bahasa runtime Apex, dan kemudian menyimpan instruksi tersebut sebagai metadata.

Tindakan Pengguna Akhir

Ketika pengguna akhir memicu eksekusi Apex, dengan mengklik tombol atau mengakses halaman Visualforce, server aplikasi platform mengambil instruksi yang dikompilasi dari metadata dan mengirimkannya melalui penafsir waktu proses sebelum mengembalikan hasilnya. Pengguna akhir mengamati tidak ada perbedaan dalam waktu eksekusi dibandingkan dengan permintaan platform aplikasi standar.

Karena Apex adalah bahasa kepemilikan Salesforce.com, Apex tidak mendukung beberapa fitur yang didukung oleh bahasa pemrograman umum. Berikut adalah beberapa fitur yang tidak didukung Apex -

  • Itu tidak dapat menampilkan elemen di Antarmuka Pengguna.

  • Anda tidak dapat mengubah fungsionalitas yang disediakan SFDC standar dan juga tidak mungkin untuk mencegah eksekusi fungsionalitas standar.

  • Membuat banyak utas juga tidak dimungkinkan karena kami dapat melakukannya dalam bahasa lain.

Memahami Sintaks Apex

Kode Apex biasanya berisi banyak hal yang mungkin kita kenal dari bahasa pemrograman lain.

Deklarasi Variabel

Sebagai bahasa yang diketik dengan kuat, Anda harus mendeklarasikan setiap variabel dengan tipe data di Apex. Seperti yang terlihat pada kode di bawah ini (gambar di bawah), lstAcc dideklarasikan dengan tipe data sebagai Daftar Akun.

Kueri SOQL

Ini akan digunakan untuk mengambil data dari database Salesforce. Kueri yang ditampilkan pada tangkapan layar di bawah ini mengambil data dari objek Akun.

Pernyataan Loop

Pernyataan loop ini digunakan untuk iterasi atas daftar atau iterasi atas sepotong kode untuk jumlah waktu tertentu. Dalam kode yang ditunjukkan pada gambar di bawah, iterasi akan sama dengan jumlah catatan yang kita miliki.

Pernyataan Kontrol Aliran

Pernyataan If digunakan untuk kontrol aliran dalam kode ini. Berdasarkan kondisi tertentu, diputuskan apakah akan melakukan eksekusi atau menghentikan eksekusi bagian kode tertentu. Misalnya, dalam kode yang ditunjukkan di bawah ini, ini memeriksa apakah daftar kosong atau berisi catatan.

Pernyataan DML

Melakukan operasi penyisipan, pembaruan, upert, hapus catatan pada catatan dalam database. Misalnya, kode yang diberikan di bawah ini membantu dalam memperbarui Akun dengan nilai bidang baru.

Berikut adalah contoh bagaimana cuplikan kode Apex akan terlihat. Kita akan mempelajari semua konsep pemrograman Apex ini lebih lanjut dalam tutorial ini.

Dalam bab ini, kita akan memahami lingkungan untuk pengembangan Salesforce Apex kita. Diasumsikan bahwa Anda sudah menyiapkan edisi Salesforce untuk melakukan pengembangan Apex.

Anda dapat mengembangkan kode Apex di Sandbox atau edisi Pengembang Salesforce. Organisasi Sandbox adalah salinan dari organisasi Anda tempat Anda dapat menulis kode dan mengujinya tanpa mengambil risiko modifikasi data atau mengganggu fungsi normal. Sesuai dengan praktik industri standar, Anda harus mengembangkan kode di Sandbox dan kemudian menerapkannya ke lingkungan Produksi.

Untuk tutorial ini, kami akan menggunakan Salesforce edisi Pengembang. Dalam edisi Pengembang, Anda tidak akan memiliki opsi untuk membuat organisasi Sandbox. Fitur Sandbox tersedia di edisi Salesforce lainnya.

Alat Pengembangan Kode Apex

Di semua edisi, kita dapat menggunakan salah satu dari tiga alat berikut untuk mengembangkan kode -

  • Konsol Pengembang Force.com
  • Force.com IDE
  • Editor Kode di Antarmuka Pengguna Salesforce

Note − Kami akan menggunakan Konsol Pengembang sepanjang tutorial kami untuk eksekusi kode karena sederhana dan ramah pengguna untuk belajar.

Konsol Pengembang Force.com

Konsol Pengembang adalah lingkungan pengembangan terintegrasi dengan sekumpulan alat yang dapat Anda gunakan untuk membuat, men-debug, dan menguji aplikasi di organisasi Salesforce Anda.

Ikuti langkah-langkah ini untuk membuka Konsol Pengembang -

Step 1 − Buka Nama → Konsol Pengembang

Step 2 − Klik pada "Konsol Pengembang" dan sebuah jendela akan muncul seperti pada tangkapan layar berikut.

Berikut adalah beberapa operasi yang dapat dilakukan menggunakan Konsol Pengembang.

  • Writing and compiling code −Anda dapat menulis kode menggunakan editor kode sumber. Saat Anda menyimpan pemicu atau kelas, kode dikompilasi secara otomatis. Setiap kesalahan kompilasi akan dilaporkan.

  • Debugging −Anda dapat menulis kode menggunakan editor kode sumber. Saat Anda menyimpan pemicu atau kelas, kode dikompilasi secara otomatis. Setiap kesalahan kompilasi akan dilaporkan.

  • Testing − Anda dapat melihat log debug dan mengatur checkpoint yang membantu dalam proses debug.

  • Checking performance −Anda dapat menjalankan pengujian kelas pengujian tertentu atau semua kelas di organisasi Anda, dan Anda dapat melihat hasil pengujian. Selain itu, Anda dapat memeriksa cakupan kode.

  • SOQL queries − Anda dapat memeriksa log debug untuk menemukan kemacetan kinerja.

  • Color coding and autocomplete − Editor kode sumber menggunakan skema warna agar elemen kode lebih mudah dibaca dan menyediakan pelengkapan otomatis untuk nama kelas dan metode.

Kode Pelaksana di Konsol Pengembang

Semua cuplikan kode yang disebutkan dalam tutorial ini harus dijalankan di konsol pengembang. Ikuti langkah-langkah berikut untuk menjalankan langkah-langkah di Konsol Pengembang.

Step 1 - Masuk ke Salesforce.com menggunakan login.salesforce.com. Salin cuplikan kode yang disebutkan dalam tutorial. Untuk saat ini, kami akan menggunakan kode contoh berikut.

String myString = 'MyString';
System.debug('Value of String Variable'+myString);

Step 2 - Untuk membuka Developer Console, klik Name → Developer Console lalu klik Execute Anonymous seperti yang ditunjukkan di bawah ini.

Step 3 - Pada langkah ini, sebuah jendela akan muncul dan Anda dapat menempelkan kode di sana.

Step 4 - Saat kami mengklik Execute, log debug akan terbuka. Setelah log masuk muncul di jendela seperti gambar di bawah ini, kemudian klik catatan log.

Kemudian ketik 'USER' di jendela seperti yang ditunjukkan di bawah ini dan pernyataan keluaran akan muncul di jendela debug. Pernyataan 'USER' ini digunakan untuk memfilter keluaran.

Jadi pada dasarnya, Anda akan mengikuti semua langkah yang disebutkan di atas untuk menjalankan potongan kode apa pun dalam tutorial ini.

Contoh Pengembangan Aplikasi Perusahaan

Untuk tutorial kami, kami akan menerapkan aplikasi CRM untuk Peralatan Kimia dan Perusahaan Pengolahan. Perusahaan ini berurusan dengan pemasok dan menyediakan layanan. Kami akan mengerjakan potongan kode kecil yang terkait dengan contoh ini di seluruh tutorial kami untuk memahami setiap konsep secara detail.

Untuk menjalankan kode dalam tutorial ini, Anda perlu membuat dua objek: objek Pelanggan dan Faktur. Jika Anda sudah mengetahui cara membuat objek ini di Salesforce, Anda dapat melewati langkah-langkah yang diberikan di bawah ini. Lain, Anda dapat mengikuti panduan langkah demi langkah di bawah ini.

Membuat Objek Pelanggan

Kami akan menyiapkan objek Pelanggan terlebih dahulu.

Step 1- Pergi ke Setup dan kemudian cari 'Object' seperti yang ditunjukkan di bawah ini. Kemudian klik tautan Objek seperti yang ditunjukkan di bawah ini.

Step 2 - Setelah halaman objek dibuka, lalu klik 'Create New Object'seperti yang ditunjukkan di bawah ini.

Step 3- Setelah mengklik tombol, halaman pembuatan objek baru akan muncul dan kemudian masukkan semua detail objek seperti yang dimasukkan di bawah ini. Nama objek harus Pelanggan. Anda hanya perlu memasukkan informasi di lapangan seperti yang ditunjukkan pada gambar di bawah dan menyimpan hal-hal default lainnya apa adanya.

Masukkan informasi dan kemudian klik tombol 'Simpan' -

Dengan mengikuti langkah-langkah di atas, kami telah berhasil membuat objek Pelanggan.

Membuat Bidang Kustom untuk objek Pelanggan

Sekarang setelah objek Pelanggan kami siap, kami akan membuat bidang 'Aktif' dan kemudian Anda dapat membuat bidang lain dengan mengikuti langkah serupa. Nama bidang dan API akan diberikan di tangkapan layar.

Step 1- Kami akan membuat bidang bernama 'Aktif' tipe data sebagai Kotak Centang. Pergi ke Setup dan klik di atasnya.

Step 2 - Cari 'Objek' seperti yang ditunjukkan di bawah ini dan klik di atasnya.

Step 3 - Klik pada objek 'Pelanggan'.

Step 4 - Setelah Anda mengklik tautan objek Pelanggan dan laman detail objek muncul, klik tombol Baru.

Step 5 - Sekarang, pilih tipe data sebagai Kotak Centang dan klik Berikutnya.

Step 6 - Masukkan nama bidang dan label seperti yang ditunjukkan di bawah ini.

Step 7 - Klik Terlihat lalu klik Berikutnya.

Step 8 - Sekarang klik 'Simpan'.

Dengan mengikuti langkah-langkah di atas, bidang khusus 'Aktif' kami dibuat. Anda harus mengikuti semua langkah pembuatan bidang kustom di atas untuk bidang yang tersisa. Ini adalah tampilan akhir dari objek pelanggan setelah semua bidang dibuat -

Membuat Objek Faktur

Step 1 - Pergi ke Setup dan cari 'Object' dan kemudian klik pada link Objects seperti yang ditunjukkan di bawah ini.

Step 2 - Setelah halaman objek dibuka, lalu klik tombol 'Buat Objek Baru' seperti gambar di bawah ini.

Step 3- Setelah mengklik tombol, halaman pembuatan objek baru akan muncul seperti yang ditunjukkan pada gambar di bawah. Anda perlu memasukkan detailnya di sini. Nama objek harus Faktur. Ini mirip dengan cara kami membuat objek Pelanggan sebelumnya di tutorial ini.

Step 4 - Masukkan informasi seperti yang ditunjukkan di bawah ini dan kemudian klik tombol 'Simpan'.

Dengan mengikuti langkah-langkah ini, objek Faktur Anda akan dibuat.

Membuat Bidang Kustom untuk objek Faktur

Kami akan membuat Deskripsi bidang pada objek Faktur seperti yang ditunjukkan di bawah ini -

Step 1 - Buka Pengaturan dan klik di atasnya.

Step 2 - Cari 'Objek' seperti yang ditunjukkan di bawah ini dan klik di atasnya.

Step 3 - Klik pada objek 'Faktur'.

Dan kemudian klik 'Baru'.

Step 4 - Pilih tipe data sebagai Area Teks dan kemudian klik tombol Berikutnya.

Step 5 - Masukkan informasi seperti yang diberikan di bawah ini.

Step 6 - Klik Terlihat lalu Berikutnya.

Step 7 - Klik Simpan.

Demikian pula, Anda dapat membuat bidang lain pada objek Faktur.

Dengan ini, kami telah membuat objek yang dibutuhkan untuk tutorial ini. Kita akan mempelajari berbagai contoh di bab-bab selanjutnya berdasarkan objek-objek ini.

Memahami Tipe Data

Bahasa Apex sangat diketik sehingga setiap variabel di Apex akan dideklarasikan dengan tipe data tertentu. Semua variabel apex diinisialisasi ke nol pada awalnya. Itu selalu disarankan bagi pengembang untuk memastikan bahwa nilai yang tepat diberikan ke variabel. Jika tidak, variabel seperti itu saat digunakan, akan menampilkan pengecualian penunjuk nol atau pengecualian yang tidak tertangani.

Apex mendukung tipe data berikut -

  • Primitive (Integer, Double, Long, Date, Datetime, String, ID, atau Boolean)

  • Koleksi (Daftar, Set dan Peta) (Akan dibahas di Bab 6)

  • sObject

  • Enums

  • Kelas, Objek dan Antarmuka (Akan dibahas dalam Bab 11, 12 dan 13)

Dalam bab ini, kita akan melihat semua Tipe Data Primitif, sObjects dan Enums. Kita akan melihat Koleksi, Kelas, Objek, dan Antarmuka di bab-bab selanjutnya karena itu adalah topik utama yang harus dipelajari secara individu.

Tipe Data Primitif

Di bagian ini, kita akan membahas Tipe Data Primitif yang didukung oleh Apex.

Bilangan bulat

Angka 32-bit yang tidak menyertakan titik desimal apa pun. Kisaran nilai untuk ini mulai dari -2.147.483.648 dan nilai maksimum hingga 2.147.483.647.

Example

Kami ingin mendeklarasikan variabel yang akan menyimpan jumlah barel yang perlu dikirim ke pembeli pabrik pengolahan kimia.

Integer barrelNumbers = 1000;
system.debug(' value of barrelNumbers variable: '+barrelNumbers);

Itu System.debug() fungsi mencetak nilai variabel sehingga kita dapat menggunakan ini untuk debug atau untuk mengetahui nilai variabel saat ini.

Tempel kode di atas ke konsol Pengembang dan klik Jalankan. Setelah log dibuat, maka itu akan menunjukkan nilai variabel "barrelNumbers" sebagai 1000.

Boolean

Variabel ini bisa benar, salah atau nol. Sering kali, jenis variabel ini dapat digunakan sebagai tanda dalam pemrograman untuk mengidentifikasi apakah kondisi tertentu disetel atau tidak disetel.

Example

Jika Boolean shippingDispatched disetel sebagai true, maka itu dapat dideklarasikan sebagai -

Boolean shipmentDispatched;
shipmentDispatched = true;
System.debug('Value of shipmentDispatched '+shipmentDispatched);

Tanggal

Jenis variabel ini menunjukkan tanggal. Ini hanya dapat menyimpan tanggal dan bukan waktu. Untuk menyimpan tanggal bersama dengan waktu, kita perlu menyimpannya dalam variabel DateTime.

Example

Pertimbangkan contoh berikut untuk memahami cara kerja variabel Tanggal.

//ShipmentDate can be stored when shipment is dispatched.
Date ShipmentDate = date.today();
System.debug('ShipmentDate '+ShipmentDate);

Panjang

Ini adalah angka 64-bit tanpa titik desimal. Ini digunakan ketika kita membutuhkan rentang nilai yang lebih luas daripada yang disediakan oleh Integer.

Example

Jika pendapatan perusahaan ingin disimpan, maka kita akan menggunakan tipe data sebagai Long.

Long companyRevenue = 21474838973344648L;
system.debug('companyRevenue'+companyRevenue);

Obyek

Kami dapat merujuk ini sebagai tipe data apa pun yang didukung di Apex. Misalnya, variabel Kelas dapat menjadi objek dari kelas itu, dan tipe umum sObject juga merupakan objek dan tipe objek yang sama spesifiknya seperti Akun juga merupakan Objek.

Example

Pertimbangkan contoh berikut untuk memahami cara kerja variabel objek.

Account objAccount = new Account (Name = 'Test Chemical');
system.debug('Account value'+objAccount);

Note - Anda juga dapat membuat objek dari kelas yang telah ditentukan, seperti yang diberikan di bawah ini -

//Class Name: MyApexClass
MyApexClass classObj = new MyApexClass();

Ini adalah objek kelas yang akan digunakan sebagai variabel kelas.

Tali

String adalah kumpulan karakter apa pun dalam tanda kutip tunggal. Itu tidak memiliki batasan jumlah karakter. Di sini, ukuran heap akan digunakan untuk menentukan jumlah karakter. Hal ini membatasi monopoli sumber daya oleh program Apex dan juga memastikan bahwa program tersebut tidak menjadi terlalu besar.

Example

String companyName = 'Abc International';
System.debug('Value companyName variable'+companyName);

Waktu

Variabel ini digunakan untuk menyimpan waktu tertentu. Variabel ini harus selalu dideklarasikan dengan metode statis sistem.

Gumpal

Blob adalah kumpulan data Biner yang disimpan sebagai objek. Ini akan digunakan saat kita ingin menyimpan lampiran di tenaga penjualan menjadi variabel. Tipe data ini mengubah lampiran menjadi satu objek. Jika blob akan diubah menjadi string, maka kita dapat menggunakan metode toString dan valueOf untuk hal yang sama.

sObject

Ini adalah tipe data khusus di Salesforce. Ini mirip dengan tabel di SQL dan berisi bidang yang mirip dengan kolom di SQL. Ada dua jenis sObjects - Standar dan Kustom.

Misalnya, Akun adalah sObject standar dan objek yang ditentukan pengguna lainnya (seperti objek Pelanggan yang kami buat) adalah sObject Kustom.

Example

//Declaring an sObject variable of type Account
Account objAccount = new Account();

//Assignment of values to fields of sObjects
objAccount.Name = 'ABC Customer';
objAccount.Description = 'Test Account';
System.debug('objAccount variable value'+objAccount);

//Declaring an sObject for custom object APEX_Invoice_c
APEX_Customer_c objCustomer = new APEX_Customer_c();

//Assigning value to fields
objCustomer.APEX_Customer_Decscription_c = 'Test Customer';
System.debug('value objCustomer'+objCustomer);

Enum

Enum adalah tipe data abstrak yang menyimpan satu nilai dari satu set pengenal tertentu yang terbatas. Anda dapat menggunakan kata kunci Enum untuk mendefinisikan Enum. Enum dapat digunakan sebagai tipe data lainnya di Salesforce.

Example

Anda dapat menyatakan kemungkinan nama Senyawa Kimia dengan menjalankan kode berikut -

//Declaring enum for Chemical Compounds
public enum Compounds {HCL, H2SO4, NACL, HG}
Compounds objC = Compounds.HCL;
System.debug('objC value: '+objC);

Java dan Apex serupa dalam banyak hal. Deklarasi variabel di Java dan Apex juga hampir sama. Kami akan membahas beberapa contoh untuk memahami cara mendeklarasikan variabel lokal.

String productName = 'HCL';
Integer i = 0;
Set<string> setOfProducts = new Set<string>();
Map<id, string> mapOfProductIdToName = new Map<id, string>();

Perhatikan bahwa semua variabel diberi nilai null.

Declaring Variables

Anda dapat mendeklarasikan variabel di Apex seperti String dan Integer sebagai berikut -

String strName = 'My String';  //String variable declaration
Integer myInteger = 1;         //Integer variable declaration
Boolean mtBoolean = true;      //Boolean variable declaration

Apex variables are Case-Insensitive

Ini berarti bahwa kode yang diberikan di bawah ini akan memberikan kesalahan karena variabel 'm' telah dideklarasikan dua kali dan keduanya akan diperlakukan sama.

Integer m = 100;
for (Integer i = 0; i<10; i++) {
   integer m = 1; //This statement will throw an error as m is being declared
   again
   System.debug('This code will throw error');
}

Scope of Variables

Variabel Apex valid dari titik di mana ia dideklarasikan dalam kode. Jadi tidak diperbolehkan untuk mendefinisikan kembali variabel yang sama dan dalam blok kode. Selain itu, jika Anda mendeklarasikan variabel apa pun dalam suatu metode, cakupan variabel itu akan dibatasi hanya untuk metode tertentu itu. Namun, variabel kelas dapat diakses di seluruh kelas.

Example

//Declare variable Products
List<string> Products = new List<strings>();
Products.add('HCL');

//You cannot declare this variable in this code clock or sub code block again
//If you do so then it will throw the error as the previous variable in scope
//Below statement will throw error if declared in same code block
List<string> Products = new List<strings>();

String di Apex, seperti dalam bahasa pemrograman lainnya, adalah kumpulan karakter apa pun tanpa batas karakter.

Example

String companyName = 'Abc International';
System.debug('Value companyName variable'+companyName);

Metode String

Kelas string di Salesforce memiliki banyak metode. Kita akan melihat beberapa metode string yang paling penting dan sering digunakan dalam bab ini.

mengandung

Metode ini akan mengembalikan nilai true jika string yang diberikan berisi substring yang disebutkan.

Syntax

public Boolean contains(String substring)

Example

String myProductName1 = 'HCL';
String myProductName2 = 'NAHCL';
Boolean result = myProductName2.contains(myProductName1);
System.debug('O/p will be true as it contains the String and Output is:'+result);

sama

Metode ini akan mengembalikan nilai true jika string yang diberikan dan string yang diteruskan dalam metode memiliki urutan karakter biner yang sama dan bukan null. Anda juga dapat membandingkan ID catatan SFDC menggunakan metode ini. Metode ini peka huruf besar / kecil.

Syntax

public Boolean equals(Object string)

Example

String myString1 = 'MyString';
String myString2 = 'MyString';
Boolean result = myString2.equals(myString1);
System.debug('Value of Result will be true as they are same and Result is:'+result);

equalsIgnoreCase

Metode ini akan mengembalikan nilai true jika stringtoCompare memiliki urutan karakter yang sama dengan string yang diberikan. Namun, metode ini tidak peka huruf besar / kecil.

Syntax

public Boolean equalsIgnoreCase(String stringtoCompare)

Example

Kode berikut akan mengembalikan nilai true karena karakter string dan urutannya sama, mengabaikan sensitivitas huruf besar / kecil.

String myString1 = 'MySTRING';
String myString2 = 'MyString';
Boolean result = myString2.equalsIgnoreCase(myString1);
System.debug('Value of Result will be true as they are same and Result is:'+result);

menghapus

Metode ini menghapus string yang disediakan dalam stringToRemove dari string yang diberikan. Ini berguna ketika Anda ingin menghapus beberapa karakter tertentu dari string dan tidak mengetahui indeks pasti dari karakter yang akan dihapus. Metode ini peka huruf besar / kecil dan tidak akan berfungsi jika urutan karakter yang sama terjadi, tetapi huruf besar / kecil berbeda.

Syntax

public String remove(String stringToRemove)

Example

String myString1 = 'This Is MyString Example';
String stringToRemove = 'MyString';
String result = myString1.remove(stringToRemove);
System.debug('Value of Result will be 'This Is Example' as we have removed the MyString 
   and Result is :'+result);

removeEndIgnoreCase

Metode ini menghapus string yang disediakan dalam stringToRemove dari string yang diberikan, tetapi hanya jika terjadi di bagian akhir. Metode ini tidak peka huruf besar-kecil.

Syntax

public String removeEndIgnoreCase(String stringToRemove)

Example

String myString1 = 'This Is MyString EXAMPLE';
String stringToRemove = 'Example';
String result = myString1.removeEndIgnoreCase(stringToRemove);
System.debug('Value of Result will be 'This Is MyString' as we have removed the 'Example'
   and Result is :'+result);

dimulai dengan

Metode ini akan mengembalikan nilai true jika string yang diberikan dimulai dengan prefiks yang diberikan dalam metode.

Syntax

public Boolean startsWith(String prefix)

Example

String myString1 = 'This Is MyString EXAMPLE';
String prefix = 'This';
Boolean result = myString1.startsWith(prefix);
System.debug(' This will return true as our String starts with string 'This' and the 
   Result is :'+result);

Array di Apex pada dasarnya sama dengan List di Apex. Tidak ada perbedaan logis antara Array dan Daftar karena struktur dan metode data internal mereka juga sama tetapi sintaks array sedikit tradisional seperti Java.

Di bawah ini adalah representasi dari Array of Products -

Index 0 - HCL

Index 1 - H2SO4

Index 2 - NACL

Index 3 - H2O

Index 4 - N2

Index 5 - U296

Sintaksis

<String> [] arrayOfProducts = new List<String>();

Contoh

Misalkan, kita harus menyimpan nama Produk kita - kita bisa menggunakan Array di mana kita akan menyimpan Nama Produk seperti yang ditunjukkan di bawah ini. Anda dapat mengakses Produk tertentu dengan menentukan indeks.

//Defining array
String [] arrayOfProducts = new List<String>();

//Adding elements in Array
arrayOfProducts.add('HCL');
arrayOfProducts.add('H2SO4');
arrayOfProducts.add('NACL');
arrayOfProducts.add('H2O');
arrayOfProducts.add('N2');
arrayOfProducts.add('U296');

for (Integer i = 0; i<arrayOfProducts.size(); i++) {
   //This loop will print all the elements in array
   system.debug('Values In Array: '+arrayOfProducts[i]);
}

Mengakses elemen array dengan menggunakan index

Anda dapat mengakses elemen apa pun dalam array dengan menggunakan indeks seperti yang ditunjukkan di bawah ini -

//Accessing the element in array
//We would access the element at Index 3
System.debug('Value at Index 3 is :'+arrayOfProducts[3]);

Seperti dalam bahasa pemrograman lainnya, Konstanta adalah variabel yang tidak berubah nilainya setelah dideklarasikan atau diberi nilai.

Di Apex, Konstanta digunakan saat kita ingin mendefinisikan variabel yang harus memiliki nilai konstan selama eksekusi program. Konstanta puncak dideklarasikan dengan kata kunci 'final'.

Contoh

Pertimbangkan a CustomerOperationClass kelas dan variabel konstan regularCustomerDiscount di dalamnya -

public class CustomerOperationClass {
   static final Double regularCustomerDiscount = 0.1;
   static Double finalPrice = 0;
   
   public static Double provideDiscount (Integer price) {
      //calculate the discount
      finalPrice = price - price * regularCustomerDiscount;
      return finalPrice;
   }
}

Untuk melihat Output dari kelas di atas, Anda harus menjalankan kode berikut di Jendela Anonim Konsol Pengembang -

Double finalPrice = CustomerOperationClass.provideDiscount(100);
System.debug('finalPrice '+finalPrice);

Struktur pengambilan keputusan mengharuskan programmer menentukan satu atau lebih kondisi untuk dievaluasi atau diuji oleh program, bersama dengan pernyataan atau pernyataan yang akan dieksekusi jika kondisi ditentukan benar, dan secara opsional, pernyataan lain akan dieksekusi jika kondisi ditentukan sebagai salah.

Dalam bab ini, kita akan mempelajari struktur dasar dan lanjutan dari pengambilan keputusan dan pernyataan bersyarat di Apex. Pengambilan keputusan diperlukan untuk mengontrol aliran eksekusi ketika kondisi tertentu terpenuhi atau tidak. Berikut ini adalah bentuk umum dari struktur pengambilan keputusan yang ditemukan di sebagian besar bahasa pemrograman

Sr.No. Pernyataan & Deskripsi
1 jika pernyataan

Pernyataan if terdiri dari ekspresi Boolean yang diikuti oleh satu atau beberapa pernyataan.

2 jika ... pernyataan lain

Pernyataan if dapat diikuti dengan opsional else pernyataan, yang dijalankan ketika ekspresi Boolean salah.

3 jika ... elseif ... pernyataan lain

Pernyataan if dapat diikuti dengan opsional else if...else pernyataan, yang sangat berguna untuk menguji berbagai kondisi menggunakan pernyataan if ... else if tunggal.

4 pernyataan if bersarang

Anda bisa menggunakannya if or else if pernyataan di dalam yang lain if or else if pernyataan.

Loop digunakan ketika potongan kode tertentu harus diulang dengan jumlah iterasi yang diinginkan. Apex mendukung loop tradisional standar serta jenis Loop lanjutan lainnya. Pada bab ini, kita akan membahas secara detail tentang Loops in Apex.

Pernyataan loop memungkinkan kita untuk mengeksekusi pernyataan atau sekelompok pernyataan beberapa kali dan berikut adalah pernyataan umum dari loop di sebagian besar bahasa pemrograman -

Tabel berikut mencantumkan Loop berbeda yang menangani persyaratan perulangan dalam bahasa Pemrograman Apex. Klik tautan berikut untuk memeriksa detailnya.

Sr.No. Jenis & Deskripsi Loop
1 untuk loop

Loop ini melakukan satu set pernyataan untuk setiap item dalam satu set record.

2 SOQL untuk loop

Jalankan urutan pernyataan langsung di atas set kueri SOQL yang dikembalikan.

3 For loop seperti Java

Jalankan urutan pernyataan dalam sintaks mirip Java tradisional.

4 while loop

Mengulangi pernyataan atau sekelompok pernyataan saat kondisi tertentu benar. Ini menguji kondisi sebelum menjalankan badan perulangan.

5 lakukan ... while loop

Seperti pernyataan while, bedanya pernyataan itu menguji kondisi di akhir badan perulangan.

Koleksi adalah jenis variabel yang dapat menyimpan beberapa record. Misalnya, Daftar dapat menyimpan beberapa catatan objek Akun. Sekarang mari kita memiliki gambaran umum mendetail dari semua jenis koleksi.

Daftar

Daftar dapat berisi sejumlah catatan primitif, koleksi, sObjects, yang ditentukan pengguna dan dibangun dalam tipe Apex. Ini adalah salah satu jenis koleksi terpenting dan juga, memiliki beberapa metode sistem yang telah disesuaikan secara khusus untuk digunakan dengan List. Indeks daftar selalu dimulai dengan 0. Ini identik dengan larik di Jawa. Sebuah daftar harus dideklarasikan dengan kata kunci 'Daftar'.

Example

Di bawah ini adalah list yang berisi List dari tipe data primitive (string), yaitu list kota.

List<string> ListOfCities = new List<string>();
System.debug('Value Of ListOfCities'+ListOfCities);

Mendeklarasikan nilai awal list adalah opsional. Namun, kami akan mendeklarasikan nilai awal di sini. Berikut adalah contoh yang menunjukkan hal yang sama.

List<string> ListOfStates = new List<string> {'NY', 'LA', 'LV'};
System.debug('Value ListOfStates'+ListOfStates);

Daftar Akun (sObject)

List<account> AccountToDelete = new List<account> (); //This will be null
System.debug('Value AccountToDelete'+AccountToDelete);

Kami juga dapat mendeklarasikan Daftar bersarang. Itu bisa naik hingga lima level. Ini disebut daftar Multidimensi.

Ini adalah daftar kumpulan bilangan bulat.

List<List<Set<Integer>>> myNestedList = new List<List<Set<Integer>>>();
System.debug('value myNestedList'+myNestedList);

Daftar dapat berisi sejumlah catatan, tetapi ada batasan pada ukuran tumpukan untuk mencegah masalah kinerja dan memonopoli sumber daya.

Metode untuk Daftar

Ada metode yang tersedia untuk Daftar yang dapat kita gunakan saat memprogram untuk mencapai beberapa fungsi seperti menghitung ukuran Daftar, menambahkan elemen, dll.

Berikut adalah beberapa metode yang paling sering digunakan -

  • size()
  • add()
  • get()
  • clear()
  • set()

Contoh berikut menunjukkan penggunaan semua metode ini

// Initialize the List
List<string> ListOfStatesMethod = new List<string>();

// This statement would give null as output in Debug logs
System.debug('Value of List'+ ListOfStatesMethod);

// Add element to the list using add method
ListOfStatesMethod.add('New York');
ListOfStatesMethod.add('Ohio');

// This statement would give New York and Ohio as output in Debug logs
System.debug('Value of List with new States'+ ListOfStatesMethod);

// Get the element at the index 0
String StateAtFirstPosition = ListOfStatesMethod.get(0);

// This statement would give New York as output in Debug log
System.debug('Value of List at First Position'+ StateAtFirstPosition);

// set the element at 1 position
ListOfStatesMethod.set(0, 'LA');

// This statement would give output in Debug log
System.debug('Value of List with element set at First Position' + ListOfStatesMethod[0]);

// Remove all the elements in List
ListOfStatesMethod.clear();

// This statement would give output in Debug log
System.debug('Value of List'+ ListOfStatesMethod);

Anda dapat menggunakan notasi array juga untuk mendeklarasikan List, seperti yang diberikan di bawah ini, tetapi ini bukan praktik umum dalam pemrograman Apex -

String [] ListOfStates = new List<string>();

Set

Set adalah jenis koleksi yang berisi beberapa catatan unik tak berurutan. Kumpulan tidak dapat memiliki rekaman duplikat. Seperti Daftar, Kumpulan dapat disarangkan.

Example

Kami akan menentukan rangkaian produk yang dijual oleh perusahaan.

Set<string> ProductSet = new Set<string>{'Phenol', 'Benzene', 'H2SO4'};
System.debug('Value of ProductSet'+ProductSet);

Metode untuk Set

Set tidak mendukung metode yang dapat kita gunakan saat memprogram seperti yang ditunjukkan di bawah ini (kami memperluas contoh di atas) -

// Adds an element to the set
// Define set if not defined previously
Set<string> ProductSet = new Set<string>{'Phenol', 'Benzene', 'H2SO4'};
ProductSet.add('HCL');
System.debug('Set with New Value '+ProductSet);

// Removes an element from set
ProductSet.remove('HCL');
System.debug('Set with removed value '+ProductSet);

// Check whether set contains the particular element or not and returns true or false
ProductSet.contains('HCL');
System.debug('Value of Set with all values '+ProductSet);

Maps

Ini adalah pasangan nilai kunci yang berisi kunci unik untuk setiap nilai. Baik kunci maupun nilai bisa dari tipe data apa pun.

Example

Contoh berikut mewakili peta Nama Produk dengan kode Produk.

// Initialize the Map
Map<string, string> ProductCodeToProductName = new Map<string, string>
{'1000'=>'HCL', '1001'=>'H2SO4'};

// This statement would give as output as key value pair in Debug log
System.debug('value of ProductCodeToProductName'+ProductCodeToProductName);

Metode untuk Maps

Berikut adalah beberapa contoh yang menunjukkan metode yang dapat digunakan dengan Map -

// Define a new map
Map<string, string> ProductCodeToProductName = new Map<string, string>();

// Insert a new key-value pair in the map where '1002' is key and 'Acetone' is value
ProductCodeToProductName.put('1002', 'Acetone');

// Insert a new key-value pair in the map where '1003' is key and 'Ketone' is value
ProductCodeToProductName.put('1003', 'Ketone');

// Assert that the map contains a specified key and respective value
System.assert(ProductCodeToProductName.containsKey('1002'));
System.debug('If output is true then Map contains the key and output is:'
   + ProductCodeToProductName.containsKey('1002'));

// Retrieves a value, given a particular key
String value = ProductCodeToProductName.get('1002');
System.debug('Value at the Specified key using get function: '+value);

// Return a set that contains all of the keys in the map
Set SetOfKeys = ProductCodeToProductName.keySet();
System.debug('Value of Set with Keys '+SetOfKeys);

Nilai peta mungkin tidak berurutan dan karenanya kita tidak boleh bergantung pada urutan penyimpanan nilai dan mencoba mengakses peta selalu menggunakan kunci. Nilai peta bisa nol. Kunci peta ketika menyatakan String peka huruf besar kecil; misalnya, ABC dan abc akan dianggap sebagai kunci yang berbeda dan diperlakukan sebagai unik.

Apa itu Kelas?

Kelas adalah templat atau cetak biru tempat objek dibuat. Objek adalah turunan dari kelas. Ini adalah definisi standar Kelas. Kelas Apex mirip dengan Kelas Java.

Sebagai contoh, InvoiceProcessorkelas menjelaskan kelas yang memiliki semua metode dan tindakan yang dapat dilakukan pada Faktur. Jika Anda membuat instance dari kelas ini, maka itu akan mewakili satu faktur yang saat ini ada dalam konteks.

Membuat Kelas

Anda dapat membuat kelas di Apex dari Konsol Pengembang, Force.com Eclipse IDE, dan dari halaman detail Kelas Apex juga.

Dari Konsol Pengembang

Ikuti langkah-langkah ini untuk membuat kelas Apex dari Konsol Pengembang -

Step 1 - Buka Nama dan klik Konsol Pengembang.

Step 2 - Klik File ⇒ New lalu klik kelas Apex.

Dari Force.com IDE

Ikuti langkah-langkah berikut untuk membuat kelas dari Force.com IDE -

Step 1 - Buka Force.com Eclipse IDE

Step 2 - Buat Proyek Baru dengan mengklik File ⇒ New ⇒ Apex Class.

Step 3 - Berikan Nama untuk Kelas dan klik OK.

Setelah ini selesai, kelas baru akan dibuat.

Dari Halaman Detail Kelas Apex

Ikuti langkah-langkah ini untuk membuat kelas dari Apex Class Detail Page -

Step 1 - Klik pada Name ⇒ Setup.

Step 2- Cari 'Apex Class' dan klik tautannya. Ini akan membuka halaman detail Apex Class.

Step 3 - Klik 'Baru', lalu berikan Nama kelas, lalu klik Simpan.

Struktur Kelas Puncak

Di bawah ini adalah contoh struktur untuk definisi kelas Apex.

Syntax

private | public | global
[virtual | abstract | with sharing | without sharing]
class ClassName [implements InterfaceNameList] [extends ClassName] {
   // Classs Body
}

Definisi ini menggunakan kombinasi pengubah akses, mode berbagi, nama kelas dan badan kelas. Kami akan melihat semua opsi ini lebih lanjut.

Example

Berikut adalah contoh struktur untuk definisi kelas Apex -

public class MySampleApexClass {       //Class definition and body
   public static Integer myValue = 0;  //Class Member variable
   public static String myString = ''; //Class Member variable
   
   public static Integer getCalculatedValue () {
   // Method definition and body
   // do some calculation
      myValue = myValue+10;
      return myValue;
   }
}

Pengubah Akses

Pribadi

Jika Anda mendeklarasikan pengubah akses sebagai 'Private', maka kelas ini hanya akan dikenal secara lokal dan Anda tidak dapat mengakses kelas ini di luar bagian tersebut. Secara default, kelas memiliki pengubah ini.

Publik

Jika Anda mendeklarasikan kelas sebagai 'Publik' maka ini berarti bahwa kelas ini dapat diakses oleh organisasi Anda dan namespace yang Anda tentukan. Biasanya, sebagian besar kelas Apex ditentukan dengan kata kunci ini.

Global

Jika Anda mendeklarasikan kelas sebagai 'global' maka ini akan dapat diakses oleh semua kode apex terlepas dari organisasi Anda. Jika Anda memiliki metode yang ditentukan dengan kata kunci layanan web, maka Anda harus mendeklarasikan kelas yang mengandung dengan kata kunci global.

Mode Berbagi

Sekarang mari kita bahas berbagai mode berbagi.

Dengan Berbagi

Ini adalah fitur khusus Kelas Apex di Salesforce. Ketika sebuah kelas ditentukan dengan kata kunci 'Dengan Berbagi' maka itu memiliki implikasi sebagai berikut: Ketika kelas akan dijalankan, itu akan menghormati pengaturan akses Pengguna dan izin profil. Misalkan, tindakan Pengguna telah memicu pembaruan catatan untuk 30 catatan, tetapi pengguna hanya memiliki akses ke 20 catatan dan 10 catatan tidak dapat diakses. Kemudian, jika kelas melakukan tindakan untuk memperbarui catatan, hanya 20 catatan akan diperbarui yang pengguna memiliki akses dan sisa 10 catatan tidak akan diperbarui. Ini juga disebut sebagai mode Pengguna.

Tanpa Berbagi

Meskipun Pengguna tidak memiliki akses ke 10 dari 30 catatan, semua 30 catatan akan diperbarui saat Kelas berjalan dalam mode Sistem, yaitu, telah ditentukan dengan kata kunci Tanpa Berbagi. Ini disebut Mode Sistem.

Virtual

Jika Anda menggunakan kata kunci 'virtual', ini menunjukkan bahwa kelas ini dapat diperpanjang dan diganti diizinkan. Jika metode perlu diganti, maka kelas harus dideklarasikan dengan kata kunci virtual.

Abstrak

Jika Anda mendeklarasikan kelas sebagai 'abstrak', maka itu hanya akan berisi tanda tangan metode dan bukan implementasi yang sebenarnya.

Variabel Kelas

Syntax

[public | private | protected | global] [final] [static] data_type
variable_name [= value]

Dalam sintaks di atas -

  • Jenis data variabel dan nama variabel wajib diisi
  • Pengubah dan nilai akses bersifat opsional.

Example

public static final Integer myvalue;

Metode Kelas

Ada dua pengubah untuk Metode Kelas di Apex - Publik atau Dilindungi. Jenis pengembalian wajib untuk metode dan jika metode tidak mengembalikan apa pun maka Anda harus menyebutkan void sebagai jenis pengembalian. Selain itu, Tubuh juga diperlukan untuk metode.

Syntax

[public | private | protected | global]
[override]
[static]

return_data_type method_name (input parameters) {
   // Method body goes here
}

Penjelasan Sintaks

Parameter yang disebutkan dalam tanda kurung siku adalah opsional. Namun, komponen berikut ini penting -

  • return_data_type
  • method_name

Pengubah Akses untuk Metode Kelas

Menggunakan pengubah akses, Anda dapat menentukan tingkat akses untuk metode kelas. Misalnya, metode Publik akan dapat diakses dari mana saja di dalam kelas dan di luar Kelas. Metode pribadi hanya dapat diakses di dalam kelas. Global akan dapat diakses oleh semua kelas Apex dan dapat diekspos sebagai metode layanan web yang dapat diakses oleh kelas apex lainnya.

Example

//Method definition and body
public static Integer getCalculatedValue () {
   
   //do some calculation
   myValue = myValue+10;
   return myValue;
}

Metode ini memiliki tipe kembalian sebagai Integer dan tidak mengambil parameter.

Metode A dapat memiliki parameter seperti yang ditunjukkan pada contoh berikut -

// Method definition and body, this method takes parameter price which will then be used 
// in method.

public static Integer getCalculatedValueViaPrice (Decimal price) {
   // do some calculation
   myValue = myValue+price;
   return myValue;
}

Konstruktor Kelas

Konstruktor adalah kode yang dipanggil ketika sebuah objek dibuat dari cetak biru kelas. Ini memiliki nama yang sama dengan nama kelas.

Kita tidak perlu mendefinisikan konstruktor untuk setiap kelas, karena secara default konstruktor tanpa argumen dipanggil. Konstruktor berguna untuk inisialisasi variabel atau ketika suatu proses akan dilakukan pada saat inisialisasi kelas. Misalnya, Anda ingin menetapkan nilai ke variabel Integer tertentu sebagai 0 saat kelas dipanggil.

Example

// Class definition and body
public class MySampleApexClass2 {
   public static Double myValue;   // Class Member variable
   public static String myString;  // Class Member variable

   public MySampleApexClass2 () {
      myValue = 100; //initialized variable when class is called
   }

   public static Double getCalculatedValue () { // Method definition and body
      // do some calculation
      myValue = myValue+10;
      return myValue;
   }

   public static Double getCalculatedValueViaPrice (Decimal price) {
      // Method definition and body
      // do some calculation
      myValue = myValue+price; // Final Price would be 100+100=200.00
      return myValue;
   }
}

Anda juga dapat memanggil metode kelas melalui konstruktor. Ini mungkin berguna saat memprogram Apex untuk pengontrol gaya visual. Ketika objek kelas dibuat, maka konstruktor dipanggil seperti yang ditunjukkan di bawah ini -

// Class and constructor has been instantiated
MySampleApexClass2 objClass = new MySampleApexClass2();
Double FinalPrice = MySampleApexClass2.getCalculatedValueViaPrice(100);
System.debug('FinalPrice: '+FinalPrice);

Konstruktor Kelebihan Beban

Konstruktor dapat kelebihan beban, yaitu kelas dapat memiliki lebih dari satu konstruktor yang ditentukan dengan parameter berbeda.

Example

public class MySampleApexClass3 {  // Class definition and body
   public static Double myValue;   // Class Member variable
   public static String myString;  // Class Member variable

   public MySampleApexClass3 () {
      myValue = 100; // initialized variable when class is called
      System.debug('myValue variable with no Overaloading'+myValue);
   }

   public MySampleApexClass3 (Integer newPrice) { // Overloaded constructor
      myValue = newPrice; // initialized variable when class is called
      System.debug('myValue variable with Overaloading'+myValue);
   }

      public static Double getCalculatedValue () { // Method definition and body
      // do some calculation
      myValue = myValue+10;
      return myValue;
   }

   public static Double getCalculatedValueViaPrice (Decimal price) {
      // Method definition and body
      // do some calculation
      myValue = myValue+price;
      return myValue;
   }
}

Anda dapat menjalankan kelas ini seperti yang telah kami jalankan di contoh sebelumnya.

// Developer Console Code
MySampleApexClass3 objClass = new MySampleApexClass3();
Double FinalPrice = MySampleApexClass3.getCalculatedValueViaPrice(100);
System.debug('FinalPrice: '+FinalPrice);

Sebuah instance dari kelas disebut Object. Dalam hal Salesforce, objek dapat berupa kelas atau Anda juga dapat membuat objek sObject.

Pembuatan Objek dari Kelas

Anda dapat membuat objek kelas seperti yang mungkin Anda lakukan di Java atau bahasa pemrograman berorientasi objek lainnya.

Berikut adalah contoh Class yang disebut MyClass -

// Sample Class Example
public class MyClass {
   Integer myInteger = 10;
   
   public void myMethod (Integer multiplier) {
      Integer multiplicationResult;
      multiplicationResult = multiplier*myInteger;
      System.debug('Multiplication is '+multiplicationResult);
   }
}

Ini adalah kelas instance, yaitu, untuk memanggil atau mengakses variabel atau metode kelas ini, Anda harus membuat instance kelas ini dan kemudian Anda dapat melakukan semua operasi.

// Object Creation
// Creating an object of class
MyClass objClass = new MyClass();

// Calling Class method using Class instance
objClass.myMethod(100);

sObject penciptaan

sObjects adalah objek Salesforce tempat Anda menyimpan data. Misalnya, Akun, Kontak, dll., Adalah objek khusus. Anda dapat membuat instance objek dari sObjects ini.

Berikut adalah contoh inisialisasi sObject dan menunjukkan bagaimana Anda dapat mengakses bidang objek tertentu menggunakan notasi titik dan menetapkan nilai ke bidang.

// Execute the below code in Developer console by simply pasting it
// Standard Object Initialization for Account sObject
Account objAccount = new Account(); // Object initialization
objAccount.Name = 'Testr Account'; // Assigning the value to field Name of Account
objAccount.Description = 'Test Account';
insert objAccount; // Creating record using DML
System.debug('Records Has been created '+objAccount);

// Custom sObject initialization and assignment of values to field
APEX_Customer_c objCustomer = new APEX_Customer_c ();
objCustomer.Name = 'ABC Customer';
objCustomer.APEX_Customer_Decscription_c = 'Test Description';
insert objCustomer;
System.debug('Records Has been created '+objCustomer);

Inisialisasi Statis

Metode dan variabel statis diinisialisasi hanya sekali ketika kelas dimuat. Variabel statis tidak dikirim sebagai bagian dari status tampilan untuk halaman Visualforce.

Berikut adalah contoh metode Statis serta variabel Statis.

// Sample Class Example with Static Method
public class MyStaticClass {
   Static Integer myInteger = 10;
   
   public static void myMethod (Integer multiplier) {
      Integer multiplicationResult;
      multiplicationResult = multiplier * myInteger;
      System.debug('Multiplication is '+multiplicationResult);
   }
}

// Calling the Class Method using Class Name and not using the instance object
MyStaticClass.myMethod(100);

Static Variable Use

Variabel statis akan dibuat instance-nya hanya sekali ketika kelas dimuat dan fenomena ini dapat digunakan untuk menghindari rekursi pemicu. Nilai variabel statis akan sama dalam konteks eksekusi yang sama dan semua kelas, pemicu, atau kode yang dijalankan dapat merujuknya dan mencegah rekursi.

Antarmuka seperti kelas Apex di mana tidak ada metode yang telah diterapkan. Ini hanya berisi tanda tangan metode, tetapi isi setiap metode kosong. Untuk menggunakan antarmuka, kelas lain harus mengimplementasikannya dengan menyediakan isi untuk semua metode yang terdapat dalam antarmuka.

Antarmuka digunakan terutama untuk menyediakan lapisan abstraksi untuk kode Anda. Mereka memisahkan implementasi dari deklarasi metode.

Mari kita ambil contoh Perusahaan Kimia kita. Misalkan kita perlu memberikan diskon kepada pelanggan Premium dan Biasa dan diskon untuk keduanya akan berbeda.

Kami akan membuat Antarmuka yang disebut DiscountProcessor.

// Interface
public interface DiscountProcessor {
   Double percentageDiscountTobeApplied(); // method signature only
}

// Premium Customer Class
public class PremiumCustomer implements DiscountProcessor {
   
   //Method Call
   public Double percentageDiscountTobeApplied () {
      
      // For Premium customer, discount should be 30%
      return 0.30;
   }
}

// Normal Customer Class
public class NormalCustomer implements DiscountProcessor {
   
   // Method Call
   public Double percentageDiscountTobeApplied () {
      
      // For Premium customer, discount should be 10%
      return 0.10;
   }
}

Ketika Anda mengimplementasikan Antarmuka, maka wajib untuk mengimplementasikan metode Antarmuka itu. Jika Anda tidak mengimplementasikan metode Antarmuka, itu akan memunculkan kesalahan. Anda harus menggunakan Interfaces saat Anda ingin membuat penerapan metode wajib bagi pengembang.

Antarmuka Salesforce Standar untuk Batch Apex

SFDC memang memiliki antarmuka standar seperti Database.Batchable, Schedulable, dll. Misalnya, jika Anda mengimplementasikan Database.Batchable Interface, Anda harus menerapkan tiga metode yang ditentukan dalam Antarmuka - Mulai, Jalankan, dan Selesai.

Di bawah ini adalah contoh untuk Database yang disediakan oleh Salesforce Standar. Antarmuka Batchable yang mengirimkan email ke pengguna dengan Status Batch. Antarmuka ini memiliki 3 metode, Mulai, Jalankan, dan Selesai. Dengan menggunakan antarmuka ini, kita dapat mengimplementasikan fungsionalitas Batchable dan juga menyediakan variabel BatchableContext yang dapat kita gunakan untuk mendapatkan lebih banyak informasi tentang Batch yang sedang dijalankan dan untuk melakukan fungsi lainnya.

global class CustomerProessingBatch implements Database.Batchable<sobject7>,
Schedulable {
   // Add here your email address
   global String [] email = new String[] {'[email protected]'};

   // Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      
      // This is the Query which will determine the scope of Records and fetching the same
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
         APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
         && APEX_Active__c = true');
   }

   // Execute method
   global void execute (Database.BatchableContext BC, List<sobject> scope) {
      List<apex_customer__c> customerList = new List<apex_customer__c>();
      List<apex_customer__c> updtaedCustomerList = new List<apex_customer__c>();
      
      for (sObject objScope: scope) {
         // type casting from generic sOject to APEX_Customer__c
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         
         // Add records to the List
         updtaedCustomerList.add(newObjScope);
      }

      // Check if List is empty or not
      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
         
         // Update the Records
         Database.update(updtaedCustomerList); System.debug('List Size
            '+updtaedCustomerList.size());
      }
   }

   // Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      
      // get the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];
      System.debug('$$$ Jobid is'+BC.getJobId());
      
      // below code will send an email to User about the status
      mail.setToAddresses(email);
     
      // Add here your email address
      mail.setReplyTo('[email protected]');
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed
         '+a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
         processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }

   // Scheduler Method to scedule the class
   global void execute(SchedulableContext sc) {
      CustomerProessingBatch conInstance = new CustomerProessingBatch();
      database.executebatch(conInstance,100);
   }
}

Untuk menjalankan kelas ini, Anda harus menjalankan kode di bawah ini di Konsol Pengembang.

CustomerProessingBatch objBatch = new CustomerProessingBatch ();
Database.executeBatch(objBatch);

Dalam bab ini, kita akan membahas cara melakukan berbagai Fungsi Modifikasi Database di Salesforce. Ada dua kata yang dengannya kita dapat melakukan fungsionalitas.

Pernyataan DML

DML adalah tindakan yang dilakukan untuk melakukan operasi penyisipan, pembaruan, penghapusan, peningkatan, pemulihan catatan, penggabungan catatan, atau konversi prospek.

DML adalah salah satu bagian terpenting di Apex karena hampir setiap kasus bisnis melibatkan perubahan dan modifikasi database.

Metode Database

Semua operasi yang dapat Anda lakukan menggunakan pernyataan DML juga dapat dilakukan dengan menggunakan metode Database. Metode database adalah metode sistem yang dapat Anda gunakan untuk melakukan operasi DML. Metode database memberikan lebih banyak fleksibilitas dibandingkan dengan Pernyataan DML.

Dalam bab ini, kita akan melihat pendekatan pertama menggunakan Pernyataan DML. Kita akan melihat Metode Database di bab selanjutnya.

Pernyataan DML

Sekarang mari kita pertimbangkan lagi contoh perusahaan pemasok bahan kimia. Catatan Faktur kami memiliki bidang sebagai Status, Jumlah Dibayar, Jumlah Tersisa, Tanggal Pembayaran Berikutnya dan Nomor Faktur. Faktur yang telah dibuat hari ini dan berstatus 'Tertunda', harus diperbarui menjadi 'Berbayar'.

Sisipkan Operasi

Operasi insert digunakan untuk membuat record baru di Database. Anda dapat membuat rekaman objek Standar atau Kustom apa pun menggunakan pernyataan Sisipkan DML.

Example

Kami dapat membuat catatan baru di objek APEX_Invoice__c karena faktur baru dibuat untuk pesanan pelanggan baru setiap hari. Kami akan membuat catatan Pelanggan terlebih dahulu dan kemudian kami dapat membuat catatan Faktur untuk catatan Pelanggan baru tersebut.

// fetch the invoices created today, Note, you must have at least one invoice 
// created today

List<apex_invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c,
   createdDate FROM APEX_Invoice__c WHERE createdDate = today];

// create List to hold the updated invoice records
List<apex_invoice__c> updatedInvoiceList = new List<apex_invoice__c>();
APEX_Customer__c objCust = new APEX_Customer__C();
objCust.Name = 'Test ABC';

//DML for Inserting the new Customer Records
insert objCust;
for (APEX_Invoice__c objInvoice: invoiceList) {
   if (objInvoice.APEX_Status__c == 'Pending') {
      objInvoice.APEX_Status__c = 'Paid';
      updatedInvoiceList.add(objInvoice);
   }
}

// DML Statement to update the invoice status
update updatedInvoiceList;

// Prints the value of updated invoices
System.debug('List has been updated and updated values are' + updatedInvoiceList);

// Inserting the New Records using insert DML statement
APEX_Invoice__c objNewInvoice = new APEX_Invoice__c();
objNewInvoice.APEX_Status__c = 'Pending';
objNewInvoice.APEX_Amount_Paid__c = 1000;
objNewInvoice.APEX_Customer__c = objCust.id;

// DML which is creating the new Invoice record which will be linked with newly
// created Customer record
insert objNewInvoice;
System.debug('New Invoice Id is '+objNewInvoice.id+' and the Invoice Number is'
   + objNewInvoice.Name);

Perbarui Operasi

Operasi pembaruan adalah melakukan pembaruan pada rekaman yang ada. Dalam contoh ini, kami akan memperbarui bidang Status dari catatan Faktur yang ada menjadi 'Berbayar'.

Example

// Update Statement Example for updating the invoice status. You have to create
and Invoice records before executing this code. This program is updating the
record which is at index 0th position of the List.

// First, fetch the invoice created today
List<apex_invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c,
createdDate FROM APEX_Invoice__c];
List<apex_invoice__c> updatedInvoiceList = new List<apex_invoice__c>();

// Update the first record in the List
invoiceList[0].APEX_Status__c = 'Pending';
updatedInvoiceList.add(invoiceList[0]);

// DML Statement to update the invoice status
update updatedInvoiceList;

// Prints the value of updated invoices
System.debug('List has been updated and updated values of records are' 
   + updatedInvoiceList[0]);

Operasi Upsert

Operasi Upsert digunakan untuk melakukan operasi pembaruan dan jika catatan yang akan diperbarui tidak ada di database, buat catatan baru juga.

Example

Misalkan, catatan pelanggan di objek Pelanggan perlu diperbarui. Kami akan memperbarui catatan Pelanggan yang ada jika sudah ada, jika tidak buat yang baru. Ini akan didasarkan pada nilai bidang APEX_External_Id__c. Bidang ini akan menjadi bidang kami untuk mengidentifikasi apakah catatan sudah ada atau belum.

Note - Sebelum menjalankan kode ini, buat catatan di objek Pelanggan dengan nilai bidang Id eksternal sebagai '12341' dan kemudian jalankan kode yang diberikan di bawah ini -

// Example for upserting the Customer records
List<apex_customer__c> CustomerList = new List<apex_customer__c>();
for (Integer i = 0; i < 10; i++) {
   apex_customer__c objcust=new apex_customer__c(name = 'Test' +i,
   apex_external_id__c='1234' +i);
   customerlist.add(objcust);
} //Upserting the Customer Records

upsert CustomerList;

System.debug('Code iterated for 10 times and created 9 records as one record with 
   External Id 12341 is already present');

for (APEX_Customer_c objCustomer: CustomerList) {
   if (objCustomer.APEX_External_Id_c == '12341') {
      system.debug('The Record which is already present is '+objCustomer);
   }
}

Hapus Operasi

Anda dapat melakukan operasi penghapusan menggunakan Hapus DML.

Example

Dalam hal ini, kami akan menghapus invoice yang telah dibuat untuk tujuan pengujian, yaitu invoice yang namanya 'Test'.

Anda juga dapat menjalankan cuplikan ini dari konsol Pengembang tanpa membuat kelas.

// fetch the invoice created today
List<apex_invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c,
createdDate FROM APEX_Invoice__c WHERE createdDate = today];
List<apex_invoice__c> updatedInvoiceList = new List<apex_invoice__c>();
APEX_Customer__c objCust = new APEX_Customer__C();
objCust.Name = 'Test';

// Inserting the Customer Records
insert objCust;
for (APEX_Invoice__c objInvoice: invoiceList) {
   if (objInvoice.APEX_Status__c == 'Pending') {
      objInvoice.APEX_Status__c = 'Paid';
      updatedInvoiceList.add(objInvoice);
   }
}

// DML Statement to update the invoice status
update updatedInvoiceList;

// Prints the value of updated invoices
System.debug('List has been updated and updated values are' + updatedInvoiceList);

// Inserting the New Records using insert DML statement
APEX_Invoice__c objNewInvoice = new APEX_Invoice__c();
objNewInvoice.APEX_Status__c = 'Pending';
objNewInvoice.APEX_Amount_Paid__c = 1000;
objNewInvoice.APEX_Customer__c = objCust.id;

// DML which is creating the new record
insert objNewInvoice;
System.debug('New Invoice Id is' + objNewInvoice.id);

// Deleting the Test invoices from Database
// fetch the invoices which are created for Testing, Select name which Customer Name
// is Test.
List<apex_invoice__c> invoiceListToDelete = [SELECT id FROM APEX_Invoice__c
   WHERE APEX_Customer__r.Name = 'Test'];

// DML Statement to delete the Invoices
delete invoiceListToDelete;
System.debug('Success, '+invoiceListToDelete.size()+' Records has been deleted');

Operasi Batalkan Penghapusan

Anda dapat membatalkan penghapusan catatan yang telah dihapus dan ada di Recycle bin. Semua hubungan yang dimiliki rekaman yang dihapus, juga akan dipulihkan.

Example

Misalkan, Record yang dihapus pada contoh sebelumnya perlu dikembalikan. Ini dapat dicapai dengan menggunakan contoh berikut. Kode pada contoh sebelumnya telah dimodifikasi untuk contoh ini.

// fetch the invoice created today
List<apex_invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c,
createdDate FROM APEX_Invoice__c WHERE createdDate = today];
List<apex_invoice__c> updatedInvoiceList = new List<apex_invoice__c>();
APEX_Customer__c objCust = new APEX_Customer__C();
objCust.Name = 'Test';

// Inserting the Customer Records
insert objCust;
for (APEX_Invoice__c objInvoice: invoiceList) {
   if (objInvoice.APEX_Status__c == 'Pending') {
      objInvoice.APEX_Status__c = 'Paid';
      updatedInvoiceList.add(objInvoice);
   }
}

// DML Statement to update the invoice status
update updatedInvoiceList;

// Prints the value of updated invoices
System.debug('List has been updated and updated values are' + updatedInvoiceList);

// Inserting the New Records using insert DML statement
APEX_Invoice__c objNewInvoice = new APEX_Invoice__c();
objNewInvoice.APEX_Status__c = 'Pending';
objNewInvoice.APEX_Amount_Paid__c = 1000;
objNewInvoice.APEX_Customer__c = objCust.id;

// DML which is creating the new record
insert objNewInvoice;
System.debug('New Invoice Id is '+objNewInvoice.id);

// Deleting the Test invoices from Database
// fetch the invoices which are created for Testing, Select name which Customer Name
// is Test.
List<apex_invoice__c> invoiceListToDelete = [SELECT id FROM APEX_Invoice__c
   WHERE APEX_Customer__r.Name = 'Test'];

// DML Statement to delete the Invoices
delete invoiceListToDelete;
system.debug('Deleted Record Count is ' + invoiceListToDelete.size());
System.debug('Success, '+invoiceListToDelete.size() + 'Records has been deleted');

// Restore the deleted records using undelete statement
undelete invoiceListToDelete;
System.debug('Undeleted Record count is '+invoiceListToDelete.size()+'. This should 
   be same as Deleted Record count');

Metode kelas database adalah cara lain untuk bekerja dengan pernyataan DML yang lebih fleksibel daripada Pernyataan DML seperti penyisipan, pembaruan, dll.

Perbedaan antara Metode Database dan Pernyataan DML

Pernyataan DML Metode Database
Pembaruan Parsial tidak diperbolehkan. Misalnya, jika Anda memiliki 20 catatan dalam daftar, maka semua catatan akan diperbarui atau tidak sama sekali. Pembaruan sebagian diperbolehkan. Anda dapat menentukan Parameter dalam metode Database sebagai benar atau salah, benar untuk mengizinkan pembaruan parsial dan salah untuk tidak mengizinkan hal yang sama.
Anda tidak bisa mendapatkan daftar catatan sukses dan gagal. Anda bisa mendapatkan daftar rekor sukses dan gagal seperti yang kita lihat pada contoh.
Example - masukkan listName Example - Database.insert (listName, False), di mana salah menunjukkan bahwa update parsial tidak diperbolehkan.

Sisipkan Operasi

Memasukkan record baru melalui metode database juga cukup sederhana dan fleksibel. Mari kita pertimbangkan skenario sebelumnya di mana, kami telah memasukkan catatan baru menggunakan pernyataan DML. Kami akan memasukkan yang sama menggunakan metode Database.

Contoh

// Insert Operation Using Database methods
// Insert Customer Records First using simple DML Statement. This Customer Record will be
// used when we will create Invoice Records
APEX_Customer__c objCust = new APEX_Customer__C();
objCust.Name = 'Test';
insert objCust; // Inserting the Customer Records

// Insert Operation Using Database methods
APEX_Invoice__c objNewInvoice = new APEX_Invoice__c();
List<apex_invoice__c> InvoiceListToInsert = new List<apex_invoice__c>();
objNewInvoice.APEX_Status__c = 'Pending';
objNewInvoice.APEX_Customer__c = objCust.id;
objNewInvoice.APEX_Amount_Paid__c = 1000;
InvoiceListToInsert.add(objNewInvoice);
Database.SaveResult[] srList = Database.insert(InvoiceListToInsert, false);

// Database method to insert the records in List
// Iterate through each returned result by the method

for (Database.SaveResult sr : srList) {
   if (sr.isSuccess()) {
      // This condition will be executed for successful records and will fetch the ids 
      // of successful records
      System.debug('Successfully inserted Invoice. Invoice ID: ' + sr.getId());
      // Get the invoice id of inserted Account
   } else {
      // This condition will be executed for failed records
      for(Database.Error objErr : sr.getErrors()) {
         System.debug('The following error has occurred.');
         
         // Printing error message in Debug log
         System.debug(objErr.getStatusCode() + ': ' + objErr.getMessage());
         System.debug('Invoice oject field which are affected by the error:' 
            + objErr.getFields());
      }
   }
}

Perbarui Operasi

Sekarang mari kita pertimbangkan contoh kasus bisnis kita menggunakan metode database. Misalkan kita perlu mengupdate field status objek Invoice tetapi pada saat yang sama, kita juga membutuhkan informasi seperti status record, ID record yang gagal, hitungan sukses, dll. Hal ini tidak mungkin dilakukan dengan menggunakan DML Statements, oleh karena itu kita harus menggunakan metode Database untuk mendapatkan status operasi kami.

Contoh

Kami akan memperbarui bidang 'Status' Faktur jika berstatus 'Tertunda' dan tanggal pembuatannya hari ini.

Kode yang diberikan di bawah ini akan membantu dalam memperbarui catatan Faktur menggunakan metode Database.update. Juga, buat catatan Faktur sebelum menjalankan kode ini.

// Code to update the records using the Database methods
List<apex_invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c,
   createdDate FROM APEX_Invoice__c WHERE createdDate = today];

// fetch the invoice created today
List<apex_invoice__c> updatedInvoiceList = new List<apex_invoice__c>();
for (APEX_Invoice__c objInvoice: invoiceList) {
   if (objInvoice.APEX_Status__c == 'Pending') {
      objInvoice.APEX_Status__c = 'Paid';
      updatedInvoiceList.add(objInvoice);    //Adding records to the list
   }
}

Database.SaveResult[] srList = Database.update(updatedInvoiceList, false);
// Database method to update the records in List

// Iterate through each returned result by the method
for (Database.SaveResult sr : srList) {
   if (sr.isSuccess()) {
      // This condition will be executed for successful records and will fetch
      // the ids of successful records
      System.debug('Successfully updated Invoice. Invoice ID is : ' + sr.getId());
   } else {
      // This condition will be executed for failed records
      for(Database.Error objErr : sr.getErrors()) {
         System.debug('The following error has occurred.');
         
         // Printing error message in Debug log
         System.debug(objErr.getStatusCode() + ': ' + objErr.getMessage());
         System.debug('Invoice oject field which are affected by the error:' 
            + objErr.getFields());
      }
   }
}

Kami hanya akan melihat operasi Sisipkan dan Perbarui dalam tutorial ini. Operasi lainnya sangat mirip dengan operasi ini dan apa yang kami lakukan di bab sebelumnya.

Setiap bisnis atau aplikasi memiliki fungsi pencarian sebagai salah satu persyaratan dasar. Untuk ini, Salesforce.com menyediakan dua pendekatan utama menggunakan SOSL dan SOQL. Mari kita bahas pendekatan SOSL secara rinci di bab ini.

SOSL

Pencarian string teks di seluruh objek dan di seluruh bidang akan dilakukan dengan menggunakan SOSL. Ini adalah Bahasa Penelusuran Objek Salesforce. Ini memiliki kemampuan untuk mencari string tertentu di beberapa objek.

Pernyataan SOSL mengevaluasi ke daftar sObjects, di mana, setiap daftar berisi hasil pencarian untuk jenis sObject tertentu. Daftar hasil selalu dikembalikan dalam urutan yang sama seperti yang ditentukan dalam kueri SOSL.

Contoh Pertanyaan SOSL

Pertimbangkan kasus bisnis di mana, kita perlu mengembangkan program yang dapat mencari string tertentu. Misalkan, kita perlu mencari string 'ABC' di kolom Nama Pelanggan objek Faktur. Kode tersebut adalah sebagai berikut -

Pertama, Anda harus membuat satu record di objek Faktur dengan nama Pelanggan sebagai 'ABC' sehingga kita bisa mendapatkan hasil yang valid saat dicari.

// Program To Search the given string in all Object
// List to hold the returned results of sObject generic type
List<list<SObject>> invoiceSearchList = new List<List<SObject>>();

// SOSL query which will search for 'ABC' string in Customer Name field of Invoice Object
invoiceSearchList = [FIND 'ABC*' IN ALL FIELDS RETURNING APEX_Invoice_c
   (Id,APEX_Customer_r.Name)];

// Returned result will be printed
System.debug('Search Result '+invoiceSearchList);

// Now suppose, you would like to search string 'ABC' in two objects,
// that is Invoice and Account. Then for this query goes like this:

// Program To Search the given string in Invoice and Account object,
// you could specify more objects if you want, create an Account with Name as ABC.

// List to hold the returned results of sObject generic type
List<List<SObject>> invoiceAndSearchList = new List<List<SObject>>();

// SOSL query which will search for 'ABC' string in Invoice and in Account object's fields
invoiceAndSearchList = [FIND 'ABC*' IN ALL FIELDS RETURNING APEX_Invoice__c
   (Id,APEX_Customer__r.Name), Account];

// Returned result will be printed
System.debug('Search Result '+invoiceAndSearchList);

// This list will hold the returned results for Invoice Object
APEX_Invoice__c [] searchedInvoice = ((List<APEX_Invoice_c>)invoiceAndSearchList[0]);

// This list will hold the returned results for Account Object
Account [] searchedAccount = ((List<Account>)invoiceAndSearchList[1]);
System.debug('Value of searchedInvoice'+searchedInvoice+'Value of searchedAccount'
   + searchedAccount);

SOQL

Ini hampir sama dengan SOQL. Anda dapat menggunakan ini untuk mengambil rekaman objek dari satu objek hanya dalam satu waktu. Anda bisa menulis kueri bertingkat dan juga mengambil rekaman dari objek induk atau anak yang Anda kueri sekarang.

Kami akan menjelajahi SOQL di bab berikutnya.

Ini adalah Bahasa Kueri Objek Salesforce yang dirancang untuk bekerja dengan Database SFDC. Itu dapat mencari record pada kriteria tertentu hanya dalam satu sObject.

Seperti SOSL, ia tidak dapat mencari di beberapa objek tetapi mendukung kueri bersarang.

Contoh SOQL

Pertimbangkan contoh Perusahaan Kimia kami yang sedang berlangsung. Misalkan, kita memerlukan daftar record yang dibuat hari ini dan yang nama pelanggannya bukan 'test'. Dalam hal ini, kita harus menggunakan kueri SOQL seperti yang diberikan di bawah ini -

// fetching the Records via SOQL
List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
InvoiceList = [SELECT Id, Name, APEX_Customer__r.Name, APEX_Status__c FROM
   APEX_Invoice__c WHERE createdDate = today AND APEX_Customer__r.Name != 'Test'];
// SOQL query for given criteria

// Printing the fetched records
System.debug('We have total '+InvoiceList.size()+' Records in List');

for (APEX_Invoice__c objInvoice: InvoiceList) {
   System.debug('Record Value is '+objInvoice); 
   // Printing the Record fetched
}

Anda dapat menjalankan kueri SOQL melalui Editor Kueri di konsol Pengembang seperti yang ditunjukkan di bawah ini.

Jalankan kueri yang diberikan di bawah ini di Konsol Pengembang. Cari catatan Faktur yang dibuat hari ini.

SELECT Id, Name, APEX_Customer__r.Name, APEX_Status__c FROM APEX_Invoice__c
   WHERE createdDate = today

Anda harus memilih bidang yang Anda perlukan nilainya, jika tidak, ini dapat menimbulkan kesalahan waktu proses.

Melintasi Bidang Hubungan

Ini adalah salah satu bagian terpenting dalam SFDC karena sering kali kita perlu melintasi hubungan objek induk anak

Selain itu, mungkin ada kasus ketika Anda perlu memasukkan dua rekaman objek terkait di Database. Misalnya, objek Faktur memiliki hubungan dengan objek Pelanggan dan karenanya satu Pelanggan dapat memiliki banyak faktur.

Misalkan, Anda membuat faktur dan kemudian Anda perlu menghubungkan faktur ini dengan Pelanggan. Anda dapat menggunakan kode berikut untuk fungsi ini -

// Now create the invoice record and relate it with the Customer object
// Before executing this, please create a Customer Records with Name 'Customer
// Creation Test'
APEX_Invoice__c objInvoice = new APEX_Invoice__c();

// Relating Invoice to customer via id field of Customer object
objInvoice.APEX_Customer__c = [SELECT id FROM APEX_Customer__c WHERE Name =
   'Customer Creation Test' LIMIT 1].id;
objInvoice.APEX_Status__c = 'Pending';
insert objInvoice;  //Creating Invoice
System.debug('Newly Created Invoice'+objInvoice);  //Newly created invoice

Jalankan cuplikan kode ini di Konsol Pengembang. Setelah dijalankan, salin Id faktur dari konsol Pengembang dan kemudian buka yang sama di SFDC seperti yang ditunjukkan di bawah ini. Anda dapat melihat bahwa catatan Induk telah ditetapkan ke catatan Faktur seperti yang ditunjukkan di bawah ini.

Mengambil Catatan Anak

Sekarang mari kita pertimbangkan contoh di mana, semua faktur yang terkait dengan catatan pelanggan tertentu harus berada di satu tempat. Untuk ini, Anda harus mengetahui nama hubungan anak. Untuk melihat nama hubungan anak, buka halaman detail bidang pada objek anak dan periksa nilai "Hubungan Anak". Dalam contoh kami, ini adalah faktur yang ditambahkan dengan __r di bagian akhir.

Contoh

Dalam contoh ini, kita perlu menyiapkan data, membuat pelanggan dengan nama sebagai catatan 'Pelanggan ABC' dan kemudian menambahkan 3 faktur ke pelanggan itu.

Sekarang, kami akan mengambil faktur yang dimiliki Pelanggan 'Pelanggan ABC'. Berikut ini adalah kueri yang sama -

// Fetching Child Records using SOQL
List<apex_customer__c> ListCustomers = [SELECT Name, Id, 
   (SELECT id, Name FROM Invoices__r) FROM APEX_Customer__c WHERE Name = 'ABC Customer'];

// Query for fetching the Child records along with Parent
System.debug('ListCustomers '+ListCustomers); // Parent Record

List<apex_invoice__c> ListOfInvoices = ListCustomers[0].Invoices__r;
// By this notation, you could fetch the child records and save it in List
System.debug('ListOfInvoices values of Child '+ListOfInvoices);
// Child records

Anda dapat melihat nilai Rekam di log Debug.

Mengambil Data Induk

Misalkan, Anda perlu mengambil Nama Pelanggan dari Faktur yang tanggal pembuatannya adalah hari ini, maka Anda dapat menggunakan kueri yang diberikan di bawah ini untuk hal yang sama -

Contoh

Ambil nilai record Parent bersama dengan objek anak.

// Fetching Parent Record Field value using SOQL
List<apex_invoice__c> ListOfInvoicesWithCustomerName = new List<apex_invoice__c>();
ListOfInvoicesWithCustomerName = [SELECT Name, id, APEX_Customer__r.Name 
   FROM APEX_Invoice__c LIMIT 10];

// Fetching the Parent record's values
for (APEX_Invoice__c objInv: ListOfInvoicesWithCustomerName) {
   System.debug('Invoice Customer Name is '+objInv.APEX_Customer__r.Name);
   // Will print the values, all the Customer Records will be printed
}

Di sini kita telah menggunakan notasi APEX_Customer__r.Name, di mana APEX_Customer__r adalah nama hubungan induk, di sini Anda harus menambahkan __r di akhir bidang Induk dan kemudian Anda dapat mengambil nilai bidang induk.

Fungsi Agregat

SOQL memang memiliki fungsi agregat seperti yang kita miliki di SQL. Fungsi agregat memungkinkan kita untuk menggulung dan meringkas data. Mari kita sekarang memahami fungsinya secara detail.

Misalkan, Anda ingin tahu berapa pendapatan rata-rata yang kita peroleh dari Pelanggan 'Pelanggan ABC', maka Anda dapat menggunakan fungsi ini untuk mengambil rata-rata.

Contoh

// Getting Average of all the invoices for a Perticular Customer
AggregateResult[] groupedResults = [SELECT
   AVG(APEX_Amount_Paid__c)averageAmount FROM APEX_Invoice__c WHERE
   APEX_Customer__r.Name = 'ABC Customer'];
Object avgPaidAmount = groupedResults[0].get('averageAmount');
System.debug('Total Average Amount Received From Customer ABC is '+avgPaidAmount);

Periksa output di log Debug. Perhatikan bahwa kueri apa pun yang menyertakan fungsi agregat akan mengembalikan hasilnya dalam larikAggregateResultbenda. AggregateResult adalah sObject hanya baca dan hanya digunakan untuk hasil kueri. Ini berguna saat kita perlu membuat Laporan tentang data Besar.

Ada juga fungsi agregat lain yang dapat Anda gunakan untuk melakukan ringkasan data.

MIN() - Ini dapat digunakan untuk menemukan nilai minimum

MAX() - Ini dapat digunakan untuk menemukan nilai maksimum.

Mengikat Variabel Apex

Anda dapat menggunakan variabel Apex dalam kueri SOQL untuk mengambil hasil yang diinginkan. Variabel Apex dapat direferensikan dengan notasi Colon (:).

Contoh

// Apex Variable Reference
String CustomerName = 'ABC Customer';
List<apex_customer__c> ListCustomer = [SELECT Id, Name FROM APEX_Customer__c
   WHERE Name = :CustomerName];

// Query Using Apex variable
System.debug('ListCustomer Name'+ListCustomer); // Customer Name

Keamanan Apex mengacu pada proses penerapan pengaturan keamanan dan menegakkan aturan berbagi pada menjalankan kode. Kelas Apex memiliki pengaturan keamanan yang dapat dikontrol melalui dua kata kunci.

Keamanan Data dan Aturan Berbagi

Apex umumnya berjalan dalam konteks sistem, yaitu izin pengguna saat ini. Keamanan tingkat lapangan, dan aturan berbagi tidak diperhitungkan selama eksekusi kode. Hanya kode blok anonim yang dijalankan dengan izin dari pengguna yang menjalankan kode tersebut.

Kode Apex kami tidak boleh mengekspos data sensitif kepada Pengguna yang disembunyikan melalui pengaturan keamanan dan berbagi. Karenanya, keamanan Apex dan menegakkan aturan berbagi adalah yang paling penting.

Dengan Berbagi Kata Kunci

Jika Anda menggunakan kata kunci ini, maka kode Apex akan memberlakukan pengaturan Berbagi dari pengguna saat ini ke kode Apex. Ini tidak memberlakukan izin Profil, hanya setelan berbagi tingkat data.

Mari kita pertimbangkan contoh di mana, Pengguna kita memiliki akses ke 5 catatan, tetapi jumlah total catatan adalah 10. Jadi ketika kelas Apex akan dideklarasikan dengan Kata Kunci "Dengan Berbagi", itu hanya akan mengembalikan 5 catatan di mana pengguna memiliki akses ke.

Example

Pertama, pastikan bahwa Anda telah membuat setidaknya 10 catatan di objek Pelanggan dengan 'Nama' dari 5 catatan sebagai 'Pelanggan ABC' dan 5 catatan lainnya sebagai 'Pelanggan XYZ'. Kemudian, buat aturan berbagi yang akan membagikan 'Pelanggan ABC' dengan semua Pengguna. Kami juga perlu memastikan bahwa kami telah menetapkan OWD objek Pelanggan sebagai Pribadi.

Tempel kode yang diberikan di bawah ini ke blok Anonim di Konsol Pengembang.

// Class With Sharing
public with sharing class MyClassWithSharing {
   // Query To fetch 10 records
   List<apex_customer__c> CustomerList = [SELECT id, Name FROM APEX_Customer__c LIMIT 10];
   
   public Integer executeQuery () {
      System.debug('List will have only 5 records and the actual records are' 
         + CustomerList.size()+' as user has access to'+CustomerList);
      Integer ListSize = CustomerList.size();
      return ListSize;
   }
}

// Save the above class and then execute as below
// Execute class using the object of class
MyClassWithSharing obj = new MyClassWithSharing();
Integer ListSize = obj.executeQuery();

Tanpa Berbagi Kata Kunci

Seperti namanya, kelas yang dideklarasikan dengan kata kunci ini dijalankan dalam mode Sistem, yaitu, terlepas dari akses Pengguna ke catatan, kueri akan mengambil semua catatan.

// Class Without Sharing
public without sharing class MyClassWithoutSharing {
   List<apex_customer__c> CustomerList = [SELECT id, Name FROM APEX_Customer__c LIMIT 10];
   
   // Query To fetch 10 records, this will return all the records
   public Integer executeQuery () {
      System.debug('List will have only 5 records and the actula records are'
         + CustomerList.size()+' as user has access to'+CustomerList);
      Integer ListSize = CustomerList.size();
      return ListSize;
   }
}
// Output will be 10 records.

Mengatur Keamanan untuk Kelas Apex

Anda dapat mengaktifkan atau menonaktifkan kelas Apex untuk profil tertentu. Langkah-langkah yang sama diberikan di bawah ini. Anda dapat menentukan profil mana yang harus memiliki akses ke kelas mana.

Mengatur keamanan kelas Apex dari halaman daftar kelas

Step 1 - Dari Setup, klik Develop → Apex Classes.

Step 2- Klik nama kelas yang ingin Anda batasi. Kami telah mengklik CustomerOperationClass.

Step 3 - Klik Keamanan.

Step 4 - Pilih profil yang ingin Anda aktifkan dari daftar Profil yang Tersedia dan klik Tambah, atau pilih profil yang ingin Anda nonaktifkan dari daftar Profil yang Diaktifkan dan klik Hapus.

Step 5 - Klik Simpan.

Mengatur Keamanan Apex dari Set Izin

Step 1 - Dari Setup, klik Manage Users → Permission Sets.

Step 2 - Pilih satu set izin.

Step 3 - Klik Akses Kelas Apex.

Step 4 - Klik Edit.

Step 5 - Pilih kelas Apex yang ingin Anda aktifkan dari daftar Kelas Apex yang Tersedia dan klik Tambah, atau pilih kelas Apex yang ingin Anda nonaktifkan dari daftar Kelas Apex yang Diaktifkan dan klik hapus.

Step 6 - Klik tombol Simpan.

Memanggil Apex mengacu pada proses mengeksekusi kelas Apex. Kelas Apex hanya dapat dieksekusi ketika dipanggil melalui salah satu cara yang tercantum di bawah ini -

  • Pemicu dan blokir Anonim

  • Pemicu dipanggil untuk acara tertentu

  • Apex Asinkron

  • Menjadwalkan kelas Apex untuk dijalankan pada interval yang ditentukan, atau menjalankan tugas batch

  • Kelas Layanan Web

  • Kelas Layanan Email Apex

  • Apex Web Services, yang memungkinkan pemaparan metode Anda melalui SOAP dan layanan Web REST

  • Pengontrol Visualforce

  • Layanan Email Apex untuk memproses email masuk

  • Memanggil Apex Menggunakan JavaScript

  • Toolkit Ajax untuk menjalankan metode layanan Web yang diimplementasikan di Apex

Kami sekarang akan memahami beberapa cara umum untuk memanggil Apex.

Dari Execute Anonymous Block

Anda dapat memanggil kelas Apex melalui eksekusi anonim di Konsol Pengembang seperti yang ditunjukkan di bawah ini -

Step 1 - Buka Konsol Pengembang.

Step 2 - Klik Debug.

Step 3- Jalankan jendela anonim akan terbuka seperti yang ditunjukkan di bawah ini. Sekarang, klik pada tombol Execute -

Step 4 - Buka Log Debug yang akan muncul di panel Log.

Dari Trigger

Anda juga dapat memanggil kelas Apex dari Trigger. Pemicu dipanggil saat peristiwa tertentu terjadi dan pemicu dapat memanggil kelas Apex saat menjalankan.

Berikut ini adalah kode contoh yang menunjukkan bagaimana kelas dijalankan ketika Pemicu dipanggil.

Contoh

// Class which will gets called from trigger
public without sharing class MyClassWithSharingTrigger {

   public static Integer executeQuery (List<apex_customer__c> CustomerList) {
      // perform some logic and operations here
      Integer ListSize = CustomerList.size();
      return ListSize;
   }
}

// Trigger Code
trigger Customer_After_Insert_Example on APEX_Customer__c (after insert) {
   System.debug('Trigger is Called and it will call Apex Class');
   MyClassWithSharingTrigger.executeQuery(Trigger.new);  // Calling Apex class and 
                                                         // method of an Apex class
}

// This example is for reference, no need to execute and will have detail look on 
// triggers later chapters.

Dari Kode Pengontrol Halaman Visualforce

Kelas Apex dapat dipanggil dari halaman Visualforce juga. Kita dapat menentukan pengontrol atau ekstensi pengontrol dan kelas Apex yang ditentukan dipanggil.

Contoh

VF Page Code

Apex Class Code (Controller Extension)

Pemicu puncak seperti prosedur tersimpan yang dijalankan saat peristiwa tertentu terjadi. Pemicu dijalankan sebelum dan setelah peristiwa terjadi pada catatan.

Sintaksis

trigger triggerName on ObjectName (trigger_events) { Trigger_code_block }

Menjalankan Pemicu

Berikut adalah peristiwa di mana kita dapat mengaktifkan pemicunya -

  • insert
  • update
  • delete
  • merge
  • upsert
  • undelete

Contoh Pemicu 1

Misalkan kita menerima persyaratan bisnis bahwa kita perlu membuat Catatan Faktur ketika bidang 'Status Pelanggan' Pelanggan berubah menjadi Aktif dari Tidak Aktif. Untuk ini, kami akan membuat pemicu pada objek APEX_Customer__c dengan mengikuti langkah-langkah ini -

Step 1 - Pergi ke sObject

Step 2 - Klik Pelanggan

Step 3 - Klik tombol 'Baru' di daftar terkait Pemicu dan tambahkan kode pemicu seperti yang diberikan di bawah ini.

// Trigger Code
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   List InvoiceList = new List();
   
   for (APEX_Customer__c objCustomer: Trigger.new) {
      
      if (objCustomer.APEX_Customer_Status__c == 'Active') {
         APEX_Invoice__c objInvoice = new APEX_Invoice__c();
         objInvoice.APEX_Status__c = 'Pending';
         InvoiceList.add(objInvoice);
      }
   }
   
   // DML to insert the Invoice List in SFDC
   insert InvoiceList;
}

Penjelasan

Trigger.new- Ini adalah variabel konteks yang menyimpan catatan saat ini dalam konteks pemicu, baik yang sedang disisipkan atau diperbarui. Dalam kasus ini, variabel ini memiliki catatan objek Pelanggan yang telah diperbarui.

Ada variabel konteks lain yang tersedia dalam konteks - trigger.old, trigger.newMap, trigger.OldMap.

Contoh Pemicu 2

Pemicu di atas akan dijalankan ketika ada operasi pembaruan pada catatan Pelanggan. Misalkan, catatan faktur perlu disisipkan hanya ketika Status Pelanggan berubah dari Tidak Aktif menjadi Aktif dan tidak setiap saat; untuk ini, kita dapat menggunakan variabel konteks laintrigger.oldMap yang akan menyimpan kunci sebagai id record dan nilainya sebagai nilai record lama.

// Modified Trigger Code
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
   
   for (APEX_Customer__c objCustomer: Trigger.new) {
      
      // condition to check the old value and new value
      if (objCustomer.APEX_Customer_Status__c == 'Active' &&
      
      trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
         APEX_Invoice__c objInvoice = new APEX_Invoice__c();
         objInvoice.APEX_Status__c = 'Pending';
         InvoiceList.add(objInvoice);
      }
   }
   
   // DML to insert the Invoice List in SFDC
   insert InvoiceList;
}

Penjelasan

Kami telah menggunakan variabel Trigger.oldMap yang seperti yang dijelaskan sebelumnya, adalah variabel konteks yang menyimpan Id dan nilai lama dari catatan yang sedang diperbarui.

Pola desain digunakan untuk membuat kode kita lebih efisien dan untuk menghindari mencapai batas pengatur. Seringkali pengembang dapat menulis kode yang tidak efisien yang dapat menyebabkan contoh objek berulang. Hal ini dapat mengakibatkan kode yang tidak efisien dan berkinerja buruk, dan berpotensi melanggar batas gubernur. Ini paling sering terjadi pada pemicu, karena dapat beroperasi pada sekumpulan record.

Kita akan melihat beberapa strategi pola desain penting dalam bab ini.

Pola Desain Pemicu Massal

Dalam kasus bisnis nyata, Anda mungkin perlu memproses ribuan catatan sekaligus. Jika pemicu Anda tidak dirancang untuk menangani situasi seperti itu, pemicu mungkin gagal saat memproses rekaman. Ada beberapa praktik terbaik yang perlu Anda ikuti saat menerapkan pemicu. Semua pemicu adalah pemicu massal secara default, dan dapat memproses beberapa catatan dalam satu waktu. Anda harus selalu merencanakan untuk memproses lebih dari satu rekaman dalam satu waktu.

Pertimbangkan kasus bisnis, di mana, Anda perlu memproses sejumlah besar catatan dan Anda telah menulis pemicunya seperti yang diberikan di bawah ini. Ini adalah contoh yang sama yang kami ambil untuk memasukkan catatan faktur ketika Status Pelanggan berubah dari Tidak Aktif menjadi Aktif.

// Bad Trigger Example
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   
   for (APEX_Customer__c objCustomer: Trigger.new) {
      
      if (objCustomer.APEX_Customer_Status__c == 'Active' && 
         trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
         
         // condition to check the old value and new value
         APEX_Invoice__c objInvoice = new APEX_Invoice__c();
         objInvoice.APEX_Status__c = 'Pending';
         insert objInvoice;   //DML to insert the Invoice List in SFDC
      }
   }
}

Anda sekarang dapat melihat bahwa Pernyataan DML telah ditulis untuk blok loop yang akan berfungsi saat memproses hanya beberapa catatan tetapi ketika Anda memproses beberapa ratus catatan, itu akan mencapai batas Pernyataan DML per transaksi yang merupakan governor limit. Kami akan melihat secara mendetail tentang Batas Gubernur di bab berikutnya.

Untuk menghindari hal ini, kita harus membuat pemicu efisien untuk memproses banyak record dalam satu waktu.

Contoh berikut akan membantu Anda memahami hal yang sama -

// Modified Trigger Code-Bulk Trigger
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
   
   for (APEX_Customer__c objCustomer: Trigger.new) {
      
      if (objCustomer.APEX_Customer_Status__c == 'Active' &&
         trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
         
         //condition to check the old value and new value
         APEX_Invoice__c objInvoice = new APEX_Invoice__c();
         objInvoice.APEX_Status__c = 'Pending';
         InvoiceList.add(objInvoice);//Adding records to List
      }
   }
   
   insert InvoiceList;
   // DML to insert the Invoice List in SFDC, this list contains the all records 
   // which need to be modified and will fire only one DML
}

Pemicu ini hanya akan mengaktifkan 1 pernyataan DML karena akan beroperasi di atas Daftar dan Daftar memiliki semua catatan yang perlu dimodifikasi.

Dengan cara ini, Anda dapat menghindari batasan gubernur pernyataan DML.

Kelas Trigger Helper

Menulis seluruh kode di trigger juga bukan praktik yang baik. Karenanya Anda harus memanggil kelas Apex dan mendelegasikan pemrosesan dari kelas Trigger ke Apex seperti yang ditunjukkan di bawah ini. Kelas Trigger Helper adalah kelas yang melakukan semua pemrosesan untuk pemicu.

Mari kita pertimbangkan lagi contoh pembuatan catatan faktur kita.

// Below is the Trigger without Helper class
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
   
   for (APEX_Customer__c objCustomer: Trigger.new) {
      
      if (objCustomer.APEX_Customer_Status__c == 'Active' &&
         trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
         
         // condition to check the old value and new value
         APEX_Invoice__c objInvoice = new APEX_Invoice__c();
         objInvoice.APEX_Status__c = 'Pending';
         InvoiceList.add(objInvoice);
      }
   }
   
   insert InvoiceList; // DML to insert the Invoice List in SFDC
}

// Below is the trigger with helper class
// Trigger with Helper Class
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   CustomerTriggerHelper.createInvoiceRecords(Trigger.new, trigger.oldMap);
   // Trigger calls the helper class and does not have any code in Trigger
}

Kelas Pembantu

public class CustomerTriggerHelper {
   public static void createInvoiceRecords (List<apex_customer__c>
   
   customerList, Map<id, apex_customer__c> oldMapCustomer) {
      List<apex_invoice__c> InvoiceList = new Listvapex_invoice__c>();
      
      for (APEX_Customer__c objCustomer: customerList) {
         
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            oldMapCustomer.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
            
            // condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            
            // objInvoice.APEX_Status__c = 'Pending';
            InvoiceList.add(objInvoice);
         }
      }
      
      insert InvoiceList;  // DML to insert the Invoice List in SFDC
   }
}

Dalam hal ini, semua pemrosesan telah didelegasikan ke kelas helper dan ketika kita membutuhkan fungsionalitas baru, kita cukup menambahkan kode ke kelas helper tanpa mengubah pemicu.

Pemicu Tunggal pada Setiap sObject

Selalu buat satu pemicu pada setiap objek. Beberapa pemicu pada objek yang sama dapat menyebabkan konflik dan kesalahan jika mencapai batas pengatur.

Anda dapat menggunakan variabel konteks untuk memanggil metode yang berbeda dari kelas helper sesuai kebutuhan. Pertimbangkan contoh kami sebelumnya. Misalkan metode createInvoice kami harus dipanggil hanya saat record diperbarui dan di beberapa acara. Kemudian kita dapat mengontrol eksekusi seperti di bawah ini -

// Trigger with Context variable for controlling the calling flow
trigger Customer_After_Insert on APEX_Customer__c (after update, after insert) {
   
   if (trigger.isAfter && trigger.isUpdate) {
      // This condition will check for trigger events using isAfter and isUpdate
      // context variable
      CustomerTriggerHelper.createInvoiceRecords(Trigger.new);
      
      // Trigger calls the helper class and does not have any code in Trigger
      // and this will be called only when trigger ids after update
   }
}

// Helper Class
public class CustomerTriggerHelper {
   
   //Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c> customerList) {
      
      for (APEX_Customer__c objCustomer: customerList) {
         
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
            
            // condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            InvoiceList.add(objInvoice);
         }
      }
      
      insert InvoiceList; // DML to insert the Invoice List in SFDC
   }
}

Batas eksekusi pengatur memastikan penggunaan sumber daya yang efisien pada platform multitenant Force.com. Ini adalah batas yang ditentukan oleh Salesforce.com pada eksekusi kode untuk pemrosesan yang efisien.

Apa Batas Gubernur?

Seperti yang kita ketahui, Apex berjalan di lingkungan multi-tenant, yaitu, satu sumber daya digunakan bersama oleh semua pelanggan dan organisasi. Jadi, penting untuk memastikan bahwa tidak ada yang memonopoli sumber daya dan karenanya Salesforce.com telah membuat rangkaian batasan yang mengatur dan membatasi eksekusi kode. Setiap kali salah satu batas gubernur dilintasi, itu akan menimbulkan kesalahan dan akan menghentikan pelaksanaan program.

Dari perspektif Pengembang, penting untuk memastikan bahwa kode kami harus dapat diskalakan dan tidak mencapai batas.

Semua batasan ini diterapkan per transaksi. Eksekusi pemicu tunggal adalah satu transaksi.

Seperti yang telah kita lihat, pola desain pemicu membantu menghindari kesalahan batas. Sekarang kita akan melihat batasan penting lainnya.

Menghindari Batas Kueri SOQL

Anda hanya dapat mengeluarkan 100 kueri per transaksi, yaitu ketika kode Anda akan mengeluarkan lebih dari 100 kueri SOQL maka itu akan menimbulkan kesalahan.

Contoh

Contoh ini menunjukkan bagaimana batas kueri SOQL dapat dicapai -

Pemicu berikut mengulang daftar pelanggan dan memperbarui deskripsi (Faktur) rekaman anak dengan string 'Oke untuk Membayar'.

// Helper class:Below code needs o be checked.
public class CustomerTriggerHelper {
  
  public static void isAfterUpdateCall(Trigger.new) {
      createInvoiceRecords(trigger.new);//Method call
      updateCustomerDescription(trigger.new);
   }
   
   // Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c> customerList) {
      for (APEX_Customer__c objCustomer: customerList) {
         
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
            
            // condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            InvoiceList.add(objInvoice);
         }
      }
      insert InvoiceList; // DML to insert the Invoice List in SFDC
   }
   
   // Method to update the invoice records
   public static updateCustomerDescription (List<apex_customer__c> customerList) {
      for (APEX_Customer__c objCust: customerList) {
         List<apex_customer__c> invList = [SELECT Id, Name,
            APEX_Description__c FROM APEX_Invoice__c WHERE APEX_Customer__c = :objCust.id];
         
         // This query will fire for the number of records customer list has and will
         // hit the governor limit when records are more than 100
         for (APEX_Invoice__c objInv: invList) {
            objInv.APEX_Description__c = 'OK To Pay';
            update objInv;
            // Update invoice, this will also hit the governor limit for DML if large
            // number(150) of records are there
         }
      }
   }
}

Ketika metode 'updateCustomerDescription' dipanggil dan jumlah record pelanggan lebih dari 100, maka itu akan mencapai batas SOQL. Untuk menghindari hal ini, jangan pernah menulis kueri SOQL di For Loop. Dalam kasus ini, kueri SOQL telah ditulis di loop For.

Berikut adalah contoh yang akan menunjukkan bagaimana menghindari DML serta batas SOQL. Kami telah menggunakan kueri hubungan bertingkat untuk mengambil catatan faktur dan menggunakan variabel kontekstrigger.newMap untuk mendapatkan peta id dan catatan Pelanggan.

// SOQL-Good Way to Write Query and avoid limit exception
// Helper Class
public class CustomerTriggerHelper {
   public static void isAfterUpdateCall(Trigger.new) {
      createInvoiceRecords(trigger.new);  //Method call
      updateCustomerDescription(trigger.new, trigger.newMap);
   }
   
   // Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c> customerList) {
      for (APEX_Customer__c objCustomer: customerList) {
         
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
            
            // condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            InvoiceList.add(objInvoice);
         }
      }
      insert InvoiceList; // DML to insert the Invoice List in SFDC
   }
   
   // Method to update the invoice records
   public static updateCustomerDescription (List<apex_customer__c>
      customerList, Map<id, apex_customer__c> newMapVariable) {
      List<apex_customer__c> customerListWithInvoice = [SELECT id,
         Name,(SELECT Id, Name, APEX_Description__c FROM APEX_Invoice__r) FROM
         APEX_Customer__c WHERE Id IN :newMapVariable.keySet()];
      
      // Query will be for only one time and fetches all the records
      List<apex_invoice__c> invoiceToUpdate = new
      List<apex_invoice__c>();
      
      for (APEX_Customer__c objCust: customerList) {
         for (APEX_Invoice__c objInv: invList) {
            objInv.APEX_Description__c = 'OK To Pay';
            invoiceToUpdate.add(objInv);
            // Add the modified records to List
         }
      }
      update invoiceToUpdate;
   }
}

Panggilan Massal DML

Contoh ini menunjukkan pemicu Massal bersama dengan pola kelas penolong pemicu. Anda harus menyimpan kelas helper terlebih dahulu dan kemudian menyimpan pemicunya.

Note - Rekatkan kode di bawah ini di kelas 'CustomerTriggerHelper' yang telah kita buat sebelumnya.

// Helper Class
public class CustomerTriggerHelper {
   public static void isAfterUpdateCall(List<apex_customer__c> customerList,
      Map<id, apex_customer__c> mapIdToCustomers, Map<id, apex_customer__c>
      mapOldItToCustomers) {
      createInvoiceRecords(customerList, mapOldItToCustomers);   //Method call
      updateCustomerDescription(customerList,mapIdToCustomers,
      mapOldItToCustomers);
   }
   
   // Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c>
      customerList, Map<id, apex_customer__c> mapOldItToCustomers) {
      List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
      List<apex_customer__c> customerToInvoice = [SELECT id, Name FROM
         APEX_Customer__c LIMIT 1];
      
      for (APEX_Customer__c objCustomer: customerList) {
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            mapOldItToCustomers.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
            //condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            objInvoice.APEX_Customer__c = objCustomer.id;
            InvoiceList.add(objInvoice);
         }
      }
      system.debug('InvoiceList&&&'+InvoiceList);
      insert InvoiceList;
      // DML to insert the Invoice List in SFDC. This also follows the Bulk pattern
   }
   
   // Method to update the invoice records
   public static void updateCustomerDescription (List<apex_customer__c>
      customerList, Map<id, apex_customer__c> newMapVariable, Map<id,
      apex_customer__c> oldCustomerMap) {
      List<apex_customer__c> customerListWithInvoice = [SELECT id,
      Name,(SELECT Id, Name, APEX_Description__c FROM Invoices__r) FROM
         APEX_Customer__c WHERE Id IN :newMapVariable.keySet()];
   
      // Query will be for only one time and fetches all the records
      List<apex_invoice__c> invoiceToUpdate = new List<apex_invoice__c>();
      List<apex_invoice__c> invoiceFetched = new List<apex_invoice__c>();
      invoiceFetched = customerListWithInvoice[0].Invoices__r;
      system.debug('invoiceFetched'+invoiceFetched);
      system.debug('customerListWithInvoice****'+customerListWithInvoice);
   
      for (APEX_Customer__c objCust: customerList) {
         system.debug('objCust.Invoices__r'+objCust.Invoices__r);
         if (objCust.APEX_Active__c == true &&
            oldCustomerMap.get(objCust.id).APEX_Active__c == false) {
            for (APEX_Invoice__c objInv: invoiceFetched) {
               system.debug('I am in For Loop'+objInv);
               objInv.APEX_Description__c = 'OK To Pay';
               invoiceToUpdate.add(objInv);
               // Add the modified records to List
            }
         }
      }
     system.debug('Value of List ***'+invoiceToUpdate);
     update invoiceToUpdate;
      // This statement is Bulk DML which performs the DML on List and avoids
      // the DML Governor limit
   }
}

// Trigger Code for this class: Paste this code in 'Customer_After_Insert'
// trigger on Customer Object
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   CustomerTriggerHelper.isAfterUpdateCall(Trigger.new, trigger.newMap,
      trigger.oldMap);
   // Trigger calls the helper class and does not have any code in Trigger
}

Batasan Gubernur Tenaga Penjualan lainnya

Tabel berikut mencantumkan batas gubernur penting.

Deskripsi Membatasi
Total ukuran heap 6 MB / 12 MB
Jumlah total pernyataan DML yang dikeluarkan 150
Jumlah total rekaman yang diambil oleh satu kueri SOSL 2000
Jumlah total kueri SOSL yang dikeluarkan 20
Jumlah total record yang diambil oleh Database.getQueryLocator 10000
Jumlah total catatan yang diambil oleh kueri SOQL 50000

Dalam bab ini, kita akan memahami Pemrosesan Batch di Apex. Pertimbangkan skenario di mana, kami akan memproses sejumlah besar catatan setiap hari, mungkin pembersihan data atau mungkin menghapus beberapa data yang tidak digunakan.

Apa itu Batch Apex?

Batch Apex adalah eksekusi asynchronous dari kode Apex, yang dirancang khusus untuk memproses record dalam jumlah besar dan memiliki fleksibilitas yang lebih besar dalam batas pengatur daripada kode sinkron.

Kapan menggunakan Batch Apex?

  • Bila Anda ingin memproses sejumlah besar catatan setiap hari atau bahkan pada waktu interval tertentu, Anda dapat memilih Batch Apex.

  • Selain itu, jika Anda ingin sebuah operasi menjadi asinkron, Anda dapat mengimplementasikan Batch Apex. Batch Apex diekspos sebagai antarmuka yang harus diterapkan oleh pengembang. Pekerjaan batch dapat dijalankan secara terprogram saat runtime menggunakan Apex. Batch Apex beroperasi pada sejumlah kecil catatan, mencakup seluruh kumpulan catatan Anda dan memecah pemrosesan menjadi potongan data yang dapat dikelola.

Menggunakan Batch Apex

Saat kita menggunakan Batch Apex, kita harus mengimplementasikan antarmuka yang disediakan Salesforce Database.Batchable, lalu memanggil kelas secara terprogram.

Anda dapat memantau kelas dengan mengikuti langkah-langkah berikut -

Untuk memantau atau menghentikan pelaksanaan tugas batch Apex Batch, buka Pengaturan → Pemantauan → Pekerjaan Apex atau Pekerjaan → Pekerjaan Apex.

Database.Batchable interface memiliki tiga metode berikut yang perlu diimplementasikan -

  • Start
  • Execute
  • Finish

Mari kita sekarang memahami setiap metode secara rinci.

Mulailah

Metode Start adalah salah satu dari tiga metode antarmuka Database.Batchable.

Syntax

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

Metode ini akan dipanggil pada awal Pekerjaan Batch dan mengumpulkan data tempat pekerjaan Batch akan beroperasi.

Pertimbangkan poin-poin berikut untuk memahami metode -

  • Menggunakan Database.QueryLocatorobjek saat Anda menggunakan kueri sederhana untuk menghasilkan cakupan objek yang digunakan dalam pekerjaan batch. Dalam kasus ini, batas baris data SOQL akan dilewati.

  • Gunakan objek iterable saat Anda memiliki kriteria yang kompleks untuk memproses rekaman. Database.QueryLocator menentukan cakupan rekaman yang harus diproses.

Menjalankan

Mari kita sekarang memahami metode Execute dari antarmuka Database.Batchable.

Syntax

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

di mana, daftar <sObject <dikembalikan oleh metode Database.QueryLocator.

Metode ini dipanggil setelah metode Mulai dan melakukan semua pemrosesan yang diperlukan untuk Pekerjaan Batch.

Selesai

Sekarang kita akan membahas metode Selesai dari antarmuka Database.Batchable.

Syntax

global void finish(Database.BatchableContext BC) {}

Metode ini dipanggil di akhir dan Anda dapat melakukan beberapa aktivitas penyelesaian seperti mengirim email dengan informasi tentang catatan pekerjaan batch yang diproses dan statusnya.

Contoh Apex Batch

Mari kita pertimbangkan contoh Perusahaan Kimia kita yang ada dan asumsikan bahwa kita memiliki persyaratan untuk memperbarui bidang Status Pelanggan dan Deskripsi Pelanggan dari Catatan Pelanggan yang telah ditandai sebagai Aktif dan yang telah membuat Tanggal seperti hari ini. Ini harus dilakukan setiap hari dan email harus dikirim ke Pengguna tentang status Pemrosesan Batch. Perbarui Status Pelanggan sebagai 'Diproses' dan Deskripsi Pelanggan sebagai 'Diperbarui Melalui Pekerjaan Batch'.

// Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject> {
   global String [] email = new String[] {'[email protected]'};
   // Add here your email address here
  
   // Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
      APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
      AND APEX_Active__c = true');
      // Query which will be determine the scope of Records fetching the same
   }
   
   // Execute method
   global void execute (Database.BatchableContext BC, List<sobject> scope) {
      List<apex_customer__c> customerList = new List<apex_customer__c>();
      List<apex_customer__c> updtaedCustomerList = new List<apex_customer__c>();
      
      // List to hold updated customer
      for (sObject objScope: scope) {
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;
         
         // type casting from generic sOject to APEX_Customer__c
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         updtaedCustomerList.add(newObjScope); // Add records to the List
         System.debug('Value of UpdatedCustomerList '+updtaedCustomerList);
      }
      
      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
         // Check if List is empty or not
         Database.update(updtaedCustomerList); System.debug('List Size '
          + updtaedCustomerList.size());
         // Update the Records
      }
   }
   
   // Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      
      // Below code will fetch the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];
      
      // get the job Id
      System.debug('$$$ Jobid is'+BC.getJobId());
      
      // below code will send an email to User about the status
      mail.setToAddresses(email);
      mail.setReplyTo('[email protected]'); // Add here your email address
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed'
         + a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
      processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }
}

Untuk menjalankan kode ini, simpan dulu lalu tempel kode berikut di Jalankan anonim. Ini akan membuat objek kelas dan metode Database.execute akan menjalankan tugas Batch. Setelah pekerjaan selesai maka email akan dikirim ke alamat email yang ditentukan. Pastikan Anda memiliki catatan pelanggan yang memilikiActive seperti yang diperiksa.

// Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProessingBatch();
Database.executeBatch (objClass);

Setelah kelas ini dijalankan, periksa alamat email yang Anda berikan di mana Anda akan menerima email dengan informasi. Selain itu, Anda dapat memeriksa status tugas batch melalui halaman Pemantauan dan langkah-langkah seperti yang disediakan di atas.

Jika Anda memeriksa log debug, Anda dapat menemukan ukuran Daftar yang menunjukkan berapa banyak catatan yang telah diproses.

Limitations

Kami hanya dapat memiliki 5 pemrosesan pekerjaan batch dalam satu waktu. Ini adalah salah satu batasan Batch Apex.

Menjadwalkan Apex Batch Job menggunakan Apex Detail Page

Anda dapat menjadwalkan kelas Apex melalui halaman detail Apex seperti yang diberikan di bawah ini -

Step 1 - Pergi ke Setup ⇒ Apex Classes, Klik pada Apex Classes.

Step 2 - Klik pada tombol Jadwalkan Apex.

Step 3 - Berikan detailnya.

Menjadwalkan Pekerjaan Batch Apex menggunakan Antarmuka Terjadwal

Anda dapat menjadwalkan Apex Batch Job menggunakan Schedulable Interface seperti yang diberikan di bawah ini -

// Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject> {
   global String [] email = new String[] {'[email protected]'};
   // Add here your email address here
   
   // Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
      APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
      AND APEX_Active__c = true');
      // Query which will be determine the scope of Records fetching the same
   }
   
   // Execute method
   global void execute (Database.BatchableContext BC, List<sobject> scope) {
      List<apex_customer__c> customerList = new List<apex_customer__c>();
      List<apex_customer__c> updtaedCustomerList = new
      List<apex_customer__c>();//List to hold updated customer
      
      for (sObject objScope: scope) {
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;//type
         casting from generic sOject to APEX_Customer__c
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         updtaedCustomerList.add(newObjScope);//Add records to the List
         System.debug('Value of UpdatedCustomerList '+updtaedCustomerList);
      }
      
      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
         // Check if List is empty or not
         Database.update(updtaedCustomerList); System.debug('List Size'
            + updtaedCustomerList.size());
         // Update the Records
      }
   }
 
   // Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      
      // Below code will fetch the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];//get the job Id
      System.debug('$$$ Jobid is'+BC.getJobId());
      
      // below code will send an email to User about the status
      mail.setToAddresses(email);
      mail.setReplyTo('[email protected]');//Add here your email address
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed' 
         + a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
      processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }
   
   // Scheduler Method to scedule the class
   global void execute(SchedulableContext sc) {
      CustomerProessingBatch conInstance = new CustomerProessingBatch();
      database.executebatch(conInstance,100);
   }
}

// Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProcessingBatch();
Database.executeBatch (objClass);

Debugging adalah bagian penting dalam pengembangan pemrograman apa pun. Di Apex, kami memiliki alat tertentu yang dapat digunakan untuk debugging. Salah satunya adalah metode system.debug () yang mencetak nilai dan keluaran variabel di log debug.

Kita dapat menggunakan dua alat berikut untuk debugging -

  • Konsol Pengembang
  • Log Debug

Debugging melalui Konsol Pengembang

Anda dapat menggunakan konsol Pengembang dan menjalankan fungsionalitas anonim untuk men-debug Apex seperti di bawah ini -

Example

Pertimbangkan contoh kami saat ini dalam mengambil catatan pelanggan yang telah dibuat hari ini. Kami hanya ingin tahu apakah kueri mengembalikan hasil atau tidak dan jika ya, maka kami akan memeriksa nilai Daftar.

Tempel kode yang diberikan di bawah ini dalam mengeksekusi jendela anonim dan ikuti langkah-langkah yang telah kita lakukan untuk membuka jendela eksekusi anonim.

Step 1 - Buka konsol Pengembang

Step 2 - Buka Jalankan anonim dari 'Debug' seperti yang ditunjukkan di bawah ini.

Step 3 - Buka jendela Execute Anonymous dan tempel kode berikut dan klik jalankan.

// Debugging The Apex
List<apex_customer__c> customerList = new List<apex_customer__c>();
customerList = [SELECT Id, Name FROM APEX_Customer__c WHERE CreatedDate =
today];
// Our Query
System.debug('Records on List are '+customerList+' And Records are '+customerList);
// Debug statement to check the value of List and Size

Step 4 - Buka Log seperti yang ditunjukkan di bawah ini.

Step 5 - Masukkan 'USER' dalam kondisi filter seperti yang ditunjukkan di bawah ini.

Step 6 - Buka Pernyataan USER DEBUG seperti yang ditunjukkan di bawah ini.

Debugging melalui Log Debug

Anda juga dapat men-debug kelas yang sama melalui log debug. Misalkan, Anda memiliki pemicu di objek Pelanggan dan perlu di-debug untuk beberapa nilai variabel, maka Anda dapat melakukannya melalui log debug seperti yang ditunjukkan di bawah ini -

Ini adalah Kode Pemicu yang memperbarui bidang Deskripsi jika pelanggan yang diubah aktif dan Anda ingin memeriksa nilai variabel dan rekaman yang saat ini ada dalam cakupan -

trigger CustomerTrigger on APEX_Customer__c (before update) {
   List<apex_customer__c> customerList = new List<apex_customer__c>();
   for (APEX_Customer__c objCust: Trigger.new) {
      System.debug('objCust current value is'+objCust);
      
      if (objCust.APEX_Active__c == true) {
         objCust.APEX_Customer_Description__c = 'updated';
         System.debug('The record which has satisfied the condition '+objCust);
      }
   }
}

Ikuti langkah-langkah yang diberikan di bawah ini untuk menghasilkan log Debug.

Step 1- Setel log Debug untuk pengguna Anda. Pergi ke Setup dan ketik 'Debug Log' di jendela pengaturan pencarian dan kemudian klik Link.

Step 2 - Setel log debug sebagai berikut.

Step 3- Masukkan nama Pengguna yang membutuhkan pengaturan. Masukkan nama Anda disini.

Step 4 - Ubah catatan pelanggan sebagai peristiwa harus terjadi untuk menghasilkan log debug.

Step 5- Sekarang pergi ke bagian log debug lagi. Buka log debug dan klik Reset.

Step 6 - Klik tautan tampilan dari log debug pertama.

Step 7 - Cari string 'USER' dengan menggunakan pencarian browser seperti yang ditunjukkan di bawah ini.

Pernyataan debug akan menunjukkan nilai bidang di mana kita telah menetapkan titiknya.

Pengujian adalah bagian terintegrasi dari Apex atau pengembangan aplikasi lainnya. Di Apex, kami memiliki kelas pengujian terpisah untuk dikembangkan untuk semua pengujian unit.

Kelas Tes

Di SFDC, kode harus memiliki cakupan kode 75% untuk digunakan ke Produksi. Cakupan kode ini dilakukan oleh kelas uji. Kelas pengujian adalah cuplikan kode yang menguji fungsionalitas kelas Apex lainnya.

Mari kita tulis kelas uji untuk salah satu kode kita yang telah kita tulis sebelumnya. Kami akan menulis kelas pengujian untuk mencakup kode kelas Pemicu dan Pembantu kami. Di bawah ini adalah kelas trigger dan helper yang perlu dibahas.

// Trigger with Helper Class
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   CustomerTriggerHelper.createInvoiceRecords(Trigger.new, trigger.oldMap);
      //Trigger calls the helper class and does not have any code in Trigger
}

// Helper Class:
public class CustomerTriggerHelper {
   public static void createInvoiceRecords (List<apex_customer__c>
      
      customerList, Map<id, apex_customer__c> oldMapCustomer) {
      List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
      
      for (APEX_Customer__c objCustomer: customerList) {
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            oldMapCustomer.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
            
            // condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            objInvoice.APEX_Customer__c = objCustomer.id;
            InvoiceList.add(objInvoice);
         }
      }
      insert InvoiceList;  // DML to insert the Invoice List in SFDC
   }
}

Membuat Kelas Tes

Di bagian ini, kita akan memahami cara membuat Kelas Tes.

Pembuatan Data

Kita perlu membuat data untuk kelas pengujian di kelas pengujian itu sendiri. Kelas pengujian secara default tidak memiliki akses ke data organisasi tetapi jika Anda menyetel @isTest (lihatAllData = true), maka itu akan memiliki akses ke data organisasi juga.

Anotasi @isTest

Dengan menggunakan anotasi ini, Anda menyatakan bahwa ini adalah kelas pengujian dan tidak akan dihitung terhadap batas kode total organisasi.

kata kunci testMethod

Metode pengujian unit adalah metode yang tidak mengambil argumen, tidak memasukkan data ke database, tidak mengirim email, dan dideklarasikan dengan kata kunci testMethod atau anotasi isTest dalam definisi metode. Selain itu, metode pengujian harus ditentukan dalam kelas pengujian, yaitu kelas yang dianotasi dengan isTest.

Kami telah menggunakan metode pengujian 'myUnitTest' dalam contoh kami.

Test.startTest () dan Test.stopTest ()

Ini adalah metode pengujian standar yang tersedia untuk kelas pengujian. Metode ini berisi peristiwa atau tindakan yang akan kami simulasi pengujiannya. Seperti dalam contoh ini, kami akan menguji kelas pemicu dan penolong kami untuk mensimulasikan pemicu kebakaran dengan memperbarui catatan seperti yang telah kami lakukan untuk memulai dan menghentikan blok. Ini juga memberikan batas gubernur terpisah untuk kode yang ada di blok start dan stop.

System.assert ()

Metode ini memeriksa keluaran yang diinginkan dengan yang sebenarnya. Dalam kasus ini, kami mengharapkan catatan Faktur dimasukkan jadi kami menambahkan assert untuk memeriksa hal yang sama.

Example

/**
* This class contains unit tests for validating the behavior of Apex classes
* and triggers.
*
* Unit tests are class methods that verify whether a particular piece
* of code is working properly. Unit test methods take no arguments,
* commit no data to the database, and are flagged with the testMethod
* keyword in the method definition.
*
* All test methods in an organization are executed whenever Apex code is deployed
* to a production organization to confirm correctness, ensure code
* coverage, and prevent regressions. All Apex classes are
* required to have at least 75% code coverage in order to be deployed
* to a production organization. In addition, all triggers must have some code coverage.
*
* The @isTest class annotation indicates this class only contains test
* methods. Classes defined with the @isTest annotation do not count against
* the organization size limit for all Apex scripts.
*
* See the Apex Language Reference for more information about Testing and Code Coverage.
*/

@isTest
private class CustomerTriggerTestClass {
   static testMethod void myUnitTest() {
      //Create Data for Customer Objet
      APEX_Customer__c objCust = new APEX_Customer__c();
      objCust.Name = 'Test Customer';
      objCust.APEX_Customer_Status__c = 'Inactive';
      insert objCust;
      
      // Now, our trigger will fire on After update event so update the Records
      Test.startTest();    // Starts the scope of test
      objCust.APEX_Customer_Status__c = 'Active';
      update objCust;
      Test.stopTest();     // Ends the scope of test
      
      // Now check if it is giving desired results using system.assert
      // Statement.New invoice should be created
      List<apex_invoice__c> invList = [SELECT Id, APEX_Customer__c FROM
         APEX_Invoice__c WHERE APEX_Customer__c = :objCust.id];
      system.assertEquals(1,invList.size());
      // Check if one record is created in Invoivce sObject
   }
}

Menjalankan Kelas Tes

Ikuti langkah-langkah yang diberikan di bawah ini untuk menjalankan kelas pengujian -

Step 1 - Pergi ke kelas Apex ⇒ klik pada nama kelas 'CustomerTriggerTestClass'.

Step 2 - Klik tombol Jalankan Tes seperti yang ditunjukkan.

Step 3 - Periksa status

Step 4 - Sekarang periksa kelas dan pemicu yang telah kami tulis tesnya

Kelas

Pelatuk

Pengujian kami berhasil dan selesai.

Apa itu Deployment di SFDC?

Sampai sekarang kami telah mengembangkan kode dalam Edisi Pengembang, tetapi dalam skenario kehidupan nyata, Anda harus melakukan pengembangan ini di Kotak Pasir dan kemudian Anda mungkin perlu menerapkannya ke kotak pasir atau lingkungan produksi lain dan ini disebut penerapan. Singkatnya, ini adalah perpindahan metadata dari satu organisasi ke organisasi lain. Alasan di balik ini adalah Anda tidak dapat mengembangkan Apex di organisasi produksi Salesforce. Pengguna langsung yang mengakses sistem saat Anda mengembangkan dapat membuat data Anda tidak stabil atau aplikasi Anda rusak.

Alat tersedia untuk penerapan -

  • Force.com IDE
  • Ubah Set
  • SOAP API
  • Alat Migrasi Force.com

Karena kami menggunakan Edisi Pengembang untuk tujuan pengembangan dan pembelajaran kami, kami tidak dapat menggunakan Kumpulan Perubahan atau alat lain yang membutuhkan SFDC enterprise atau edisi berbayar lainnya. Karenanya, kami akan menguraikan metode penerapan IDE Force.com dalam tutorial ini.

Force.com Eclipse IDE

Step 1 - Buka Eclipse dan buka pemicu kelas yang perlu diterapkan.

Step 2 - Setelah Anda mengklik 'Deploy to server', lalu masukkan nama pengguna dan kata sandi organisasi di mana Komponen perlu digunakan.

Dengan melakukan langkah-langkah yang disebutkan di atas, komponen Apex Anda akan diterapkan ke organisasi target.

Deployment menggunakan Change Set

Anda dapat menerapkan aturan Validasi, aturan alur kerja, kelas Apex, dan Pemicu dari satu organisasi ke organisasi lain dengan menghubungkannya melalui pengaturan penerapan. Dalam hal ini, organisasi harus terhubung.

Untuk membuka penyiapan penerapan, ikuti langkah-langkah yang diberikan di bawah ini. Ingatlah bahwa fitur ini tidak tersedia di Edisi Pengembang -

Step 1 - Buka Setup dan cari 'Deploy'.

Step 2 - Klik 'Kumpulan Perubahan Keluar' untuk membuat kumpulan perubahan untuk diterapkan.

Step 3 - Tambahkan komponen untuk mengubah set menggunakan tombol 'Tambah' dan kemudian Simpan dan klik Unggah.

Step 4 - Pergi ke organisasi Target dan klik pada set perubahan masuk dan terakhir klik pada penerapan.

Panggilan SOAP API untuk Menerapkan

Kami hanya akan memiliki gambaran kecil tentang metode ini karena ini bukan metode yang umum digunakan.

Anda dapat menggunakan panggilan metode yang diberikan di bawah ini untuk menerapkan metadata Anda.

  • compileAndTest()
  • compileClasses()
  • compileTriggers()

Alat Migrasi Force.com

Alat ini digunakan untuk penerapan skrip. Anda harus mengunduh alat Migrasi Force.com dan kemudian Anda dapat melakukan penyebaran berbasis file. Anda dapat mengunduh alat migrasi Force.com dan kemudian melakukan penerapan skrip.