Schema浅谈

想象一下当我们访问salesforce数据时,当我们在domain后面输入 /001就会跳转到 Account列表,输入 006就可以跳转到 Opportunity列表,原因是什么呢?在salesforce中,表和字段以及其他的配置文件,都是基于metadata进行存储和管理。我们想要了解表的label信息,表都包含哪些字段,表是标准表还是自定义表,表包含哪些record type信息等等,这些大部分可以通过Schema获取到。salesforce中想要获取Metadata信息,可以通过Schema以及Tooling API中的一些表进行实现,以下主要介绍以下常用的 Schema命名空间下的类的使用。

需要注意的是,Schema涉及到很多内容,篇中知识针对表字段进行描述,针对app/ tab等等,大家可以自行查看 Schema命名空间下的其他类的使用方式。

sObjectType以及DescribeSObjectResult

Apex提供了两种数据结构以及一个方法来获取 sObject以及Field的metadata信息。

上述内容描述较为抽象,我们可以将Token简单的理解成 sObjectType,将 Describe Result描述成 DescribeSObjectResult,我们最终的目的是获取到一个 sObject的 DescribeSObjectResult,从而获取到当前表的metadata信息,比如当前user对这个表的可访问性,表的label,表是自定义还是标准等等。接下来我们以Account表为例看一下哪些种方式可以获取到 DescribeSObjectResult。demo中仅仅调用了getLabel方法,其他方法可以自行查看。

//以下用于确定的需求,已经知道获取哪个表的 Describe Result

//Token代表 Schema.SObjectType
sObject s = new Account();
Schema.SObjectType accountObjType = s.getsObjectType();
Schema.DescribeSObjectResult dsr = accountObjType.getDescribe();

Schema.SObjectType accountObjType2 = Account.sObjectType;
Schema.DescribeSObjectResult dsr2 = accountObjType2.getDescribe();

Schema.DescribeSObjectResult dsr3 = Account.sObjectType.getDescribe();

Schema.DescribeSObjectResult dsr4 = Schema.SObjectType.Account;

//以下可用于动态传递值来获取传递的Describe Result,我们可以将 Account理解成通过参数动态传递

String[] types = new String[]{'Account'};
Schema.DescribeSObjectResult dsr5;
Schema.DescribeSobjectResult[] results = Schema.describeSObjects(types);
if(results != null && results.size() > 0) {
	dsr5 = results[0];
}

//此种方法谨慎使用,因为 Schema.getGlobalDescribe()会返回当前系统的所有的object的mapping,heap size所占较大。
Schema.DescribeSObjectResult dsr6;
Map<String, Schema.SObjectType> allObjectTypeMap = Schema.getGlobalDescribe();
for(String objectAPIName : allObjectTypeMap.keySet()) {
	if('Account'.equalsIgnorecase(objectAPIName)) {
		Schema.SObjectType tempObjectType = allObjectTypeMap.get(objectAPIName);
		dsr6 = tempObjectType.getDescribe();
	}
}

//结果都会输出account
System.debug(LoggingLevel.INFO, '*** dsr.getLabel(): ' + dsr.getLabel());
System.debug(LoggingLevel.INFO, '*** dsr.getLabel(): ' + dsr2.getLabel());
System.debug(LoggingLevel.INFO, '*** dsr.getLabel(): ' + dsr3.getLabel());
System.debug(LoggingLevel.INFO, '*** dsr.getLabel(): ' + dsr4.getLabel());
System.debug(LoggingLevel.INFO, '*** dsr.getLabel(): ' + dsr5.getLabel());
System.debug(LoggingLevel.INFO, '*** dsr.getLabel(): ' + dsr6.getLabel());

SObjectField以及DescribeFieldResult

同 sObject的token以及Describe Result相似,针对Object Field同样也包含了 token以及 Describe Result。

针对token我们可以使用以下的方式。

针对Describe Result我们可以使用以下的方式。

我们来直接看demo进行更好的了解,demo中我们以 Account的Name字段作为演示。

//获取 field token
Schema.SObjectField fieldToken = Account.Name;

//获取field result

//通过DescribeSObjectResult中的fields变量,然后找到Name
Schema.DescribeFieldResult dfr = Schema.sObjectType.Account.fields.Name;
//通过token获取field result
Schema.DescribeFieldResult dfr2 = Account.Name.getDescribe();

//以下可用于动态传递值来获取传递的Describe Result,我们可以将 Account的Name字段理解成通过参数动态传递
Schema.DescribeFieldResult dfr3;
Map<String, Schema.SObjectField> fieldMap = Schema.SObjectType.Account.fields.getMap();

for(String fieldAPIName : fieldMap.keySet()) {
	if('Name'.equalsIgnorecase(fieldAPIName)) {
		Schema.SObjectField tempField = fieldMap.get(fieldAPIName);
		dfr3 = tempField.getDescribe();
	}
}

System.debug(LoggingLevel.INFO, '*** dfr.getLabel: ' + dfr.getLabel());
System.debug(LoggingLevel.INFO, '*** dfr.getLabel2: ' + dfr.getLabel());
System.debug(LoggingLevel.INFO, '*** dfr.getLabel3: ' + dfr.getLabel());

参考文档:

Salesforce Developers

Salesforce Developers