0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Salesforce Apex 実践的重要用語集

Posted at

image.png

クイックリファレンス

用語 説明 重要度
Apex Salesforceプラットフォーム用のオブジェクト指向プログラミング言語。Javaに似た構文を持つ。 ★★★
SOQL Salesforce Object Query Language の略。データベースからレコードを取得するための専用クエリ言語。 ★★★
DML Data Manipulation Language の略。データの作成・更新・削除などの操作を行う。 ★★★
Trigger データベースの変更(挿入・更新・削除)時に自動的に実行されるApexコード。 ★★★
sObject Salesforceのデータベースレコードを表現する基本データ型。 ★★★
Governor Limits マルチテナント環境での安定性を確保するためのリソース使用制限。 ★★★
Test Class コードの品質を保証するためのテストコード。本番環境へのデプロイには75%以上のカバレッジが必要。 ★★★
Queueable Apex 推奨される非同期処理の実装方法。状態保持や連鎖実行が可能。Future Methodの後継。 ★★★
Batch Apex 大量のレコードを非同期で処理するための仕組み。 ★★
Future Method 従来の非同期処理方式。特定のユースケースを除き、Queueable Apexが推奨。
Visualforce 従来のUIフレームワーク。新規開発ではLWCが推奨。
Lightning Web Components (LWC) モダンなWeb標準に基づくUIフレームワーク。現在の推奨UI開発手法。 ★★★
Apex Scheduler 定期的に実行される処理をスケジュールするための仕組み。 ★★

基本概念

image.png

Apexとは

Salesforceプラットフォーム専用のオブジェクト指向プログラミング言語です。Java/C#に似た構文を持ち、以下の特徴があります:

  • 強力な型システム(コンパイル時のエラーチェック)
  • データベースとの統合(SOQLやDMLが言語に組み込まれている)
  • トランザクション管理の自動化
  • マルチテナント環境に最適化された実行制御(Governor Limits)
// Apexの基本的な構文例
public class HelloWorld {
    private String greeting;
    
    public HelloWorld() {
        this.greeting = 'Hello, Salesforce!';
    }
    
    public void printGreeting() {
        System.debug(greeting);
    }
}

データ操作の基礎

sObject

Salesforceのすべてのデータベースレコードを表現する基本データ型です。標準オブジェクトとカスタムオブジェクトの両方に対応します。

// 標準オブジェクトの操作
Account acc = new Account(
    Name = 'Example Corp',
    Industry = 'Technology'
);

// カスタムオブジェクトの操作
Custom_Object__c obj = new Custom_Object__c(
    Name = 'Custom Record',
    Custom_Field__c = 'Value'
);

// 動的なsObject生成
SObject dynamicObj = (SObject)Type.forName('Account').newInstance();

SOQL (Salesforce Object Query Language)

データベースからレコードを取得するための専用クエリ言語です。リレーションシップの横断やサブクエリもサポートしています。

// 基本的なクエリ
List<Account> tecAccounts = [
    SELECT Id, Name, Industry
    FROM Account 
    WHERE Industry = 'Technology'
    LIMIT 100
];

// リレーションを含むクエリ
List<Account> accountsWithContacts = [
    SELECT Id, Name, 
        (SELECT Id, FirstName, LastName 
         FROM Contacts 
         WHERE Email != NULL)
    FROM Account
    WHERE Type = 'Customer'
];

// 集計クエリ
AggregateResult[] groupedResults = [
    SELECT Industry, COUNT(Id) totalAccounts
    FROM Account
    GROUP BY Industry
    HAVING COUNT(Id) > 5
];

DML (Data Manipulation Language)

データベースレコードを作成、更新、削除するための操作セットです。

// 基本的なDML操作
Account newAccount = new Account(Name = 'New Corp');
insert newAccount;  // 作成

newAccount.Industry = 'Technology';
update newAccount;  // 更新

delete newAccount;  // 削除

// バルクDML(推奨される使用方法)
List<Account> accountsToUpdate = new List<Account>();
for(Account acc : [SELECT Id FROM Account WHERE Industry = NULL]) {
    acc.Industry = 'Other';
    accountsToUpdate.add(acc);
}
update accountsToUpdate;  // 一括更新

// upsert操作(存在すれば更新、なければ作成)
List<Contact> contacts = new List<Contact>();
contacts.add(new Contact(Email = 'test@example.com', LastName = 'Doe'));
upsert contacts Email;  // Emailフィールドを一意キーとして使用

制御と自動化

image.png

トリガー

データベースの変更イベントに応答して自動実行されるApexコードです。

trigger AccountTrigger on Account (before insert, after insert, 
    before update, after update) {
    
    // beforeトリガーでの入力検証
    if (Trigger.isBefore) {
        for(Account acc : Trigger.new) {
            if (acc.Industry == null) {
                acc.Industry = 'Other';
            }
        }
    }
    
    // afterトリガーでの関連レコード作成
    if (Trigger.isAfter && Trigger.isInsert) {
        List<Contact> defaultContacts = new List<Contact>();
        for(Account acc : Trigger.new) {
            defaultContacts.add(new Contact(
                AccountId = acc.Id,
                LastName = 'Default Contact'
            ));
        }
        insert defaultContacts;
    }
}

非同期処理

Future Methods

非同期で実行される処理を定義する従来の方法です。現在は特定のユースケースを除き、Queueable Apexの使用が推奨されています。

主な用途:

  • 外部システムの呼び出し(特にHTTP Callout)
  • 非同期での単純な処理実行

制限値:

  • 1トランザクションあたりの呼び出し回数:50回まで
  • 同時実行数:最大50
  • メソッドの引数として使用可能な型に制限あり(primitive型のみ)
public class AsyncProcessor {
    @future(callout=true)  // HTTP Calloutを行う場合はcallout=trueが必要
    public static void processRecordsAsync(Set<Id> recordIds) {
        List<Account> accounts = [SELECT Id, Name FROM Account WHERE Id IN :recordIds];
        // 外部システム呼び出しや重い処理を実行
    }
}

// 呼び出し例
AsyncProcessor.processRecordsAsync(new Set<Id>{'001xx000003Gxxx'});

注意点:

  • 新規開発では可能な限りQueueable Apexの使用を検討してください
  • Future Methodは引数の型に制限があり、複雑なデータの受け渡しが困難です
  • 処理の状態監視や連鎖実行が難しい構造になっています

Queueable Apex

Future Methodの後継として推奨される非同期処理の実装方法です。コンストラクタでの状態保持や連鎖実行が可能です。

制限値:

  • 連鎖実行の深さ:最大50
  • 同時実行数:最大50
  • インスタンス変数としてあらゆる型が使用可能
public class AccountQueueable implements Queueable {
    private List<Account> accounts;
    
    public AccountQueueable(List<Account> accounts) {
        this.accounts = accounts;  // コンストラクタで状態を保持可能
    }
    
    public void execute(QueueableContext context) {
        // 非同期処理の実装
        for(Account acc : accounts) {
            // 処理ロジック
        }
        
        // 連鎖実行の例
        if(accounts.size() > 0) {
            System.enqueueJob(new AnotherQueueable(accounts));
        }
    }
}

// 実行例
List<Account> accountsToProcess = [SELECT Id FROM Account LIMIT 100];
System.enqueueJob(new AccountQueueable(accountsToProcess));

主な特徴:

  • 複雑なデータ構造の受け渡しが可能
  • 処理の連鎖実行(chaining)がサポート
  • 処理状態の監視が容易
  • テストでの実行制御が向上

Batch Apex

大量のレコードを処理するための非同期バッチ処理フレームワークです。
処理するレコード数が多い場合や、長時間の処理が必要な場合に使用します。

制限値:

  • バッチサイズ:最大2,000レコード
  • 同時実行数:最大5(開発者版組織は1)
  • 1日あたりの実行回数:250,000回まで
  • 実行時間:最大24時間
public class AccountNameUpdateBatch implements Database.Batchable<sObject> {
    
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT Id, Name FROM Account');
    }
    
    public void execute(Database.BatchableContext bc, List<Account> scope) {
        List<Account> toUpdate = new List<Account>();
        for(Account acc : scope) {
            acc.Name = acc.Name + ' Updated';
            toUpdate.add(acc);
        }
        update toUpdate;
    }
    
    public void finish(Database.BatchableContext bc) {
        System.debug('Batch job completed');
    }
}

// バッチの実行
Database.executeBatch(new AccountNameUpdateBatch(), 200);

Schedulable Interface

定期的に実行される必要があるジョブを定義します。cron式を使用してスケジュール設定が可能です。

制限値:

  • 同時スケジュール可能数:100
  • cron式による最小実行間隔:1時間
  • 1組織あたりのスケジュールジョブ数:25
public class DailyAccountCleanup implements Schedulable {
    public void execute(SchedulableContext sc) {
        // 日次処理のロジック
    }
}

// ジョブのスケジュール(毎日午前3時に実行)
String cronExp = '0 0 3 * * ?';
System.schedule('Daily Account Cleanup', cronExp, new DailyAccountCleanup());

開発のベストプラクティス

image.png

Governor Limits への対応

Salesforceプラットフォームの安定性を確保するための実行制限です。主な制限値:

  • SOQL クエリ:トランザクションあたり100回まで
  • DML操作:トランザクションあたり150回まで
  • ヒープサイズ:6MB
  • CPU時間:10秒
// 制限値の確認方法
System.debug('SOQL使用回数: ' + 
    Limits.getQueries() + '/' + Limits.getLimitQueries());

// 良い実装例(バルク処理)
Set<Id> accountIds = new Set<Id>();
for(Account acc : Trigger.new) {
    accountIds.add(acc.Id);
}
// 1回のクエリで必要なデータをすべて取得
List<Contact> contacts = [SELECT Id, AccountId 
    FROM Contact 
    WHERE AccountId IN :accountIds];

// 悪い実装例(避けるべき)
for(Account acc : Trigger.new) {
    // ループ内でクエリを実行(制限に抵触する可能性が高い)
    List<Contact> contacts = [SELECT Id 
        FROM Contact 
        WHERE AccountId = :acc.Id];
}

テスト

すべてのApexコードは75%以上のコードカバレッジが必要です。

@isTest
private class AccountServiceTest {
    @testSetup
    static void setup() {
        // テストデータのセットアップ
        Account testAcc = new Account(Name = 'Test Account');
        insert testAcc;
    }
    
    @isTest
    static void testAccountUpdate() {
        // テストの実行
        Account acc = [SELECT Id FROM Account LIMIT 1];
        
        Test.startTest();
        acc.Industry = 'Technology';
        update acc;
        Test.stopTest();
        
        // 結果の検証
        Account updatedAcc = [SELECT Industry FROM Account WHERE Id = :acc.Id];
        System.assertEquals('Technology', updatedAcc.Industry);
    }
}

UI開発

Lightning Web Components (LWC)

最新のWeb標準に基づくUIフレームワークです。

// myComponent.js
import { LightningElement, api } from 'lwc';

export default class MyComponent extends LightningElement {
    @api recordId;
    
    handleClick() {
        // クリックイベントの処理
    }
}
<!-- myComponent.html -->
<template>
    <lightning-card title="My Component">
        <div class="slds-p-around_medium">
            <lightning-button 
                label="Click Me"
                onclick={handleClick}>
            </lightning-button>
        </div>
    </lightning-card>
</template>

まとめ

image.png

Apexを効果的に使用するためのポイント:

  1. バルク処理を意識したコード設計
  2. Governor Limitsを考慮したリソース管理
  3. 適切なテストカバレッジの確保
  4. 非同期処理の効果的な活用
  5. モダンなUI開発(LWC)の採用

これらの概念を理解し、適切に組み合わせることで、堅牢なSalesforceアプリケーションの開発が可能になります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?