salesforce零基礎學習(一百二十七)Custom Metadata Type 篇二 salesforce零基礎學習(一百一十一)custom metadata type數據獲取方式更新

本篇參考:

 salesforce零基礎學習(一百一十一)custom metadata type數據獲取方式更新

https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_custom_metadata_types.htm

https://help.salesforce.com/s/articleView?id=sf.custommetadatatypes_overview.htm&language=en_US&type=5

https://trailhead.salesforce.com/content/learn/modules/custom_metadata_types_dec/cmt_overview

https://developer.salesforce.com/docs/atlas.en-us.224.0.apexcode.meta/apexcode/apex_class_Metadata_Operations.htm

我們在之前的篇中簡單描述了 custom metadata type的使用,最開始的 custom metadata type是來建議取代 list custom setting,好處是可以基於metadata進行部署,不用像custom setting基於數據方式,容易出現漏部署情況,所以基於當時的版本來說, custom metadata type相對 list custom setting來說好處是基於metadata部署避免遺漏。

隨着 custom metadata type的不斷升級,目前增加了很多吸引人的點,主要是針對 Metadata Relationship字段類型的展開,接下來我們看一下這個新的類型可以實現的內容和場景。

一. Metadata Relationship類型

當我們在 custom metadata type創建字段時,目前字段類型增加了Metadata Relationship類型,此種類型可以設置兩類的關聯關係。

  • 關聯到其他的custom metadata type,比如metadata type中維護省和市的信息,可以在市的metadata type中關聯到省的metadata type。

  • 關聯到salesforce標準的表或者自定義表/字段的實例中,比如關聯到 Account表的 Industry字段(場景可以基於配置方式設置 default value)。

 當我們點擊此類型創建的下一步,會讓你選擇系統已經存在的 custom metadata type還是選擇 Entity Definition。需要注意的是,如果你的系統曾經已經創建過 Entity Definition,那樣以後的步驟中,還會再列表中可以選擇 Field Definition以及Entity Particle,這個在下面圖中會有涉及。

demo中會創建這兩種類型,其中關聯自定義 metadata type的創建步驟不在此處羅列,主要講一下 Entity Definition相關的關聯,當我們創建了關聯到 Entity Definition的字段以後,我們繼續創建 Metadata Relationship類型的字段,就可以看到下圖內容。其中:

  • Field Definition:關聯的是上述選定的表的標準或者自定義字段
  • Entity Particle:關聯的是上述選定的表的標準字段中的複合類型字段或者地理信息類型字段。

 當我們選擇 Field Definition類型以後,點擊下一步會選擇 controling field,這樣就會實現當選擇某個表信息以後,就可以選擇到當前這個表的字段。

 當我們創建表相關的表數據以後,我們就可以爲custom metadata type設置數據,下圖demo中維護了Account Customer Priority(自定義字段)默認值的一條數據,我們可以看到當Object Name選擇了 Account以後,Field Name就可以自動的基於Account(作爲 controling field)選擇到 Account表中的字段。

這裏針對父子的場景不做一步一步處理,感興趣的可以基於下圖進行數據的創建。

二. Custom Metadata Type使用場景介紹

1. 字段default value: 我們在項目上,有時需要在字段級別或者後臺代碼設置字段的默認值。原有方式是可以基於類型進行設置,比如picklist可以通過選擇,其他類型就在 Default Value處設置初始值。apex端設置可以通過Custom Label或者hardcode方式寫。除此以外,我們建議使用 Custom Metadata Type來統一維護初始值設置。UI方面可以基於指定的寫法進行設置,格式如下圖所示。

 

2. 用於validation rule / formula / process builder:這裏只針對validation rule進行舉例,寫法相同。舉個例子,當系統validation rule需要配置的規則用於很多表,並且這個值可能是動態修改的,我們不能每次變更都修改所引用到的所有的validation rule,這時我們可以基於custom metadata type進行配置來更好的可配置化管理。

 三. 通過apex class獲取 custom metadata type

1. 獲取 field Definition類型的metadata type數據

基於 apex端,我們可以通過基於metadata的方式,或者基於SOQL搜索方式獲取到這條數據,然後獲取這條數據的信息,下方的demo僅供參考。

 1). 通過 custom metadata type的getInstance方式獲取。此方法前提是你需要了解到這個metadata type的 Name信息。

Default_Value__mdt defaultValue = Default_Value__mdt.getInstance('Account_Customer_Priority_Default');
system.debug('*** default value: ' + defaultValue.Default_Value__c);

2). 通過表字段的名稱獲取(這裏代碼可以進行優化,目前demo中的場景爲有且僅有一條配置)。這裏我們通過 FieldDefinition獲取了當前表的 DurableId,原因是custom metadata type返回的 Field Definition是 DurableId,這個表會在下一篇博客做一些介紹。

List<Default_Value__mdt> defaultValueList = Default_Value__mdt.getAll().values();

Default_Value__mdt defaultValue;

List<FieldDefinition> fieldDefinitionList = [SELECT Id, DeveloperName, DurableId 
                                                FROM FieldDefinition  
                                                WHERE DeveloperName = 'Customer_Priority' 
                                                AND EntityDefinition.QualifiedApiName = 'Account'];
//TODO 實際項目中禁止此種寫法,需要非空判斷
String customerPriorityDurableId = fieldDefinitionList.get(0).DurableId;

for(Default_Value__mdt valueItem : defaultValueList) {
    if('Account'.equalsIgnorecase(valueItem.Object_Name__c) 
        && customerPriorityDurableId.equalsIgnorecase(valueItem.Field_Name__c)) {
        defaultValue = valueItem;
    }
}

if(defaultValue != null) {
    system.debug('*** default value : ' + defaultValue.Default_Value__c);
}

2. 獲取到關聯其他metadata type的數據

1). 通過 custom metadata type的getInstance方式獲取,方式同上,不做說明。

 2) 通過關聯父表的數據的developerName進行獲取(這裏代碼可以進行優化,目前demo中的場景爲有且僅有一條配置)。

List<Default_Value__mdt> defaultValueList = Default_Value__mdt.getAll().values();

Default_Value__mdt targetDefaultValue;

for(Default_Value__mdt valueItem : defaultValueList) {
    if(String.isNotBlank(valueItem.Parent_Metadata_Type__c) 
        && 'test_parent'.equalsIgnorecase(valueItem.Parent_Metadata_Type__r.DeveloperName)) {
        targetDefaultValue = valueItem;
    }
}

system.debug(JSON.serialize(targetDefaultValue));

我們看一下目標數據通過 getAll返回的JSON結構,我們會發現如果有負責結構內容,會將復結構的信息同樣返回。

{
    "MasterLabel": "TEST_RELATION_WITH_PARENT", 
    "NamespacePrefix": null, 
    "QualifiedApiName": "TEST_RELATION_WITH_PARENT", 
    "Parent_Metadata_Type__c": "m005g000002FMry", 
    "Language": "zh_CN", 
    "attributes": {
        "type": "Default_Value__mdt", 
        "url": "/services/data/v57.0/sobjects/Default_Value__mdt/m025g000000rtgz"
    }, 
    "DeveloperName": "TEST_RELATION_WITH_PARENT", 
    "Id": "m025g000000rtgz", 
    "Parent_Metadata_Type__r": {
        "attributes": {
            "type": "Parent_Metadata_Type__mdt"
        }, 
        "DeveloperName": "test_parent"
    }, 
    "Field_Name__c": null, 
    "Object_Name__c": null, 
    "Label": "TEST_RELATION_WITH_PARENT", 
    "SystemModstamp": "2023-03-15T10:00:03.000+0000", 
    "Default_Value__c": null
}

總結:本篇主要是介紹了一下 metadata type除取代list custom setting以外的其他的使用場景以及使用apex獲取的方式。篇中的demo也僅用於獲取數據用,對判斷,邏輯,可行性操作都可以進一步優化。篇中有錯誤地方歡迎指出,有不懂歡迎留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章