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:
//第二种方式,通过getSObjectType方法获取Schema.sObjectType对象
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的描述信息
这里介绍两种常用的方法:
(二)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。(常用)
主要方法如下:
(三)Schema.DescribeSObjectResult
此类的方法用来描述SObject描述结果
主要方法如下:
Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();
Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();
以上两个表中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
eg:api名称为Goods__c的sObject,他的label名称为Goods.通过以下代码可以获取到label名称。
Schema.DescribeSObjectResult describeSObjectResult= Goods__c.sObjectType.getDescribe();
System.debug(describeSObjectResult.getLabel());
(四)Schema.ChildRelationship
此类包含的方法用来处理子关系的sObject。
此实例通过DescribeSObjectResult的getChildRelationships方法创建。主要有以下方法:
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()方法获取。
此类含有一个方法:
(六)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实例化字段描述元信息结果。
主要方法如下:
(七)Schema.PicklistEntry
此类中方法用于获取PickList的value数组。主要方法如下:
注意:一个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 }
如果有写错的地方欢迎批评指正,如果有不懂得地方欢迎留言,共同探讨,转载请注明出处。