Salesforce 中的数据库操作方式

Salesforce 为用户和开发者提供了四种基本的数据库操作方式:

  • Apex 中的 DML 语句
  • Apex 中的 Database 类
  • SOQL 查询
  • SOSL 查询

DML 语句

DML 全称 Data Manipulation Language,是 Apex 中直接进行数据库操作的一组命令。和大多数数据库类似,DML 语句包括:

  • insert,插入
  • update,更新
  • upsert,插入或更新
  • delete,删除
  • undelete,撤销删除
  • merge,合并

    每个DML语句都可以对一个或多个 sObject 对象进行操作。Salesforce 鼓励用户使用同一条 DML 语句对多条数据进行操作,而不是对每条数据分别调用一次相同的 DML 语句。这样做可以优化执行效率。

upsert 语句特点

upsert 语句包括了 insert 和 update 的功能。对于将要进行 upsert 操作的数据,Salesforce 会检索数据库中这些数据是否已经存在。对于已经存在的数据,进行 update 处理,对于不存在的数据,进行 insert 处理。

需要注意的是,upsert 语句的执行效率比 update 和 insert 都要低,所以我们在进行开发的时候,要尽可能的避免使用 upsert 语句。

merge 语句特点

merge 语句可以将至多三条相同类型的记录合并,只保留一条数据,删除其他两条,并将之前与三条记录相关的其他数据记录重新关联到保留的记录中。

系统内的 ID 字段

对于每个对象,无论是标准的还是自定义的,Salesforce 都会自动创建一个 ID 字段。该字段的值是由系统自动生成,在整个系统内部唯一存在,并且不会更改。

在用户利用 DML 的 insert 或 upsert 语句插入新的数据记录后,便可以直接使用该记录的 ID 字段。

Account acc = new Account(Name='test account');

insert acc;

ID accountId = acc.Id;

在上面的代码中,变量 accountId 中存储了刚刚建立的 Account 记录的 ID 值。用户可以立即利用该 ID 值进行其他操作。

DML 语句操作示例

// 插入单条数据
Account acc = new Account(Name='test');
insert acc; // 插入多条数据
List<Account> accList = new List<Account> {
new Account(Name='test1'),
new Account(Name='test2'),
new Account(Name='test3'),
new Account(Name='test4')
};
insert accList; // 更新单条数据
acc.Name = 'test name';
update acc; // 更新多条数据
for(Account a : accList) {
a.Phone = '12345678';
}
update accList; // 删除单条数据
delete acc; // 删除多条数据
delete accList;

upsert 语句示例

upsert 语句运行时,先比较数据中某个字段的值是否在数据库中已经存在,如果存在则更新该数据,否则插入该数据。

upsert 语句有两个参数,第一个参数是需要操作的单条数据或一组数据,第二个参数是可选参数,表明了应该用数据中的哪个字段进行比较,如果没有声明则默认使用ID字段。

要注意的是,第二个参数必须是 ID 字段、自定义的“外部 ID”字段或者索引字段。

假设 Contact 对象中有一个“外部 ID”字段,名为“External_contact_person_number__c”,那么:

// 插入一条Contact数据
Contact con1 = new Contact(FirstName='A', LastName='LA');
insert con1; // 插入数据之后更新数据
con1.Description = 'inserted contact 1'; // 新建另一条Contact数据
Contact con2 = new Contact(FirstName='B', LastName='LB'); // 将两条Contact数据加入一个列表中
List<Contact> cons = new List<Contact> { con1, con2 }; // 对列表进行upsert操作
upsert cons;

上面代码执行的结果是 con1 数据被更新了,con2 数据被插入了。

如果上面的代码改为:

Contact con1 = new Contact(FirstName='A', LastName='LA', External_contact_person_number__c = 'ex001');
insert con1; Contact con2 = new Contact(FirstName='B', LastName='LB', External_contact_person_number__c = 'ex001'); upsert con2 Contact.Fields.External_contact_person_number__c;

那么系统在 upsert 时会比较 Contact 数据中的 External_contact_person_number__c 字段,找到 External_contact_person_number__c 字段是 “ex001” 的数据,然后直接进行更新。所以上面代码的执行之后,系统中只有一条 Contact 记录,其 FirstName 和 LastName 字段的值被更新为 “B”。

注意,如果在 upsert 语句执行时,系统查找到系统中已经有两条或更多符合条件的记录,则该操作会报错,不会更新或插入任何数据。比如:

// 插入多条数据
List<Contact> conList = new List<Contact> {
new Contact(FirstName='A', LastName='LA', External_contact_person_number__c = 'ex001'),
new Contact(FirstName='B', LastName='LB', External_contact_person_number__c = 'ex001')
};
insert conList; // 新建数据
Contact con = new Contact(FirstName='C', LastName='LC', External_contact_person_number__c = 'ex001'); // upsert新建的数据,基于LastName字段
upsert con Contact.Fields.External_contact_person_number__c;

这段代码会报错,因为系统中已经有了两条 External_contact_person_number__c 为 “ex001” 的数据,无法进行插入或更新。

如果最后的 upsert 操作改为:

upsert con;

则不会有问题,因为比较的是 ID 字段,而 ID 字段必然是唯一的,不存在于系统中,所以该记录(con)会被插入。

Database 类

Apex中有Database类,其中包含了一组静态函数,它们的作用和 DML 语句类似:

  • Database.insert()
  • Database.update()
  • Database.upsert()
  • Database.delete()
  • Database.undelete()
  • Database.merge()

    与 DML 语句不同的是,每个函数都有一个可选布尔型参数,可以决定当操作的一组数据中部分数据出现错误时,是否将没有出错的数据继续执行相应的命令。

比如:

Database.insert(accList, false);

如果插入的一组数据 accList 中有不符合条件的数据,那么系统会跳过这些数据,将剩下的数据成功插入数据库,并且不会报错。

该布尔型参数默认为“真”(true)。当有部分数据出错时,所有数据都不会被执行相应的操作,并报错。

Database 类的操作返回值

Database 类的操作函数会返回一组值,对于进行操作的每一条数据,都会有成功或失败的信息。

// insert 的结果
Database.SaveResult[] = Database.insert(recordList, false); // upsert 的结果
Database.UpsertResult[] = Database.upsert(recordList, false); // delete 的结果
Database.DeleteResult[] = Database.delete(recordList, false);

SOQL

SOQL 是 Salesforce 提供的数据库操作语言,全称是 Salesforce Object Query Language,类似于 SQL。

在 Developer Console 的 Query Editor 部分,可以键入 SOQL 语句并进行查询。

在 Apex 中,可以直接调用 SOQL 语句操作一个或一组 sObject 对象。

比如:

List<Account> accList = [SELECT Name FROM Account];

SOQL 语法

SOQL 基本语法和 SQL 类似,比如 SELECT 语句的格式是:

SELECT 字段 FROM sObject [WHERE 条件]

其中 WHERE 语句是可选部分。

要注意的是:

  1. SELECT 后面声明的字段需要用逗号隔开,并且不能用“*”来选取所有字段,必须声明每个要查询的字段
  2. 对于不存在于 SELECT 语句的字段,系统不会去查询其值,所以后面的语句无法使用这些字段的值

比如:

List<Account> accList = [SELECT Id, Name FROM Account];

// 使用 Phone 字段会出错
// accList[0].Phone = '12345678';

查询结果中的每个 Account 对象只包含 Id 和 Name 字段的值,如果用户想使用 Phone 字段的值,系统会报错。

SELECT 语句后面也可以加 ORDER BY 和 LIMIT 语句。比如:

List<Account> accList = [SELECT Id, Name FROM Account ORDER BY Name LIMIT 20];

通配符

在 SOQL 的 WHERE 语句中,如果想查询某字段包含某个值的话,可以用通配符进行模糊查询。比如:

SELECT Id, Name FROM Account WHERE Name LIKE '%test%'

上面的语句查询的是字段 Name 中包含 “test” 的所有 Account 记录。

使用变量

如果要在 SOQL 查询中使用变量,则变量名前需要用“:”来引导。比如:

String queryStr = 'test';

List<Account> accList = [SELECT Id, Name FROM Account WHERE Name LIKE :queryStr];

关联对象的查询

在 SOQL 语句中,可以嵌套查询相关联的对象。在子对象中,定义了和父对象相关联的字段,其中的“子级关系名称”属性需要在查询中使用。

对于标准对象,“子级关系名称”可以直接使用。对于自定义对象,要在“子级关系名称”后面加上“__r”。

比如:

// 嵌套查询和 Account 相关的 Contact 对象,其中 “Contacts” 是 Contact 对象中和父对象 Account 关系字段的子级关系名称
List<Account> accWithConList = [SELECT Name,
(SELECT FirstName, LastName FROM Contacts)
FROM Account
WHERE Name like '%test'
]; // 查询到的 Contact 对象
List<Contact> firstConList = accWithConList[0].Contacts; // 使用 Contact 对象中查询到的值
String firstNameFromQuery = firstConList[0].FirstName;
String lastNameFromQuery = firstConList[0].LastName;

又如:

// 查询父对象的字段内容
List<Contact> conList = [SELECT Account.Name FROM Contact WHERE FirstName = 'testFirst']; // 使用父对象的字段内容
String accName = conList[0].Account.Name;

自定义对象的关联对象

比如:

  1. 在系统中建立了 “Address__c” 对象和 “Street__c” 对象
  2. 每个 “Address__c” 对象中包含若干个 “Street__c” 对象
  3. 在 “Street__c” 对象中定义了字段表明和 “Address__c”的关系,其“子级关系名称”的名字是 “Streets”。那么查询可以这样写:
// 从父对象查询子对象的字段
SELECT Name, (SELECT Name FROM Streets__r) FROM Address__c // 从子对象查询父对象的字段
SELECT Name, Address__r.Name FROM Street__c

SOSL

SOSL 是 Salesforce 提供的数据库操作语言,全称是 Salesforce Object Search Language。

SOSL 主要用于在数据库的各个对象中查询符合条件的列。

SOSL 和 SOQL 类似,都可以在 Apex 中直接调用。SOSL 返回的类型永远是一个包含了 sObject 对象列表的列表,即 List<List> 类型。

比如,对于所有 Account 和 Contact 对象,查询任一字段中包含 “test” 的记录:

List<List<SObject>> resultList = [FIND 'test'
IN ALL FIELDS
RETURNING Account(Name), Contact(FirstName, LastName)];

返回的结果便是符合条件的两个列表,一个列表包含 Account 对象,其中只有 Name 的值,另一个列表包含 Contact 对象,其中只有 FirstName 和 LastName 的值。

SOSL语法

SOSL 的基本语法是:

FIND 要查询的字符串 IN 要查找的字段 RETURNING 查询结果包含的对象和字段名

其中:

  • 要查询的字符串是无关大小写的
  • 要查找的字段是可选参数,默认是所有字段,即 “ALL FIELDS”,也可以在此声明只在某几个字段中查询,可以使用的仅限于:“NAME FIELDS”、“EMAIL FIELDS”、“PHONE FIELDS”、“SIDEBAR FIELDS”
  • 查询结果包含的对象和字段名可以包含一个或多个想要查询的对象,并声明哪些字段保存在查询结果中

Salesforce 数据库操作简介的更多相关文章

  1. 【Django】Django model与数据库操作对应关系(转)

    Django对数据库的操作分用到三个类:Manager.QuerySet.Model. Manager的主要功能定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manag ...

  2. android中的数据库操作

    如何在android中调用数据库资源 在android中主要有两种方法来实现对数据库的访问,一种是adb shell方式,另一种是通过相关的android 的java类来间接的对数据库来进行操作.其中 ...

  3. android中的数据库操作(转)

    android中的数据库操作 android中的应用开发很难避免不去使用数据库,这次就和大家聊聊android中的数据库操作. 一.android内的数据库的基础知识介绍 1.用了什么数据库   an ...

  4. Java Web的数据库操作(一)

    一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库交互,JDBC在Java程序与 ...

  5. Java Web----Java Web的数据库操作(一)

    Java Web的数据库操作 一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库 ...

  6. Java8 Lambda表达应用 -- 单线程游戏server+异步数据库操作

    前段时间我们游戏server升级到开发环境Java8,这些天,我再次server的线程模型再次设计了一下,耗费Lambda表情. LambdaJava代码.特别是丑陋不堪的匿名内部类,这篇文章主要就是 ...

  7. VC与ADO数据库操作

    VC与ADO数据库操作 学研部的同志们,大家好! 想开一次学习会,实习时间冲突了,只好把文档发给大家看了.重点推荐李振龙的BMP读图教程! 尤其是大三GIS班的同志,注意了,可能实习用得上的! 一.A ...

  8. Python程序练习4--模拟员工信息数据库操作

    1.功能简介 此程序模拟员工信息数据库操作,按照语法输入指令即能实现员工信息的增.删.改.查功能.   2.实现方法 架构: 本程序采用python语言编写,关键在于指令的解析和执行:其中指令解析主要 ...

  9. Cayley图数据库的简介及使用

    图数据库   在如今数据库群雄逐鹿的时代中,非关系型数据库(NoSQL)已经占据了半壁江山,而图数据库(Graph Database)更是攻城略地,成为其中的佼佼者.   所谓图数据库,它应用图理论( ...

随机推荐

  1. java.io.IOException: No space left on device 错误

    今天碰到比较奇怪的问题: 7/05/14 19:20:24 INFO util.Utils: Fetching http://192.168.31.160:33039/jars/spark_study ...

  2. 使用 PLSQL 提示动态执行表不可访问,本会话的自动统计被禁止

    使用PLSQL,第一次执行表的select操作的时候,提示"动态执行表不可访问,本会话的自动统计被禁止",如上图: 这种问题,一看就是当前连接用户没有对sys用户下的表v$sess ...

  3. Swift5 语言指南(八) 控制流

    Swift提供了各种控制流程语句.这些包括while多次执行任务的循环; if,guard和switch基于特定条件执行不同代码分支的语句; 和语句,如break和continue对执行流在你的代码转 ...

  4. 自动化测试之数据库操作pymysql

    1.下载并导入pymysql 2.配置参数连接mysql db = pymysql.connect(**config) config = { 'host': str(host), 主机地址 'user ...

  5. asp.net mvc 安全测试漏洞 " HTTP 动词篡改的认证旁路" 问题解决

    IBM Security Appscan漏洞筛查-HTTP 动词篡改的认证旁路漏洞,具体解决方案: 在Web.Config中system.webServer节点增加配置security: <se ...

  6. Linux - 创建定时任务

    crontab命令 用来创建周期性定时任务 crontab {-l|-r|-e} -l 显示当前的 crontab -r 删除当前的 crontab -e 使用编辑器编辑当前 crontab 文件 输 ...

  7. rest framework 尝鲜

    安装 pip install djangorestframework 新建项目 python manage.py startapp idcs 添加模型(models.py) class Idcs(mo ...

  8. python面试

    第一部分 python基础篇 1.简述解释型和编译型编程语言? 解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候才翻译.这样解释型语言 ...

  9. php -- 目录、路径、磁盘

    ----- 028-dir.php ----- <!DOCTYPE html> <html> <head> <meta http-equiv="co ...

  10. oracle笔记--查询10条之后记录的数据

    本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 由于之前一直在用mysql 对于oracle 的一些语法不太了解,自己有一次去面试让写一个oracle ...