(最終更新月: 2024年2月)
✔以下の疑問をお持ちの方へ向けた記事です
「Salesforce Apexでデータベース操作を行う基本的な方法は?」
「ApexでのデータベースクエリやDML操作のベストプラクティスは?」
「Apexでのデータベース操作時にエラーハンドリングをどのように行うか?」
✔当記事を読むことで得られる知識
- Salesforce Apexにおけるデータベース操作の基本概念
- SOQLクエリとDML(データ操作言語)操作の使用方法
- データベース操作時のエラーハンドリングとパフォーマンス最適化のヒント
Apexでは、SOQL(Salesforce Object Query Language)を使用してデータをクエリし、DML(Data Manipulation Language)ステートメントを使用してデータを操作します。
当記事では、効率的なSOQLクエリの書き方、DML操作のベストプラクティス、およびエラーハンドリングやパフォーマンス最適化のための重要な考慮事項に焦点を当てます。
Salesforceの開発者にとって、データベース操作の効率を高め、アプリケーションの信頼性を向上させるためのガイドとなるでしょう。
ぜひ最後までご覧ください。
Apexにおけるデータベース操作の基礎
こちらでは、Apexを使用したSalesforceデータベースの操作の基礎についてご紹介します。
データベース操作の基礎を把握することは、Salesforce上でのアプリ開発やデータ整理に不可欠です。
- ApexとSalesforceデータベースの関係
- SOQLとSOSLクエリの基本
- DML操作の概要
ApexとSalesforceデータベースの関係
Apexは、Salesforceデータベースとの連携に特化しています。
なぜなら、Salesforceのオブジェクト指向プログラミング言語だからです。
Salesforceデータベースには、主に以下の2オブジェクトがあり、Apexを通じてこれらのデータを操作できます。
- 標準オブジェクト(例:Account、Contact)
- カスタムオブジェクト(例: CustomObj__c)
Account myAccount = new Account(Name='Acme', Type='Customer');
新しいアカウントレコードを作成し、それをデータベースに保存する準備をします。
こうしたコードを書くためには、Salesforceデータモデルの理解が必要です。
SOQLとSOSLクエリの基本
SOQL(Salesforce Object Query Language)とSOSL(Salesforce Object Search Language)は、Salesforceデータベースに対して問い合わせをおこなうための言語です。
SOQLはオブジェクト間の関係を指定して、特定のデータを抽出する際に用います。
SELECT Name FROM Account;
全アカウントの名前を取得できます。
一方、SOSLはよりテキストベースの検索をおこない、複数のオブジェクトからデータを検索する際に優れています。
FIND 'Acme*' IN ALL FIELDS RETURNING Account (Id, Name)
‘Acme’で始まる任意のテキストをアカウントの全フィールドから検索し、対応するレコードのIDと名前を返します。
DML操作の概要
DML(Data Manipulation Language)操作は、以下などをおこなう手段です。
- データの挿入(Insert)
- 更新(Update)
- 削除(Delete)
Apexコード内でDML文を使用することで、Salesforceデータベースにレコードを持続させたり、既存のデータを変更したりが可能。
例えば、先に作成したmyAccount
オブジェクトをデータベースに保存するためには、以下のDML文を実行します。
insert myAccount;
このようなDML操作を理解し、適切に使用することが、効率的なデータ管理につながります。
DML操作の詳細
データベース操作の中で、DML操作は特に重要です。
これらの操作を適切におこなうことで、データ整合性を保ちつつ、アプリケーションの要件を満たせるでしょう。
- レコードの挿入(Insert)
- レコードの更新(Update)
- レコードの削除(Delete)と復元(Undelete)
- レコードの取得とロック(Upsert、Merge)
レコードの挿入(Insert)
レコードをSalesforceデータベースに新規作成したい場合、insert文を使用します。
例えば、新しいContactレコードを作成するには、まずContactオブジェクトのインスタンスを生成し、必要なフィールドに値を設定します。
以下はその一例です。
Contact newContact = new Contact(FirstName='Jane', LastName='Doe', Email='jane.doe@example.com');
insert newContact;
このコードはまずLinkedInにJane Doeという名前のコンタクトを作成し、続いてそのレコードをデータベースに挿入しています。
これが成功すると、newContact
には新しく作成されたレコードのIDが割り当てられます。
ガバナ制限などを考えると、レコードをひとつずつ処理するよりは、Listにしてまとめたinsertがおすすめ。
レコードの更新(Update)
既存のレコードに変更を加えたいときにはupdate文を使います。
例えば、特定のContactレコードの電話番号を更新するには、以下の手順を踏みます。
- 更新したいレコードを取得。
- レコードのフィールドに新しい値を設定。
- update文を実行。
Contact contactToUpdate = [SELECT Id, Phone FROM Contact WHERE Email='jane.doe@example.com' LIMIT 1];
contactToUpdate.Phone = '123-456-7890';
update contactToUpdate;
このコードは最初にジェーン・ドウの連絡先を検索し、電話番号フィールドを新しい値に設定した後、変更をデータベースに更新しています。
レコードの削除(Delete)と復元(Undelete)
delete文を使うことでレコードを削除できます。一度削除されたレコードはゴミ箱に移動し、期間内であればundelete文を使用して復元することが可能です。
レコードを削除する一例を次に示します。
Contact contactToDelete = [SELECT Id FROM Contact WHERE LastName='Doe'];
delete contactToDelete;
そして、もし削除したレコードを復元する必要がある場合は、次のように実行します。
undelete contactToDelete;
これらの操作を使うと、誤って削除したレコードも安全に回復できます。
レコードの取得とロック(Upsert、Merge)
upsert
文はレコードの挿入または更新をひとつの操作でおこないます。
レコードが既に存在するかどうかに基づいて、必要に応じて新しいレコードを作成したり、既存のレコードを更新したりします。
また、merge
文を使用することで、重複するレコードを統合。
upsert
の使用例を見てみましょう。
Contact contact = new Contact(Email='john.doe@example.com', Phone='123-456-7890');
upsert contact Email;
このコードは、Email
フィールドを基にしてレコードがデータベースに存在するかを判断し、存在しなければ新規作成し、存在すれば電話番号を更新します。
SOQLクエリの実行
データ取得を行うにはSOQLクエリが必要です。
クエリの構築や結果の操作の方法を学ぶことで、効率的なデータアクセスが可能。
セレクタ、フィルタコンディション、ソートなど、使いこなせるようになりましょう。
- SOQLクエリの基本文法
- クエリの結果を操作する方法
- 集約関数とグループ化
SOQLクエリの基本文法
SOQLクエリの目的は、Salesforceデータベースから必要な情報を選択的に取得することです。
基本的なクエリ文法には、以下のような句が含まれます。
- SELECT
- FROM
- WHERE
クエリを実行し、条件に一致するレコードの集合取得。
例えば、すべてのアカウントのレコードを取得するために以下のようなクエリを利用します。
List<Account> accounts = [SELECT Id, Name FROM Account];
このクエリでは、SELECT
句でIdとNameのフィールドを指定し、FROM
句でAccountオブジェクト(つまりアカウントのレコード)を指定しています。
クエリの結果を操作する方法
取得したクエリの結果を、プログラム内でさらに操作できます。
LIMIT句やORDER BY句を使用して、結果を絞り込んだり、並べ替えたりすることも可能です。
例ば、最初の10件のアカウントレコードを名前順に取得するためには、次のようなクエリを記述します。
List<Account> accounts = [SELECT Id, Name FROM Account ORDER BY Name LIMIT 10];
ここでORDER BY Name
は結果を名前順に並び替えるためのもの、LIMIT 10
は結果を最初の10件に限定するためのものです。
集約関数とグループ化
ごく大まかなデータセットから意味のある情報を集約するために、集約関数を使用することがあります。
以下などがよく使われます。
- COUNT()
- SUM()
- MAX()
- MIN()
これらは、特定の条件に合致するレコードの数を数えたり、数値フィールドの合計や最大値、最小値を計算したりするために使うもの。
行をグループ化するGROUP BY
句もまた、似た属性を持つレコードをまとめる際に役立ちます。
例えば、各アカウントタイプごとのレコード数を知りたい場合、次のクエリを実行しましょう。
List<AggregateResult> results = [SELECT Type, COUNT(Id) FROM Account GROUP BY Type];
これにより、アカウントタイプごとに何件のレコードがあるかを取得できます。
Apexトランザクション管理
Apexコードでは、複数のDML操作を1つのトランザクションとして扱い、成功または失敗に応じてすべて確定するか、ロールバックするかを制御できます。
トランザクション管理にはエラー処理やバッチ処理の概念を理解することが必要です。
- トランザクションの概念
- トランザクション内でのエラー処理
- Apexのバッチ処理
トランザクションの概念
トランザクションは、一連の操作をひとつの単位として扱う概念です。
全操作が成功するとトランザクションはコミットされ、ひとつでも失敗すると全ての操作がロールバックされます。
Apexでは、トランザクションのスコープが自動的に管理され、DML操作が連結。
例えば、次のように複数のDML命令がひとつのトランザクション内で実行されます。
Database.Savepoint sp = Database.setSavepoint();
try {
Account a = new Account(Name='Test Account');
insert a;
Contact c = new Contact(LastName='Test Contact', AccountId=a.Id);
insert c;
} catch(Exception e) {
Database.rollback(sp);
}
トランザクションが成功すればアカウントとコンタクトの両方がデータベースに保存されますが、いずれかのinsertでエラーが発生した場合はロールバックされ、どちらのレコードも保存されません。
トランザクション内でのエラー処理
トランザクション中に何らかのエラーが生じた際には、適切なエラー処理が重要です。
try-catchブロックを使用して、DML操作中に発生することがある例外を捕捉し、適切なリカバリー処理またはロールバックをおこないます。
例えば、以下はひとつのアカウントレコードを挿入しようとするものの、失敗した際に処理をロールバックする例です。
try {
Account account = new Account(Name='Invalid Account ###');
insert account;
} catch(DmlException e) {
// エラーログを生成するなどのエラー処理を行う
System.debug('An error occurred: ' + e.getMessage());
// ここでロールバックが可能
}
このようにエラー処理を記述することで、予期せぬ障害に対処しトランザクションの整合性を保てます。
Apexのバッチ処理
大量のデータに対してDML操作を適用する必要がある場合、Apexのバッチクラスを利用して処理を分割し、ガバナ制限を超えないようにします。
バッチ処理を使用すると、大量のレコードを順次処理できるため、全データセットに一括で操作を適用するよりもシステムへの負荷を軽減できます。
次のサンプルコードはバッチ処理クラスの基本的な骨格です。
global class MyBatchClass implements Database.Batchable<sObject> {
global Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator('SELECT Id FROM Account');
}
global void execute(Database.BatchableContext BC, List<Account> records) {
// 何らかの処理
}
global void finish(Database.BatchableContext BC) {
// 処理完了後のクリーンアップ作業
}
}
このクラスを実行することで、指定したクエリに一致したすべてのアカウントに対する処理をバッチとして実行できます。
データベース操作のベストプラクティス
効率的で安全なデータベース操作を行うためのベストプラクティスを理解することは、Salesforceアプリケーションのパフォーマンスと信頼性を確保するために非常に重要です。
ガバナ制限を遵守し、適切なテストをおこない、セキュリティを保ちながらデータへのアクセスを管理することで、アプリケーションの総合的な品質を向上させられます。
- ガバナ制限とパフォーマンスの考慮
- テストクラスとデータベース操作
- 安全なデータアクセスパターン
ガバナ制限とパフォーマンスの考慮
ガバナ制限(Governor Limits)はSalesforce上でのリソース利用を規制するための仕組みです。
Apexを使用してデータベース操作の際は、これらの制限を意識してコードを記述する必要があります。
以下のテクニックを適用することでパフォーマンスを改善できます。
- まとめてDML操作する
- SOQLクエリを最適化する
- キャッシュを有効に使う
例えば、リストを使って複数のレコードを一度に挿入することで、DMLステートメントとSOQLクエリの数を削減できます。
List<Account> accountList = new List<Account>();
for(Integer i=0; i<200; i++) {
accountList.add(new Account(Name='Account '+i));
}
insert accountList;
この方法では200件のアカウントを一つのDML操作で挿入しています。
これによりガバナ制限のひとつである「単一トランザクション内のDMLステートメントの最大数」に違反することがなくなります。
テストクラスとデータベース操作
Apexコードにおけるテストクラスの作成は、コード動作の検証とデプロイ前の要件を満たすために不可欠です。
テストクラスでは、テストデータを生成し、それを用いてDML操作や他のApexロジックを実行します。
テストクラスの作成には@isTest
アノテーションを用い、テストデータをセットアップするためにTest.loadData()
やTest.setMock()
といったメソッドが使用されます。
以下のコードはテストクラスの例です。
@isTest
private class DatabaseOperationTest {
static testMethod void testInsertAccounts() {
List<Account> accounts = new List<Account>();
for(Integer i=0; i<5; i++) {
accounts.add(new Account(Name='Test Account '+i));
}
Test.startTest();
insert accounts;
Test.stopTest();
// 検証
System.assertEquals(5, [SELECT Count() FROM Account WHERE Name LIKE 'Test Account%']);
}
}
このテストメソッドは5件のアカウントを挿入し、実際に挿入されたかどうかを検証しています。
安全なデータアクセスパターン
データへのアクセスを安全におこなうためには、共有ルール、フィールドレベルのセキュリティ、プロファイル設定などを適切に設定し、ユーザが必要な権限のみを持つようにすることが必須です。
Apexコードでは、with sharing
またはwithout sharing
キーワードをクラス宣言に付加することで、データアクセスのセキュリティレベルを指定できます。
例えば、次のApexクラスは共有ルールに従ってデータにアクセスすることを保証します。
public with sharing class SecureDataAccess {
public List<Account> getAccounts() {
return [SELECT Id, Name FROM Account];
}
}
この例では、with sharing
キーワードにより、クラスのメソッドが実行中のユーザの権限に基づいたデータアクセスがおこなわれます。
まとめ
Salesforceでの開発において、Apexを用いたデータベース操作は基本であり、その上でSOQLクエリの実行、DML操作、トランザクション管理 および ベストプラクティスの理解が重要です。
ApexとSOQLを習得し、ガバナ制限やセキュリティを考慮した効率的なコードを書くことは、Salesforce開発者にとって必要不可欠なスキルセットとなります。
当記事を通して、これらの重要な概念を学び活用するための一助となれば幸いです。