技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Salesforce開発の基礎編5

trailhead.salesforce.com

Apex の基礎とデータベース

Apex の使用開始

まぁJava書いてたら特に問題なくやれる。言語仕様は体感 Java1.42 位の印象(1.4 よりはマシ?だが5の様なGenericsなどは存在しない)。
ローカルコンパイルできず、Salesforce 組織上でしかコンパイル/実行できない。
Apex の特徴的な機能として

サンプルのコードは非常にうれしい作りではあるのでここでも転記。
Java だとメールサーバに接続して…なんて色々やるけど、そういった内容はすべて Salesforce にビルトイン。
こういう所は楽っちゃ楽

public class EmailManager {
    public void sendMail(String address, String subject, String body) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {address};
        mail.setToAddresses(toAddresses);
        mail.setSubject(subject);
        mail.setPlainTextBody(body);
        Messaging.SendEmailResult[] results = Messaging.sendEmail(
                                 new Messaging.SingleEmailMessage[] { mail });
        inspectResults(results);
    }
    
    private static Boolean inspectResults(Messaging.SendEmailResult[] results) {
        Boolean sendResult = true;
        for (Messaging.SendEmailResult res : results) {
            if (res.isSuccess()) {
                System.debug('Email sent successfully');
            }
            else {
                sendResult = false;
                System.debug('The following errors occurred: ' + res.getErrors());                 
            }
        }
        return sendResult;
    }
}

基本はこっから起動して
f:id:white-azalea:20210524200351p:plain

クラスを追加
f:id:white-azalea:20210524200533p:plain

クラス名は StringArrayTest
f:id:white-azalea:20210524200615p:plain

答えを書いても仕方ないのでテスト内容の翻訳

  • StringArrayTest というクラスで public で作ります
  • public static なメソッド generateStringArray を作成します
  • generateStringArray の仕様は
    • Integer 型の引数
    • List<String> 型の返値型
    • 引数の値によって Test 0, Test 1 ... の様な値を返します。

sObject の使用

Salesforce のデータベースはすべてオブジェクト、Apex 的には sObject 型です。
全てのオブジェクトには Id フィールドがあり、プライマリキーです。型も ID 型で、18文字 String 値が入ってます。

sObject は Salesforce開発の基礎編2 - 技術をかじる猫 このデータモデリング参照。
クエリもソース内でこんな風に書ける

List<Account> values = [SELECT Id, Name FROM Account WHERE Name LIKE 'Test%'];

DML を使用したレコードの操作

DML ってのは、要するにレコード操作 insert, delete, update, upsert, undelete, merge でデータを色々いじれる。

Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);
insert acct;

insertupsert した直後に Id フィールドにだけ値が設定される。
数式項目は insert が完了したときに埋められる…のだけど、insert に使ったオブジェクトには入らないので、select しなおさないといけない。

upsertinsert としても update としても使えるコマンドで、merge は最大 3 レコードを 1 レコードに自動マージして既存レコードを削除して保存される。
一応データベース操作はメソッドでもできる。

Database.insert()
Database.update()
Database.upsert()
Database.delete()
Database.undelete()
Database.merge()

問題はこんな内容

  • AccountHandler クラスを作成します public でね
  • 以下の仕様を満たす public staticinsertNewAccount メソッドを作ります
    • 引数に String を受け取り、Account オブジェクトを作成、 Account.Name に設定します。
    • 作ったら Accountinsert し、return する。
    • 引数では空文字も受付け、保存に失敗したら null を返します。

SOQL クエリの作成

ソース中にクエリが書ける仕様の演習課題。

  • public class ContactSearch を作成してください
  • public static なメソッド searchForContacts を定義します。
    • 二つの String パラメータを受け取ります
    • Contact を検索します。第一引数は LastName とマッチさせ、第二引数は MailingPostalCode と一致検索します。
    • 最終的に List<Contact> を return します。SELECT 内容は Id, Name です。

Apex トリガ

trailhead.salesforce.com

何故かやたらとお世話になる Apex トリガ。
これはデータベースレコード操作に割り込む処理で、ソースコードで割り込めるあたりが割と便利。

Apex トリガの使用開始

Apex トリガの記述
要するに DML に割り込めるタイミングの説明。
以下のタイミングが扱える。

before insert
before update
before delete
after insert
after update
after delete
after undelete

トリガの設定はこれ見れば分かるはず

trigger HelloWorldTrigger on Account (before insert, after insert) {
    if (Trriger.isInsert) {
        if (Trriger.isBefore) {
            List<Account> values = Trriger.New;
        } else if (Trigger.isAfter) {
            List<Account> values = Trriger.New;
        }
    }
}

before は実際にデータの操作(insert 等)の直前に実行される。関連するカラムを計算して保存する場合、加工はここ。
after はデータ操作実行直後に実行される。この時点で Id 等が設定されている。関連するレコードを作成するなどする場合はここ。

因みに、before insertafter insert 内で Trigger.New のデータを delete したりすることはできません。
やるなら after insert で再度 select することで delete 等を実行することができます。

また、トリガ内では原則的に Callout (Callout は外部サーバへのHTTPリクエストの事)は実行できません。
そこで @future(callout=true) アノテーションのついた非同期処理などを使用することで呼び出すことができます。

一括 Apex トリガ

前述で Trigger.NewList 返してることを考えれば分かるけど、要するに複数レコードがまとめて入ってくる。
それは insert でリストを指定していたり、DataLoader でまとめてどーんしたときに複数入ってきます。

で、ここからが問題で、Salesforce にはガバナ制限つーもんがあります。
developer.salesforce.com

見れば分かるけど、1回の処理で行っていい DML 操作や SELECT 回数には限界がある。
ループしながら SELECT すると、制限の 100 回なんて一瞬な訳で…なので、そういう操作するならまとめて SELECT や一気に操作を心がけましょうという話。

developer.salesforce.com

トリガの実行順序なども試験の範囲なんで覚えときせう