Salesforce Apex 実践的重要用語集

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e845ec07-8af6-ea13-ba39-320067032aa7.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/fb283d3b-208b-b868-8b2f-c9f7954a47b6.png)

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

- 強力な型システム（コンパイル時のエラーチェック）
- データベースとの統合（SOQLやDMLが言語に組み込まれている）
- トランザクション管理の自動化
- マルチテナント環境に最適化された実行制御（Governor Limits）

```apex
// Apexの基本的な構文例
public class HelloWorld {
    private String greeting;
    
    public HelloWorld() {
        this.greeting = 'Hello, Salesforce!';
    }
    
    public void printGreeting() {
        System.debug(greeting);
    }
}
```

### データ操作の基礎

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

```apex
// 標準オブジェクトの操作
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)
データベースからレコードを取得するための専用クエリ言語です。リレーションシップの横断やサブクエリもサポートしています。

```apex
// 基本的なクエリ
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)
データベースレコードを作成、更新、削除するための操作セットです。

```apex
// 基本的な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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/9813bf21-dfe7-5bba-b490-1bbecf6a3bc7.png)

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

```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型のみ）

```apex
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
- インスタンス変数としてあらゆる型が使用可能

```apex
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時間

```apex
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

```apex
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/588f0647-c5cc-5899-27f6-eee71e9cad07.png)


### Governor Limits への対応
Salesforceプラットフォームの安定性を確保するための実行制限です。主な制限値：

- SOQL クエリ：トランザクションあたり100回まで
- DML操作：トランザクションあたり150回まで
- ヒープサイズ：6MB
- CPU時間：10秒

```apex
// 制限値の確認方法
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%以上のコードカバレッジが必要です。

```apex
@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フレームワークです。

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

export default class MyComponent extends LightningElement {
    @api recordId;
    
    handleClick() {
        // クリックイベントの処理
    }
}
```

```html
<!-- 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/d53d08d1-221c-815a-40ef-cc6db818b9fe.png)


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

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

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