salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解

建立好的数据表在数据库中查看有很多方式,本人目前采用以下两种方式查看数据表。

1.采用schema Builder查看表结构以及多表之间的关联关系,可以登录后点击setup在左侧搜索框输入schema Builder 或者build-->schema Builder进入;

2.采用force.com Explorer通过自己写查询语句来查询数据。

此链接为force.com Explorer的下载链接:  http://force-com-explorer-beta.software.informer.com/

下载完成后通过用户,密码,Security token账号登陆即可,见(篇一)。

此篇主要讲解表字段的Data type的每种类型以及多表关联下的SOQL查询,由于多表关联涉及到Data type中的look up或者master-detail,所以先讲一下Data type类型。

一)Data type

当数据表创建表的列时,会选择Data Type,不同的Data Type在页面处理以及数据插入时会有不同的处理。而且不同的字段会有其相对应的数据类型与之对应。

1.Auto Number:系统生成的序列号,通过自身定义的形式显示,为每条新纪录自动递增数;

2Formula:声明一个计算式,功能很强大,以后会单独篇章讲解formula用法;

3.Lookup Relationship:创建链接一个对象和另一个对象的关系,创建关系后,通过一个对象可以访问另一个对象的内容信息;

4.Master-Detail Relationship:创建一个特殊的父子关系(主从关系),和lookup Relationship 的相同与差异在下面介绍;

5.External Lookup Relationship:创建一个对象和另一个额外对象的关系。其中这个对象的数据存储在额外对象的数据源中;

6.Checkbox:声明一个布尔类型;

7.Currency:声明一个货币类型;

8.Date:声明一个Date类型,用户在前台绑定后可以直接使用Date类型相应的控件;

9.Date/Time:声明一个Date和Time类型,用户选择日期后,日期和当前时间便赋值到输入域;

10.Email:声明一个Email类型;

11.Geolocation:声明一个位置的类型,此类型包含经纬度信息;

12.Number:允许输入任何的数字,如果输入的全是0则全部移除;

13.Percent:声明一个百分比类型;

14.Phone:声明一个手机号码类型,输入的内容自动转换成此类型;

15.Picklist:声明一个列表类型,类似于HTML中的<select><option></option></select>关系,下面会有例子讲解;

16.Picklist(Multi-Select):声明一个列表类型,区别上面的为允许多选;

17.Text:声明一个字符串类型,最大长度为255;

18.Text Area:和Text类型相似,区别为内容可以换行;

19.Text Area(Long):和Text Area相似,最大长度为131072;

20.Text Area(Rich):富输入框,可以存储图片等;

21.Text(Encrypted):可以加密的形式存储;

22.URL:声明一个URL类型。

在项目中有一些是我们需要经常用到的类型,比如2,3,4,6,7,8,9,10,12,15,16,17,19,20,22.有一些类型配置相对简单,选中Data type 类型,输入字段名称然后一直执行下一步便可以完成操作;有一些类型配置则相对麻烦。接下来主要描述Lookup Relationship,Master-detail Relationship,Picklist这三种类型配置。

1)PickList

PickList声明一组数据,类似HTML中的选择框。通常用于确定的内容选择,比如学生表可以声明学生的学历--Education__c字段。他的值为确定范围的:幼稚园,小学,初中,高中,大学。。。所以这个字段可以声明为PickList类型字段。即此字段适用于值是确定范围的,有穷的情况。

声明PickList操作步骤如下:

1.如果存在Student表情况下,在setup-->create-->Objects下找到Student,点击进入。如果不存在Student,则按照上一篇步骤新建Student表;

2.在Custom Fields & Relationships模块下点击add新建一个字段并选择PickList点击Next;

3.在Field Label 中输入Education,鼠标移动到Field Name中则自动输入。将Value选择第二个Enter Value ,并在输入框中输入相应值,如图1所示;

4.一直选择Next,最后点击Save按钮新增PickList类型字段。

                                                                    图1

2)Lookup Relationship 与Master-detail Relationship

二者均可以关联两个数据表,实现其他数据库语言类似join功能,二者区别如下:

1.master detail关系比较紧密,可以自动进行级联删除,Lookup 关系相对灵活,不可以级联删除,如果删除操作,则需要先删除从表,再删除主表操作;

2.用lookup允许父为空,master不允许--master模式需要级联删除,如果master情况父为空则无法级联删除。

具体使用那种分数据表关系,如果数据表关联比较紧密,删除时需要级联删除则可以选择master-detail模式,如果关系相对松散,希望表之间灵活控制,则推荐使用lookup关系。

 以权限表和角色表两个表关系来引入Look up.

做过权限管理的人都知道,一个权限可以对应多个角色,一个角色可以分配多种权限,权限与角色是多对多关系。比如,查看文章的权限可以是管理员具有查看权利,也可以是普通用户具有查看的权利;一个管理员可以有查看的权限,也可以有修改的权限。所以应该引入一个中间表角色权限表作为中间表,实现以上的数据表结构构造,如图2所示。

                                                                    图2

通过图2可以看出,PRIVELEGEROLE__c外键依赖于PRIVELEGE__c 以及 ROLE__c,即PRIVELEGEROLE__c的PRIVELEGEID__c字段与PRIVELEGE__c的Id字段进行关联,PRIVELEGEROLE__c的ROLEID__c的Id字段进行关联,通过这两个关联字段可以访问到这两个关联的表中。访问方式比较特殊,即通过PRIVELEGEID__r可以访问到PRIVELEGE表(对应的sObject为PRIVELEGE__c)中的字段,通过ROLEID__r可以访问到ROLE表(对应的sObject为ROLE__c)中的字段。

注意:这三个表如果按照Master-Detail关系情况,则PRIVELEGE__c和ROLE__c为主表,PRIVELEGEROLE__c为从表(外键依赖于另外两个表)。通过外键依赖的sObject,将sObject最后的c改成r便可以访问此表。eg:

SELECT
     PRIVELEGEID__r.Id,PRIVELEGEID__r.PRIVELEGENAME__c,
     ROLEID__r.ROLENAME__c, Id
FROM PRIVELEGEROLE__c

通过上面例子可以看出:PRIVELEGEROLE__c表中的PRIVELEGEID__c是表中的一个字段,通过LookUp关系关联到PRIVELEGE__c,则PRIVELEGEID__r则相当于PRIVELEGE__c表的一个引用,通过PRIVELEGEID__r则可以访问PRIVELEGE__c表中的数据,为了更加明确的了解,将数据表查询结果通过JSON形式显示,便会更加的一目了然。通过查询输出的json结果可以看出,PRIVELEGEID__r他的类型为PRIVELEGE__c,并且把此条记录中的PRIVELEGE__c需要的字段信息查出,ROLEID__r类型为ROLE__c,并且将此条记录中ROLE__c表需要的字段信息查出。推荐下方的网页查看json,它可以将输出的混乱的json格式变得整洁,增强可读性。

json在线转换网页:http://json.parser.online.fr/

查询结果转成JSON语句:

String queryString = 'SELECT              
                      PRIVELEGEID__r.Id,PRIVELEGEID__r.PRIVELEGENAME__c,
                      ROLEID__r.ROLENAME__c, ROLEID__c, Id 
                      FROM PRIVELEGEROLE__c';
List<PRIVELEGEROLE__c> prs = Database.query(queryString);
String queryJson = JSON.serialize(prs);
System.debug(queryJson);

以下为查询的输出json结果。

 1 [
 2     {
 3         "attributes":{
 4         "type":"PRIVELEGEROLE__c",
 5         "url":"/services/data/v36.0/sobjects/PRIVELEGEROLE__c/a03280000089RbkAAE"
 6         },
 7         "PRIVELEGEID__c":"a012800000KufW5AAJ",
 8         "ROLEID__c":"a0228000008fwJ6AAI",
 9         "Id":"a03280000089RbkAAE",
10         "PRIVELEGEID__r":{
11             "attributes":{
12                 "type":"PRIVELEGE__c",
13                 "url":"/services/data/v36.0/sobjects/PRIVELEGE__c/a012800000KufW5AAJ"
14             },
15             "Id":"a012800000KufW5AAJ",
16             "PRIVELEGENAME__c":"权限添加"
17         },
18         "ROLEID__r":{
19             "attributes":{
20                 "type":"ROLE__c",
21                 "url":"/services/data/v36.0/sobjects/ROLE__c/a0228000008fwJ6AAI"
22             },
23             "Id":"a0228000008fwJ6AAI",
24             "ROLENAME__c":"角色添加"
25         }
26     }
27 ]

接下来讲解如何在网站中构建出LookUp关系,如果不懂如何创建表和字段,请查看上一篇内容。

1.创建PRIVELEGE表,按照图二的表结构可以看出,需要创建PRIVELEGENAME和PRIVELEGEDESCRIBE两个字段,创建后,系统会自动为其创建API Name;

2.创建ROLE表,按照图二的表结构可以看出,需要创建ROLENAME和ROLEDESCRIBE两个字段,创建后,系统会自动为其创建API NAME;

3.创建PRIVELEGEROLE表;

4.创建和PRIVELEGE表的依赖,新增一个字段,Datatype选择LookUp,点击Next,如图3;

5.在Relate To下拉框处选择需要关联的表,此处选择PRIVELEGE表,如图4,然后点击Next;

6.在Field Label 输入字段名称,此处输入PRIVELEGEID,鼠标移动到Field Name,则自动赋值,如图5,一直点击next;

7.点击save&new按钮,重复4--6步骤,将于ROLE表关联的字段创建,Field Label处输入ROLEID,最后save,关联结束,如图6.

             图3                                      

                   图4

                   图5                                            

                  图6

使用Master-Detail关系和使用LookUp关系创建基本相同,这里不在做说明。

接下来说明DML操作。现在说一下增删查操作,改操作和其他相同,则不再讲述。

上述代码查询出来的内容为PRIVELEGEROLE__c对象,那么如何检索出需要的PRIVELEGE__c对象的字段或者ROLE__c对象的字段呢?

apex提供简单的方式来处理,即如果各层级嵌套,则可以通过类似A.B.C方式来获取需要的内容。查询操作代码将与删除操作代码在下方一起显示。 

因为表之间存在关联关系,所以进行增加操作时,应先处理主表,然后再处理从表;进行删除操作时,应先删除从表,在删除主表。

这里在啰嗦一下:主表表示独立的表,从表表示外键依赖于其他表的表。主表有时也被成为父表,子表有时也被成为子表,上述的例子中,PRIVELEGEROLE为从表,其他为主表

增加操作代码举例:

PRIVELEGE__c privelege = new PRIVELEGE__c(PRIVELEGENAME__c='权限添加',PRIVELEGEDESCRIBE__c='权限描述');
ROLE__c role = new ROLE__c(ROLENAME__c='角色添加',ROLEDESCRIBE__c='角色描述');
insert privelege;//执行insert后,privelege的ID字段便会自动被赋值,且唯一
insert role;
ID roleId = [select Id from ROLE__c limit 1][0].ID;
ID privelegeId = [select Id from PRIVELEGE__c limit 1][0].ID;
PRIVELEGEROLE__c privelegeRole = new PRIVELEGEROLE__c();
privelegeRole.ROLEID__c = roleId;
privelegeRole.PRIVELEGEID__c = privelegeId;
insert privelegeRole;//添加操作需要先添加主表,主表添加以后,ID便自动赋值,然后再取出ID操作从表。

删除操作代码举例:

 1 String deletePrivelegeRoleSql = 'SELECT  ROLEID__c,     
 2                                                 Id,PRIVELEGEID__r.ID,ROLEID__r.ID' +  
 3                                                 'FROM PRIVELEGEROLE__c';
 4 List<SObject> privelegeRoles = Database.query(deletePrivelegeRoleSql);
 5          
 6  if(privelegeRoles.size() > 0) {//查询有记录的时候才对子表进行删除操作
 7              
 8      PRIVELEGEROLE__c privelegeRole = (PRIVELEGEROLE__c)privelegeRoles[0];
 9      ID privelegeId = privelegeRole.PRIVELEGEID__r.ID;//通过层级A.B.C可以查出需要使用的变量
10      ID roleId = privelegeRole.ROLEID__r.ID;
11      try {
12        Database.delete(privelegeRole.Id);
13      } catch(Exception e) {
14        System.debug('error occured when deleting privelegerole!');
15      }
16 
17       try {
18             Database.delete(privelegeId);
19         Database.delete(roleId);
20       } catch(DmlException e) {
21         System.debug('error occured when deleting privelege or role');
22       }
23 }//先删除从表,在删除主表。删除从表后,表数据即消失。所以在表数据删除以前,需要先将需要的数据取出,比如上述的ID字段

通过此篇,可以对表关联操作有一个基础的认识,如果需要详细了解内容,请查看官方的PDF文档。如果篇中有写错的地方,欢迎批评指正。有不懂得地方也可以留言。

下一篇将介绍批处理的简单使用。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小李刀刀的专栏

在ASP中实现UNIX时间戳

  在康盛创想发布UC以后,我曾经尝试为其编写ASP把版本的客户端类库,过程中发现了几个问题,首当其冲的当然是服务器端不支持非php平台的接口,这个问题直接导致...

3416
来自专栏数据之美

玩转 SHELL 脚本之:linux date 知多少?

最近好久没 update 了,一来是近期有点烦人的私事需要处理,二来是工作有点忙,业余时间还要整个 PPT,搜集素材啥的,非常耗时间。。。好吧,这都是借口,其实...

1817
来自专栏技术博客

ExtJs十四(ExtJs Mvc图片管理之四)

现在来实现排序的问题。要实现远程排序,首先要清楚的是排序信息是如何提交到服务器的,而这个,利用FireBug相当简单。

613
来自专栏10km的专栏

jface databinding:输入无效数值时强制恢复初始值-updateModelToTarget

解决方案 Binding类中的updateModelToTarget方法,就是实现从数据对象到目标对象(比如Widget)的更新方法,只要调用这个方法就能强制让...

1815
来自专栏用户2442861的专栏

javascript dom学习笔记

http://blog.csdn.net/zhoulenihao/article/details/11099455

441
来自专栏林冠宏的技术文章

Go 实现 自动检索 API 错误码代码行 并 打印成文档,例 markDown 形式等

1053
来自专栏Hongten

JSP 三讲

401
来自专栏我的博客

ThinkPHP3.1.2笔记

1.开启trace 方法一:在配置文件中添加(默认在config.php,如果定义debug模式,可以定义在debug.php) SHOW_PAGE_TRAC...

2538
来自专栏岑玉海

sqoop 常用命令整理(二)

  26.Validate 它用来比较源数据和目标数据的数量 它有三个接口 Validator. 它有三个接口 Validator. Property: ...

3046
来自专栏腾讯云API

腾讯云API:无服务器函数

无服务器函数是一个很好玩的东西,可以通过这个程序跑一些脚本,在一定程度上,是很方便的。但是作为新鲜事物,一般很难被大家接受,所以,我今天在这里,就做一个小例子,...

2885

扫码关注云+社区