Wherever you want to perform some operation on bulk data the Batch Class is the right option for that.
Here I am going to explain the steps of how a batch class can be implemented….
declare a batch class
global class TestBatchClass implements Database.Batchable <Sobject>,Database.Stateful{
public Id accountId{get;set;}
}
The syntex will be same for all batch classes you only need to change the class name “TestBatchClass”.
Here I am taking an example of account updation, suppose we want to perform some operation on accounts than we need to take a property accountId in the batch class. This property will be used when we create test class for this batch class.
In below lines I am declaring constructor for the batch class
public TestBatchClass(){
}
public TestBatchClass (Id accountId){
this.accountId = accountId;
}
One noticeable point is second constructor will be used when we write test
class for this batch class. You can avoid the parameterize constructor if does not
required in your case.
//--------------------------------------------------------------//
//Start Method :->
//-------------------------------------------------------------//
global Database.Querylocator start(Database.BatchableContext ctx){
return null;
}
As per the name start method will be called as the class start execution. In this method
you need to change the query as per you requirement. For Eg we are using a query to get
accounts on which we will perform some operations.
if(test.isrunningTest()) {
return Database.getQueryLocator([select Id,Name from Account limit 5]);
}
else{
return Database.getQueryLocator([select Id,Name from Account where Id=: accountId]);
}
Here one noticeable point is there are two queries to get the accounts. Test.isrunninTest
checks and execute the first query if we are calling this batch class from test class, it
will useful because we should not perform the batch logic for thousands of account if it is
calling from Test class.
//--------------------------------------------------------------//
//Execute method
//-------------------------------------------------------------//
global void execute(Database.BatchableContext ctx, List<Account>){
}
Execute method is the most important method of the batch class, here you need to write the
logic on the basis of you want to perform update/insert/delete operation. For Eg if we need
to change a field the fetched accounts than the code will be look like as below-
List<Account> listOfAccounts = (List<Account>)scope;
List<Account> listOfAccountsUpdated = new List<Account>();
Account newAccount;
for(Account acct :listOfAccounts) {
newAccount = new Account(Id = acct.Id);
newAccount.checked__c = true;
listOfAccountsUpdated.add(newAccount);
}
If(listOfAccountsUpdated.Size()>0){
Update listOfAccountsUpdated;
}
At the end of the batch class there is finish method, generally you need not to write any
code in this method, you can write some code if there is any specific requirement at the
end of batch execution. for eg. send a mail in finish.
//--------------------------------------------------------//
//Finish method
//----------------------------------------------------------//
global void finish(Database.BatchableContext ctx){
}
The whole class code will be look like as below-
The whole class code will be look like as below-
global class TestBatchClass implements Database.Batchable <Sobject>, Database.Stateful {
public Id accountId{get;set;}
public TestBatchClass(){
}
public TestBatchClass (Id accountId){
this.accountId = accountId;
}
//--------------------------------------------------------//
//Start Method :->
//----------------------------------------------------------//
global Database.Querylocator start(Database.BatchableContext ctx){
if(test.isrunningTest()) {
return Database.getQueryLocator([
select Id,Name from Account limit 5]);
}
else{
return Database.getQueryLocator([
select Id,Name from Account where Id=: accountId]);
}
}
//--------------------------------------------------------//
//Execute method
//---------------------------------------------------------//
global void execute(Database.BatchableContext ctx, List<Account> scope){
List<Account> listOfAccounts = (List<Account>)scope;
List<Account> listOfAccountsUpdated = new List<Account>();
Account newAccount;
for(Account acct :listOfAccounts) {
newAccount = new Account(Id = acct.Id);
newAccount.checked__c = true;
listOfAccountsUpdated.add(newAccount);
}
If(listOfAccountsUpdated.Size()>0){
Update listOfAccountsUpdated;
}
}
//-------------------------------------------------------//
//Finish method
//--------------------------------------------------------//
global void finish(Database.BatchableContext ctx){
}
it's done..!!
If you want to test this batch class then open the system log & execute below lines of
code
TestBatchClass obj = new TestBatchClass ();
Database.executeBatch(obj,5);
In execute batch you can specify how many records need to take in a batch, for example we
are taking 5. Generally we should not take more than 200 for this.
Now you can check the implementation flow/bugs in the system log detail & manipulate the
logic of the batch class.
After executing this batch class sometimes you will not able to save data in the class if
there any error thrown in by batch class & batch class not execute successfully. For this
you need to go to Setup->Monitoring->Apex Jobs & then Abort the job. In our case it will be
“TestBatchClass”.
Happy Coding...!!