Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Apexコアデベロッパーセミナー(Apexコード)071010

15,901 views

Published on

2007/10/10のコア開発者向けセミナー資料です

Published in: Technology
  • Be the first to comment

Apexコアデベロッパーセミナー(Apexコード)071010

  1. 1. 株式会社セールスフォース・ドットコム  ビジネス開発本部 Apex コア開発者向けセミナー ~ Apex コード編 ~
  2. 2. 本セミナーの内容 <ul><li>Apex コードの概要 </li></ul><ul><li>Apex コードの文法 </li></ul><ul><li>トリガの作成 </li></ul><ul><li>Web サービスの公開 </li></ul><ul><li>デバッグ、テスト、配備 </li></ul><ul><li>参考: Visualforce </li></ul>
  3. 3. Apex コード Your Code Our Servers Integer NUM = 10; Account[] accs; // Clean up old data accs = [select id from account where name like 'test%']; delete accs; commit; accs = new Account[NUM]; for (Integer i = 0; i < NUM; i++) { accs[i] = new Account(name='test ' + i, outstandingshares__c=i); } insert accs; Contact[] cons = new Contact[0];
  4. 4. Force.com プラットフォームにおけるコンポーネント プラットフォーム データベース ユーザインターフェース ビジネスロジック
  5. 5. Apex コードの基本 <ul><li>オンデマンド型のプログラミング言語 </li></ul><ul><ul><li>Salesforce サーバ上でネイティブに動作する </li></ul></ul><ul><li>ロジックの記述にフォーカスしている </li></ul><ul><ul><li>ユーザインターフェースからは、ボタンやイベント、 API などを介してアクセスする </li></ul></ul><ul><li>特徴 </li></ul><ul><ul><li>Java に類似した構文 </li></ul></ul><ul><ul><li>ストアド・プロシージャ的な言語スコープ </li></ul></ul><ul><ul><li>強い型付けと依存関係のメタデータ保存 </li></ul></ul><ul><ul><li>マルチテナント環境での動作を前提とするリソース管理 </li></ul></ul><ul><ul><li>単体テストのサポート </li></ul></ul>
  6. 6. <ul><li>トリガ </li></ul><ul><ul><li>レコードの作成、更新、削除などのイベントで駆動されるロジックを記述 </li></ul></ul><ul><ul><li>クラスを呼び出し可能 </li></ul></ul><ul><li>クラス </li></ul><ul><ul><li>Java のクラスに類似 </li></ul></ul><ul><ul><li>WebService 修飾子でカスタム Web サービスとしてロジックを公開 </li></ul></ul>Apex コードの種類 global class HelloWorld2 {    // パブリック WebService メソッドにするときは、キーワード WebService を付ける    WebService static String sayHelloWorld(String arg) {      return 'Hello '+arg;    } } trigger helloWorldAccountTrigger on Account (before insert) {    Account[] accs = Trigger.new;    MyHelloWorld.addHelloWorld(accs); }
  7. 7. Summer’07 で何が新しくなった? <ul><li>1.0 言語仕様ファイナル </li></ul><ul><ul><li>クラス(“パッケージ”から変更)、正規表現、バルクトリガ、暗黙的トランザクション </li></ul></ul><ul><li>テストおよびコードの移行 </li></ul><ul><ul><li>Salesforce.com の UI からテスト可能 </li></ul></ul><ul><ul><li>開発組織から他の組織へのデプロイのサポート </li></ul></ul><ul><li>Eclipse </li></ul><ul><ul><li>チーム開発のサポート </li></ul></ul><ul><li>外部 Web サービス呼び出し( Salesforce SOA ) </li></ul><ul><ul><li>3rd party の Web サービスを Apex コードのクラスから呼び出し可能 </li></ul></ul>
  8. 8. Apex コードの文法
  9. 9. Apex コードと Java の類似点、相違点 <ul><li>類似点 </li></ul><ul><ul><li>制御構文( if else, for, while ) </li></ul></ul><ul><ul><li>イテレーション ,  ジェネリクス( Java5 ) </li></ul></ul><ul><ul><li>正規表現クラス </li></ul></ul><ul><li>相違点 </li></ul><ul><ul><li>変数、関数名は大文字小文字を区別しない </li></ul></ul><ul><ul><li>文字列はシングルクオート(一重引用符)で括る </li></ul></ul><ul><ul><li>パッケージ階層はない </li></ul></ul><ul><ul><li>クラス継承(デフォルトでは有効でない) </li></ul></ul><ul><ul><li>インラインの SOQL クエリ、 DML 文 </li></ul></ul><ul><ul><li>global, webService, testMethod などの修飾子 </li></ul></ul>
  10. 10. インライン SOQL クエリ <ul><li>Web サービス API の SOQL とほぼ同じ </li></ul><ul><li>記述方法 </li></ul><ul><ul><li>Apex コード中に [ … ] セクションで指定する </li></ul></ul><ul><ul><li>結果が 1 件のみの場合は SObject に直接代入可能 </li></ul></ul><ul><ul><li>Apex コード内の変数を「 : 」を付けることで文中にバインド可能 </li></ul></ul>Account[] accounts = [SELECT Id, Name FROM Account]; Account a = [SELECT Id, Name FROM Account WHERE Id = :accId]; Account[] accs = [SELECT Id, Name FROM Account WHERE Name LIKE :(s + '%')]; Account a = [SELECT Id, Name FROM Account LIMIT 1];
  11. 11. DML 文 <ul><li>種類: insert( 挿入 ), update (更新) , delete (削除) , upsert( 上書き作成 ) </li></ul><ul><li>データベースアクセス後のトランザクション制御( commit, rollback )は必要ない </li></ul><ul><ul><li>リクエスト正常終了時は暗黙的にコミット、異常時にはロールバックされる </li></ul></ul>insert <SObject>; insert <SObject[]>; update <SObject>; update <SObject[]>; delete <SObject>; delete <SObject[]>;
  12. 12. Apex コードのクラス <ul><li>システム静的 </li></ul><ul><ul><li>System </li></ul></ul><ul><ul><li>Math </li></ul></ul><ul><ul><li>Limits </li></ul></ul><ul><li>コレクション </li></ul><ul><ul><li>List (リスト配列) </li></ul></ul><ul><ul><li>Set (集合) </li></ul></ul><ul><ul><li>Map (ハッシュマップ、連想配列) </li></ul></ul><ul><li>正規表現 </li></ul><ul><ul><li>Pattern </li></ul></ul><ul><ul><li>Matcher </li></ul></ul><ul><li>基本データ型 </li></ul><ul><ul><li>Double </li></ul></ul><ul><ul><li>Integer </li></ul></ul><ul><ul><li>String </li></ul></ul><ul><ul><li>Date </li></ul></ul><ul><ul><li>Datetime </li></ul></ul><ul><li>SObject 型 </li></ul><ul><li>ユーザ定義のクラス </li></ul>
  13. 13. SObject 型 <ul><li>Salesforce 内のオブジェクト(標準/カスタム)をあらわす抽象データ型 </li></ul><ul><li>宣言時には常に具象的な型( Account, Contact など)を使う </li></ul><ul><li>コンストラクタに項目の属性値をセットできる </li></ul>Account account = new Account(Name=' 東京建設 ', NumberOfEmployees=200);
  14. 14. コレクションクラス: List <ul><li>リスト構造の格納 </li></ul><ul><li>Apex コード上では配列と同じ扱い </li></ul>String[] colors = new List<String>(); colors.add('red'); colors.add('white'); colors.add('green'); System.debug(colors[1]); // => 'white'; System.debug(colors.size()); // => 3
  15. 15. コレクションクラス: Map <ul><li>ハッシュマップ(連想配列)用のデータ構造 </li></ul><ul><li>インターフェースでなくクラス実装( Java とは異なる) </li></ul>Map<String, String> myStrings = new Map<String, String>{'a' => 'b', 'c' => 'd' };
  16. 16. コレクションクラス: Set <ul><li>データの集合を現すデータ構造 </li></ul><ul><li>インターフェースではなくクラス実装( Java とは異なる) </li></ul><ul><li>重複を排除 </li></ul><ul><li>利用例 </li></ul><ul><ul><li>複数レコードの親レコードを重複なく取得 </li></ul></ul>Set<ID> accountIds = new Set<ID>(); for (Contact c : contacts) accountIds.add(c.AccountId); Account[] accounts = [SELECT Id, Name FROM Account WHERE Id IN :accountIds];
  17. 17. 正規表現クラス <ul><li>Pattern, Matcher </li></ul><ul><ul><li>ほぼ JavaSE の同名クラスと同じ http://java.sun.com/j2se/1.5.0/docs/api/index.html?java/util/regex/Pattern.html </li></ul></ul><ul><ul><li>高度な入力値検査、構文解析などが可能に </li></ul></ul>Boolean match = Pattern.matches('a*b', 'aaaaab');
  18. 18. ユーザ定義クラス <ul><li>ほぼ Java と同様 </li></ul><ul><ul><li>定義 </li></ul></ul><ul><ul><li>インスタンス化 </li></ul></ul><ul><li>外部クラス・内部クラスの定義も可能 </li></ul><ul><ul><li>Java における「パッケージ」に相当する用途に代用できる </li></ul></ul>public class MyClass { public MyClass (String a, Integer b) { // コンストラクタ }    private void doSomething () {    // プライベートメソッド    } } MyClass c = new MyClass('abc', 12);
  19. 19. トリガの作成
  20. 20. トリガ <ul><li>データベース操作に対する各種イベント発生時に起動される Apex コードのロジック </li></ul><ul><ul><li>データベース・ストアドプロシージャのトリガに類似 </li></ul></ul><ul><li>トリガ定義の構文 </li></ul><ul><li>イベント発生のタイミング </li></ul><ul><ul><li>before insert / before update / before delete </li></ul></ul><ul><ul><li>after insert / after update / after delete </li></ul></ul><ul><ul><li>after undelete </li></ul></ul>trigger < トリガ名 > on < オブジェクト名 > ( < イベント > ) { // トリガの処理 }
  21. 21. トリガの記述方法 <ul><li>トリガのコード内から、システム変数 Trigger.new/Trigger.old を用いて新旧レコード情報にアクセスする </li></ul><ul><ul><li>Trigger.new/Trigger.old からリスト(配列)としてアクセス可能 </li></ul></ul><ul><ul><li>Trigger.newMap/Trigger.oldMap で ID をキーとするマップ構造としてアクセス可能 </li></ul></ul>trigger testTrigger on Account (after insert) { for (Account a : Trigger.new ) { // 作成された各レコードに対して反復処理する } } trigger oppTrigger on Opportunity (before delete) {    for (Quote__c q : [SELECT Opportunity__c FROM Quote__c                     WHERE Opportunity__c IN :Trigger.oldMap .keySet()]) { Trigger.oldMap .get(q.opportunity__c)       .addError('Cannot delete opportunity with a quote'); } }
  22. 22. トリガに対する注意事項 <ul><li>トリガはすべてバルクトリガ(レコードを一括で処理) </li></ul><ul><ul><li>API のリクエストなど、作成・更新要求は一度に複数レコードが送信されることが多い </li></ul></ul><ul><ul><li>トリガから1レコードごとに DB 処理 ?    DB 負荷が高い </li></ul></ul><ul><ul><li>トリガの中から DB にアクセスするときは、 Apex VM ヒープ中でレコード処理してから、まとめてアクセスすること </li></ul></ul><ul><ul><li> ガバナ制限(実行時のリソース制限) に引っかからないように </li></ul></ul>
  23. 23. ガバナ制限( Governor Limit ) <ul><li>共有されたマルチテナント環境であるがための機能 </li></ul><ul><ul><li>暴走スクリプト、リソースを大量に消費するコードをプラットフォームが排除する </li></ul></ul><ul><li>制限に達したコードは例外を起こして途中終了される </li></ul><ul><li>モニタリングしているリソースの例 </li></ul><ul><ul><li>実行される SOQL クエリの総数 </li></ul></ul><ul><ul><li>SOQL クエリで取得されるレコードの総数 </li></ul></ul><ul><ul><li>実行される DML ステートメントの総数 </li></ul></ul><ul><ul><li>実行されるスクリプトステートメントの総数 </li></ul></ul><ul><ul><li>合計ヒープサイズ </li></ul></ul><ul><li>詳細は言語リファレンスマニュアルを参照 </li></ul>
  24. 24. SOQL for ループ <ul><li>イテレーション処理を SOQL 結果レコードに対して直接適用 </li></ul><ul><li>通常のリスト配列イテレーションの違い </li></ul><ul><ul><li>レコードを一時的に格納するためのメモリを必要としない </li></ul></ul><ul><ul><li>ガバナ制限値を回避して多量のレコードを処理できる </li></ul></ul>for (Account a : [SELECT Id, Name FROM Account                  WHERE Name LIKE :(s+'%')]) {    // 繰り返しコード }
  25. 25. トリガ実装の例 <ul><li>悪い実装例 </li></ul><ul><li>よい実装例 </li></ul>trigger myTrigger on Emp__c (after insert) {    Map<Id, Integer> deptEmps = new Map<Id, Integer>();    for (Emp__c emp : Trigger.new) { Integer count = deptEmps.get(emp.Dept__c); if (count==null) count=0; deptEmps.put(emp.Dept__c, count+1); } Dept__c[] depts = [SELECT Id FROM Dept__c WHERE Id IN :deptEmps.keySet()]; for (Dept__c d : depts) { d.EmployeesNumber__c += deptEmps.get(d.Id); } update depts; } trigger myTrigger on Emp__c (after insert) {    for (Emp__c emp : Trigger.new) { Dept__c dept = [SELECT Id, Name FROM Account WHERE Id = :emp.Dept__c]; dept.EmployeesNumber__c++; update dept; } } ループ内で DML を発行しているため、 DML 文数のガバナ制限値に抵触する ループ内でクエリを発行しているため、クエリ数のガバナ制限値に抵触する すぐにデータベースに更新するのでなく、一旦値をマップ構造に格納 ループの外側で 一括クエリ&一括 DML 処理
  26. 26. Web サービスの公開
  27. 27. Apex コード と Web サービス API 外部サーバ or クライアント端末 SOAP WSDL WSDL WSDL SOAP ロジックをカスタム Web サービスとして公開
  28. 28. Web サービスとしての公開 <ul><li>Web サービスを含むクラスを修飾子 global を付けて宣言する </li></ul><ul><li>Web サービスとして公開するメソッドを修飾子 webService を付けて宣言する </li></ul>global class HelloWorld {    // パブリック WebService メソッドにするときは、キーワード WebService を付ける    w ebService static String sayHello (String msg ) {      return 'Hello , ' + msg ;    } }
  29. 29. WSDL のダウンロード <ul><li>[ 設定 ]  [ 開発 ]  [ コード ] </li></ul><ul><li>開発したクラス毎に WSDL としてダウンロード可能 </li></ul>
  30. 30. Apex コードのセキュリティについて <ul><li>クラスごとに実行権限を設定可能 </li></ul><ul><ul><li>呼び出し可能なクラスをユーザプロファイル毎に設定することでアクセスコントロールする </li></ul></ul><ul><ul><li>システム管理者権限はすべて呼び出し可能 </li></ul></ul><ul><li>Apex コード実行時はすべてシステム権限で動きます </li></ul><ul><ul><li>共有設定によるアクセスコントロールはすべて無視されるので注意! </li></ul></ul>
  31. 31. 外部 Web サービス呼び出し ( Salesforce SOA ) <ul><li>外部 Web サービスを Apex コードから呼び出す機能 </li></ul><ul><li>WSDL ファイルを読み込み、自動的に Apex コードのクラスに変換 </li></ul><ul><ul><li>[ 設定 ]  [ 開発 ]  [ コード ]  [WSDL からの生成 ] </li></ul></ul><ul><li>現在、対応 Web サービスは SOAP 形式のみ(サービス情報が WSDL として提供されているもののみ) </li></ul><ul><ul><li>次バージョン( Winter’08 )から通常の XML Web サービス( REST 形式)も呼び出し可能に </li></ul></ul><ul><li>注:トリガ内からの呼び出しは不可 </li></ul>
  32. 32. デバッグ・テスト・配備
  33. 33. デバッグ <ul><li>System.debug() で文字列として出力 </li></ul><ul><ul><li>ブレークポイントなどの機能はない </li></ul></ul><ul><li>デバッグログの出力先 </li></ul><ul><ul><li>[ 設定 ] - [ 監視 ] - [Monitor Apex Logs] </li></ul></ul><ul><ul><li>Apex ログウィンドウ </li></ul></ul>
  34. 34. Apex ログウィンドウ <ul><li>ブラウザにデバッグ情報を出力 </li></ul><ul><ul><li>トリガ内で発生したデバッグ情報 </li></ul></ul><ul><li>Apex コードの即時実行が可能 </li></ul><ul><ul><li>匿名ブロックを記述して Execute ボタンで実行 </li></ul></ul>
  35. 35. Apex コードのテスト <ul><li>Apex コード開発は、テスト駆動型開発で </li></ul><ul><ul><li>最初にテストケースを作りましょう </li></ul></ul><ul><ul><li>結局本番環境へのデプロイの際に必要になります </li></ul></ul><ul><li>クラスだけでなくトリガについてもテストする必要あり </li></ul><ul><ul><li>テストコードとしてトリガとなるイベントを発生するような DML 処理を記述する </li></ul></ul><ul><li>テストの実行方法 </li></ul><ul><ul><li>Web 画面から </li></ul></ul><ul><ul><ul><li>[ 設定 ]  [ 開発 ]  [ コード ]  [Run all Tests] </li></ul></ul></ul><ul><ul><li>Eclipse プラグインから </li></ul></ul><ul><ul><ul><li>runTests API メソッドを内部的に使用 </li></ul></ul></ul>
  36. 36. テストコードの記述 <ul><li>testMethod 修飾子を含むメソッドを定義 </li></ul><ul><li>テストコード内での DML 文によるデータベースへのデータ変更はコミットされない </li></ul><ul><li>startTest/stopTest メソッドにより、ガバナ制限を意識したテストが可能 </li></ul>public class MyClass {    // ユニットテストのメソッドは static で宣言し、引数は定義しない static testMethod void myTest1() { // ユニットテスト用のコード } }
  37. 37. Apex コードの配備 <ul><li><注意>本番環境に配備するには以下の手順に従う必要があります! </li></ul><ul><li>開発組織( DE )上で、クラス・トリガなどのコードに加え 「単体テストのコードを含めて」 開発します </li></ul><ul><li>上記のコードを Sandbox 組織でテストします(オプション) </li></ul><ul><li>最後に本番の運用組織( UE )にデプロイします </li></ul><ul><ul><li>デプロイに成功するためには、テストコードが 75%以上 のコードカバレッジで成功する必要あり </li></ul></ul>
  38. 38. 配備方法 <ul><li>API による配備 </li></ul><ul><ul><li>compileAndTest メソッド </li></ul></ul><ul><ul><li>配備用プロセスをカスタムでコーディングする必要がある場合などに利用可能 </li></ul></ul><ul><li>Ant Tools </li></ul><ul><ul><li>Apache Ant を利用したデプロイツール </li></ul></ul><ul><ul><li>正式にサポートされているツール </li></ul></ul><ul><ul><ul><li>[ 設定 ]  [ 開発 ]  [Tools] からダウンロード </li></ul></ul></ul><ul><ul><li>Apex コードをローカルに保存、デプロイ用の build.xml を記述する </li></ul></ul><ul><li>Eclipse 用プラグイン </li></ul><ul><ul><li>推奨(ただし、あくまでコミュニティプロダクトであり正規のサポートはありません) </li></ul></ul>
  39. 40. Apex コード と Visualforce View Controller Model
  40. 41. Visualforce Page による View の定義 <apex:page> <h1>Hello World</h1> </apex:page> <apex:detail subject=“ id expression ” relatedList=“false” />
  41. 42. Visualforce Controller <ul><li>ブラウザからのイベントハンドリング、および画面遷移のコントロールを行う </li></ul><ul><ul><li>Java におけるサーブレット、 Struts に相当 </li></ul></ul><ul><li>コントロールロジックの記述は Apex コードで </li></ul><ul><ul><li>例) </li></ul></ul><ul><li>カスタムコントローラのほかにデフォルトコントローラもあり </li></ul>public class MyController {    private String name;    public String getName() {   return this.name;   }    public void setName(String name) {   this.name = name;   }    public PageReference save() {      Account newAcc = new Account(Name=this.name);      insert newAcc; return Page.success; } }
  42. 43. その他
  43. 44. Apex コードのはじめかた <ul><li>Apex Developer Network に登録して、 Developer Edition アカウントを取得 </li></ul><ul><ul><li>Apex Developer Network Japan </li></ul></ul><ul><ul><li>h ttp:// developer.salesforce.co.jp / </li></ul></ul><ul><li>(オプション) Eclipse IDE へのプラグインをインストール </li></ul><ul><ul><li>Apex Toolkit for Eclipse </li></ul></ul><ul><ul><li>http://developer.salesforce.co.jp/tool.html#apex_toolkit_eclipse </li></ul></ul><ul><li>Apex コード言語リファレンス </li></ul><ul><ul><li>サンプルコードあり </li></ul></ul>
  44. 45. 世界初のオンデマンドプログラム言語のための IDE for Apex Code の編集 Apex Code のデバッグ Apex Project の管理
  45. 46. Apex コード言語リファレンス <ul><li>日本語訳ができました </li></ul><ul><li>Apex Developer Network からダウンロード可能 </li></ul><ul><ul><li>http://developer.salesforce.co.jp/document.html#apex_code </li></ul></ul>

×