salesforce 零基礎開發入門學習(十一)sObject及Schema深入


sObject在salesforce中占有舉足輕重的位置,除了在數據庫中數據以外,我們還應該關心一下他的元信息。元信息封裝在Schema命名空間內。

作為面向對象語言,我們可以暢想一下如果我們是設計人員,應該封裝哪些方法。下圖為自定義的一個Object.

通過圖中的簡短描述,我們可以猜測應該封裝以下方法:

  1.可以獲取sObject的label名稱,api名稱,是否可以訪問等;

  2.可以獲取field的label名稱,api名稱,字段類型等;

  3.如果sObject作為父sObject,可以獲取相關的子sObject的描述信息等;

  4.如果字段為PickList類型,可以獲取相應的value數組;

  5.如果表之間存在lookup或者master-detail關系,是否可以進行級聯刪除;

  6.sObject或者field是自定義類型還是標准類型等等。

這里只是大概舉了一個例子,因為開發經驗不足,所以考慮的比較少,相信大神們會想出很多很多。當然,大部分功能都已經封裝好了。

元信息下面主要介紹兩個方面,一個為sObject的元信息,一個為field的元信息。

可以使用兩種方式獲取sObject和field描述信息結果,描述結果分別為(Schema.DescribeSObjectResult,Schema.DescribeFieldResult)

一.token

sObject的token代表Schema.SObjectType,field的token代表Schema.SObjectField.兩個token對象均有getDescribe()方法,此方法返回token的描述結果,描述結果中封裝的方法用來實現上述猜測的功能。描述結果中,通過使用getSObjectType 和 getSObjectField 方法分別返回sObject和field的tokens。

1)SObjectType

 Schema.SObjectType 是sObject 的token的一種數據類型,可以通過兩種方式獲取。eg:

  • Schema.sObjectType t = Account.sObjectType; 

  //第二種方式,通過getSObjectType方法獲取Schema.sObjectType對象

  • Account a = new Account();

    Schema.sObjectType t = a.getSObjectType();

在SObjectType中可以通過調用getDescribe方法使用token方式獲取sObject描述結果,返回類型為Schema.DescribeSObjectResult.

調用方式:Schema.DescribeSObjectResult dsr = Account.sObjectType.getDescribe();

2)sObjectField

通過getSObjectField方法獲取Schema.sObjectField對象來訪問field token。

獲取sObjectField有兩種方式,其中第一種方式為獲取指定的sObject指定field的token,第二種為獲取sObject所有field的token。

1.獲取指定sObject指定field的token。

兩個步驟:1.先獲取sObject相關字段的描述信息;2.通過調用getSObjectField方法獲取field token。

Schema.DescribeFieldResult F = Account.Industry.getDescribe();

Schema.sObjectField T = F.getSObjectField();

以下內容為獲取Account的Industry字段的token描述信息

Schema.DescribeFieldResult F = Account.Industry.getDescribe(); 

2.獲取一個sObject所有的field的描述結果

Map<String, Schema.SObjectField> fieldMap = Schema.SObjectType.Account.fields.getMap();

其中fieldMap對象包含了Account所有字段的描述結果信息。

fieldMap包含了以下特性:

1.他是動態的,在運行時動態生成sObject的所有的fields;

2.所有的字段名不區分大小寫;

3.keys反映出field是否為一個自定義的Object

 

二.Schema的方法 describeSObjects.

 使用Schema類的describesSObjects方法獲取描述sObject結果.使用此方法可以通過sObject類型名稱描述一個或者多個sObject描述信息。

 1 // sObject types to describe 
 2 String[] types = new String[]{'Account','Merchandise__c'};
 3  // Make the describe call Schema.
 4 DescribeSobjectResult[] results = Schema.describeSObjects(types); 
 5 System.debug('Got describe information for ' + results.size() + ' sObjects.'); 
 6 // For each returned result, get some info 
 7 for(Schema.DescribeSobjectResult res : results) { 
 8     System.debug('sObject Label: ' + res.getLabel()); 
 9     System.debug('Number of fields: ' + res.fields.getMap().size()); 
10     System.debug(res.isCustom() ? 'This is a custom object.' : 'This is a standard object.');
11      // Get child relationships 
12     Schema.ChildRelationship[] rels = res.getChildRelationships();
13      if (rels.size() > 0) { 
14         System.debug(res.getName() + ' has ' + rels.size() + ' child relationships.');
15     }
16 }

注:通過使用Schema類的getGlobalDescribe方法可以獲取所有的sObject的描述信息token。

 Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe(); 

此map有以下特性:

1.他是動態的,意思為在運行時,根據權限生成所有的可訪問的sObject描述信息;

2.key不區分大小寫;

3.通過key可以判斷sObject是自定義的還是系統的。

 

 以下為獲取SObject以及相關Field的元信息常用的類:

(一)System.Schema

Schema類方法用來獲取Schema的描述信息

這里介紹兩種常用的方法:

  • public static Map<String, Schema.SObjectType> getGlobalDescribe():此方法用來根據當前用戶訪問權限返回權限內所有的sObject描述信息token。
  • public static List<Schema.DescribeSObjectResult> describeSObjects(List<String> sObjectTypes):此方法用來返回指定的sObject(s)的描述信息結果。

(二)Schema.SObjectType(sObject的token)

一個Schema.SObjectType對象可以通過以下方式獲取:

1.通過field的描述結果使用getReferenceTo方法獲取;

eg:

Schema.DescribeFieldResult F = Account.Industry.getDescribe();

List<Schema.sObjectType> P = F.getReferenceTo();

2.從sObject描述結果使用getSObjectType 方法獲得。

3.直接通過sObject獲取:Schema.sObjectType sObjType = Goods__c.sObjectType;其中Goods__c為自定義的object。(常用)

主要方法如下:

  • public Schema.DescribeSObjectResult getDescribe():返回Schema.DescribeSObjectResult對象,此對象為SObject的描述信息結果。

(三)Schema.DescribeSObjectResult

此類的方法用來描述SObject描述結果

主要方法如下:

  • public Schema.SObjectTypeFields fields():返回一個特殊的數據類型,此數據類型通常不單獨使用。通常應跟在一個字段成員變量名或者getMap()方法后。
  • public Schema.SObjectTypeFields fieldSets():描述同上.eg:   
Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();

Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();  
  • public List<Schema.ChildRelationship> getChildRelationships():獲取子關系列表,即sObject中有外鍵描述的列表

以上兩個表中PRIVELEGEROLE__c外鍵關聯於PRIVELEGE__c中,所以通過對PRIVELEGE__c調用此方法可以獲取PRIVELEGEROLE__c的信息

List<Schema.ChildRelationship> lists = PRIVELEGE__c.sObjectType.getDescribe().getChildRelationships();
for(Schema.ChildRelationship child : lists) {
	System.debug(child.getChildSObject());
}

輸出結果中有一條即為PRIVELEGEROLE__c  

  • public String getLabel():獲取sObject的label名稱,此label名稱為創建sObject對象時的label名稱,可以通過create->objects中查看具體的名稱。

  eg:api名稱為Goods__c的sObject,他的label名稱為Goods.通過以下代碼可以獲取到label名稱。

Schema.DescribeSObjectResult describeSObjectResult= Goods__c.sObjectType.getDescribe();
System.debug(describeSObjectResult.getLabel());  
  • public String getName():返回object的api名稱;
  • public Schema.SObjectType getSobjectType():返回sObject的類型。
  • public Boolean isAccessible():當前用戶是否可以訪問相關的field,可以返回true,否則返回false
  • public Boolean isCreateable():當前用戶是否可以創建,可以返回true,否則返回false
  • public Boolean isCustom():判斷當前sObject為自定義Obj還是標准的Obj。自定義返回true,標准返回false。
  • public Boolean isUpdateable():判斷當前用戶是否可以修改此sObject,可以返回true,不可以返回false。
  • public Boolean isDeletable():判斷當前用戶是否可以刪除此sObject,可以刪除判斷true,否則返回false。

(四)Schema.ChildRelationship

此類包含的方法用來處理子關系的sObject。

此實例通過DescribeSObjectResult的getChildRelationships方法創建。主要有以下方法:

  • public Schema.SObjectType getChildSObject():返回子Object的token;
  • public Schema.SObjectField getField():返回外鍵回到父sObject的field的token
  • public String getRelationshipName():返回關系名稱。eg:PRIVELEGEROLE__c通過PRIVELEGEID__c外鍵關聯於PRIVELEGE__c,則返回的名稱為PRIVELEGEID__r
  • public Boolean isCascadeDelete():是否可以級聯刪除,可以返回true,否則返回false。父子關系中LOOKUP不可以級聯刪除,MASTER-DETAIL可以級聯刪除。
  • public Boolean isRestrictedDelete():如果父對象因為被子對象引用不能刪除則返回true,否則返回false
Schema.DescribeSObjectResult  describeSObjectResult= PRIVELEGE__c.sObjectType.getDescribe();
List<Schema.ChildRelationship> childs = describeSObjectResult.getChildRelationships();
for(Schema.ChildRelationship child :childs) {
	if(child.getRelationshipName() == 'PRIVELEGEROLE__r') {
		 System.debug(child.getRelationshipName());
		 Schema.SObjectField childField = child.getField();
		 System.debug(childField);
	}
} 

(五)Schema. SObjectField

此類可以通過以下兩種方式獲取:

1.Map<String,SObjectField> maps = Schema.SObjectType.Goods__c.fields.getMap();
Schema.SObjectField goodsName = maps.get('goodsname__c');

第一步為獲取sObejct為Goods__c的所有字段的token的map集合,第二步為獲取field為goodsname__c的token。

2.通過DescribeFieldResult的getController()方法獲取。

此類含有一個方法:

  • public Schema.DescribeFieldResult getDescribe():返回Schema.DescribeFieldResult對象實例,用於描述sObject對象的field描述結果。

(六)Schema.DescribeFieldResult 

此類中的方法用來描述sObject中字段的元信息描述結果。

實例化操作方式:

Schema.DescribeFieldResult goodsPriceDescribe = Goods__c.GoodsName__c.getDescribe();

//此方式返回指定sObject的指定field的元信息描述結果or :  

Map<String,SObjectField> maps = Schema.SObjectType.Goods__c.fields.getMap();
Schema.SObjectField goodsName = maps.get('goodsname__c');

Schema.DescribeFieldResult goodsPriceDescribe = goodsName.getDescribe();

//此方式為先獲取指定sObject的所有field的token,通過token實例化字段描述元信息結果。

主要方法如下:

  • public Schema.sObjectField getController():獲取當前字段描述結果的token;
  • public Object getDefaultValue():獲取字段默認值;
  • public String getCalculatedFormula():返回此字段指定的公式,此字段無公式則返回null字符串;
  • public String getLabel():返回field的label名稱;
  • public Schema.sObjectField getSObjectField():獲取當前字段描述結果的token;
  • public Schema.DisplayType getType():返回字段類型,返回類型為枚舉類型;
  • public Boolean isAutoNumber():判斷此字段是否為autoNumber類型,是返回true,否則返回false;
  • public Boolean isCustom():判斷此字段是否為自定義類型字段,是返回true,否則返回false;
  • public String getName():返回字段的api名稱;
  • public List<Schema.PicklistEntry> getPicklistValues():如果此字段為PickList類型字段,可以通過此方法返回PicklistEntry實例對象用來獲取PickList的value。

(七)Schema.PicklistEntry

此類中方法用於獲取PickList的value數組。主要方法如下:

  • public String getLabel():返回這個picklist的item的顯示名稱;
  • public String getValue():返回這個picklist的item的VALUE;
  • public Boolean isActive():這個item的值在UI的drop-down的列表中顯示則返回true,否則返回false;
  • public Boolean isDefaultValue():判斷當前的picklist的item是否為picklist的默認值,如果是則返回true,否則返回false。

注意:一個PickList只允許有一個默認值。

總結:如果需要通過獲取sObject或者field的元信息描述結果,首先應該思考如何實例化描述結果,即DescribeSObjectResult或者DescribeFieldResult。token作用為實例化描述元信息結果對象,如果不需要token便直接實例化,則可以直接實例化,即token方式非必需.

最后通過一個sample作為總結,通過Student__c作為例子,他的Education__c為PickList類型,內容下圖所示:

 

 以下sample為上述類和方法的訓練,希望通過下面的代碼將上述沒有描述清楚的地方理順通。

 1 public class SObjectSchema {
 2     public void testSchema() {
 3         /*
 4             獲取SObject的token主要可以分為兩種方式
 5             1.先獲取所有token,然后通過key獲取需要的token
 6             2.直接獲取指定的sObject的token
 7         */
 8         
 9         //1.通過獲取全部描述信息,然后get方法獲取需要的指定字段的描述信息
10         Map<String,Schema.SObjectType> allSObjectTypeDescribes = Schema.getGlobalDescribe();
11         Schema.SObjectType studentType = allSObjectTypeDescribes.get('student__c');
12         
13         //2.直接獲取指定sObject的token。
14         Schema.SObjectType studentType1 = Student__c.SObjectType;
15         
16         /*
17             獲取Schema.DescribeSObjectResult有兩種方式:
18             1.通過token的getDescribe方法
19             2.通過System命名空間下的Schema的方法
20         */
21         //以下為第一種方式
22         Schema.DescribeSObjectResult studentResult = studentType.getDescribe();
23         //以下為第二種方式
24         List<String> sObjectTypes = new String[] {'Student__c'};
25         List<Schema.DescribeSObjectResult> studentResult1 = Schema.describeSObjects(sObjectTypes);
26         System.debug('sObject的label名稱為:' + studentResult.getLabel());
27         System.debug('sObject的API的名稱為' + studentResult.getName());
28         System.debug('Student表是否為自定義的Object :' + (studentResult.isCustom() ? '是':'否'));
29         //------還有好多方法,可以自己嘗試-------// 
30         List<Schema.ChildRelationship> studentChildRelationResult = studentResult.getChildRelationships();
31         for(Schema.ChildRelationship child : studentChildRelationResult) {
32             System.debug('Student子Object的關聯名稱:' + child.getRelationshipName());
33         }
34         
35         /*
36             以下操作為獲取field的元信息結果,以Education__c為例
37             兩種操作方式:
38             1.通過DescribeSObjectResult的fieds方法獲取token,然后再通過getDescribe方法獲取
39             2.直接獲取字段然后使用getDescribe方法
40         */
41         
42         Map<String,SObjectField> sObjectFieldMaps = studentResult.fields.getMap();
43         SObjectField educationField = sObjectFieldMaps.get('Education__c');
44         Schema.DescribeFieldResult educationFieldResult = educationField.getDescribe();
45         Schema.DisplayType educationType = educationFieldResult.getType();
46         System.debug('education字段類型為:' + educationType);
47         System.debug('education字段API名稱為:'+educationFieldResult.getName());
48         System.debug('education字段label名稱為:'+educationFieldResult.getLabel());
49         //-----很多方法,可以自己練習-----//
50         List<Schema.PicklistEntry> educationListValues = educationFieldResult.getPicklistValues();
51         Map<String,Object> educationListValuesMap = new Map<String,Object>();
52         for(Schema.PicklistEntry educationListItem : educationListValues) {
53             educationListValuesMap.put(educationListItem.getValue()
54             ,new Map<String,Object>{
55                 'value' => educationListItem.getValue(),
56                 'isActive' => educationListItem.isActive(),
57                 'isDefaultValue' => educationListItem.isDefaultValue(),
58                 'label' => educationListItem.getLabel()
59             });
60         }
61         Set<String> educationListValuesSet = educationListValuesMap.keySet();
62         System.debug('educations values'+ educationListValuesSet);
63     }
64 }

 如果有寫錯的地方歡迎批評指正,如果有不懂得地方歡迎留言,共同探討,轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM