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 }

 如果有写错的地方欢迎批评指正,如果有不懂得地方欢迎留言,共同探讨,转载请注明出处。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

你可能不知道的字符比较中的“秘密”

有时候,一个简单的字符比较,你可能也会被弄得晕头转向。为什么这样说呢?请看下面这个例子(代码就不贴了,因为后来发现页面不支持这两个字符的显示)。猜测一下,会是什...

1827
来自专栏互联网杂技

JavaScript实现java中的|接口|继承|抽象类|继承|多态|对象|工厂模式|重写|重载|

//定一个接口方法, var Interface = function(name,methods){ if(arguments.length != 2){ ...

3188
来自专栏西枫里博客

ThinkPHP使用数组条件进行查询之同一字段多个条件

对同一表中多个字段的查询,在thinkPHP中使用数组条件进行查询,有三个好处,第一可以批量设置多个查询字段,第二可以设置多个查询条件,第三结构化你的代码,让代...

542
来自专栏DOTNET

【翻译】MongoDB指南/CRUD操作(一)

【原文地址】https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档...

2889
来自专栏xdecode

Java 代码质量

被滥用的instanceof instanceof滥用, 或者直接强转, 大都数情况可以用方法override, 而且应当避免使用isA(), isB()之类的...

1959
来自专栏CSDN技术头条

【问底】王帅:深入PHP内核(一)——弱类型变量原理探究

PHP是一门简单而强大的语言,提供了很多Web适用的语言特性,其中就包括了变量弱类型,在弱类型机制下,你能够给一个变量赋任意类型的值。 PHP的执行...

2205
来自专栏技术之路

Windows数据类型

 WORD:16位无符号整形数据 DWORD:32字节无符号整型数据(DWORD32) DWORD64:64字节无符号整型数据 INT:32位有符号整型数据类型...

1636
来自专栏鸿的学习笔记

python源码阅读笔记之几个值得注意的点

762
来自专栏禁心尽力

数据库设计之数据库,数据表和字段等的命名总结

数据库命名规则: 根据项目的实际意思来命名。 数据表命名规则: 1.数据表的命名大部分都是以名词的复数形式并且都为小写; 2.尽量使用前缀"table_"; 3...

1895
来自专栏C/C++基础

2018腾讯内部调岗面试试题1——使用C/C++但不能用sizeof判断操作系统是32位还是64位

2018上半年折腾了一回,想换个后台开发岗尝试锻炼一下自己,面了三个部门,将有关有意思的题目汇总记录下来,供大家参考。

651

扫码关注云+社区