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 条评论
登录 后参与评论

相关文章

来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

7066
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2752
来自专栏落花落雨不落叶

canvas画简单电路图

83611
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2997
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5747
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4385
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5228
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.4K7
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

27210
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

3005

扫码关注云+社区