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语句:
1
2
3
4
5
6
7
|
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文档。如果篇中有写错的地方,欢迎批评指正。有不懂得地方也可以留言。
下一篇将介绍批处理的简单使用。