APEX初步 [4] —— 用DML来操作数据

DML操作记录

Apex是Force.com上专为数据访问设计的语言,拥有对数据的直接访问能力。不像其他语言还要设置Connection对象。Apex可以直接调用DML操作记录。

// Create the account sObject 
Account acct = new Account(Name='wokaogongsi', Phone='12345678', NumberOfEmployees=100);
// Insert the account by using DML
insert acct;

 

  • insert
  • update
  • upsert
  • delete
  • undelete
  • merge 将最多三条同类对象的记录合并为一条,删除其他的记录,并重新设置Relate关系

一共有以上几种DML语句。

 

批量DML

使用批量DML可以帮我们避免达到管理限制(比如每个Apex事务使用的DML语句限制为150,这样做是多租户架构下确保公平分享系统资源的一种机制),建议对一个List使用一句DML,而不是每个对象一句DML。

// 创建一个联系人清单
List<Contact> conList = new List<Contact> {
    new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
        new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
        new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
        new Contact(FirstName='Kim',LastName='Shain',Department='Education')};
            
// 将所有联系人使用一句DML来插入
insert conList;

// 用来暂存需要更新的联系人的List
List<Contact> listToUpdate = new List<Contact>();

// 枚举并添加Title
//  如果部门是Finance
for(Contact con : conList) {
    if (con.Department == 'Finance') {
        con.Title = 'Financial analyst';
        // 将更新后的联系人对象添加到List中
        listToUpdate.add(con);
    }
}

// 用一个DML批量更新List
update listToUpdate;

 

Upsert记录

Upsert一般用于当你有一个同时含有新纪录和已有记录的List在内存的时候。这时你就可以直接使用Upsert来插入新的并更新已有的。这样可以防止创建重复的记录而且我们也不需要再去判断哪些记录是已有的。

Upsert需要ID来匹配记录,如果在调用DML的时候特别指定字段,默认会用该对象的ID来匹配记录。也可以自己指定匹配字段。

对于自定义对象,需要指定一个自定义字段为External ID.

对于标准对象,需要可以指定任何theidLookup 属性设置为真的字段。要查看哪些字段有这个属性,访问Object Reference for Salesforce and Force.com.

upsert sObjectList Account.Fields.MyExternalId;

其中

Account.Fields.MyExternalId 就是我们指定的匹配字段。

  • 如果匹配字段没找到,插入新纪录
  • 如果匹配字段找到,更新记录
  • 如果匹配字段找到多条记录,产生Error,记录不被更新也不会插入。

 

下面的代码显示如何在一句DML中同时创建一个新纪录和更新已有记录。

// 插入小明
Contact xiaoming= new Contact(FirstName='小明',LastName='',Department='财务');       
insert xiaoming;

// 小明已被插入,且拥有一个ID了,这个ID将被Upsert用来匹配,因为没指定特别的匹配字段,所以系统默认会用ID
xiaoming.Description = '小明马上要被Upsert更新到了';

// 在内存中创建老李,先不存到数据库
Contact laoli= new Contact(FirstName='向阳',LastName='李',Department='技术');

// 将小明和老李放到List里面
List<Contact> contacts = new List<Contact> { xiaoming, laoli};

// 调用Upsert
upsert contacts;

// 结果是小明被更新,老李被创建。

 

 

DML的异常处理

使用Apex的try catch来捕捉DML的异常

try {//故意不放客户的名称来引发异常
    Account acct = new Account();
    // 插入客户
    insert acct;
} catch (DmlException e) {
    System.debug('已捕捉到DML异常: ' + e.getMessage());
}

 

Database 方法

Apex拥有内建的Database类,其中包括执行DML操作的静态方法,可以直接通过类名访问。 

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

与DML语句不同,Database方法拥有一个叫‘allOrNone’的可选参数,设置它可以决定要不要让这个操作‘部分成功’。这么参数的意思类似‘要么不做,要么全做’。如果设置为false,即是允许部分成功,那么成功的记录会被提交,发生Error的记录将不被提交,且会返回Error记录的信息,不会抛出异常。 这个参数默认为true

Database方法返回的是每条记录的成功或失败的信息。例如Insert和Update返回的是Database.SaveResult对象.

Database.SaveResult[] results = Database.insert(recordList, false);

 

部分成功

下面的例子展示了部分提交的特点,三个联系人被创建,一个联系人没放名字,导致出错,然后四个联系人的结果返回到SaveResult里面

// 创建一个联系人List
List<Contact> conList = new List<Contact> {
        new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
        new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
        new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
        new Contact()};
            
// 插入所有联系人
Database.SaveResult[] srList = Database.insert(conList, false);

// 枚举Saveresult
for (Database.SaveResult sr : srList) {
    if (sr.isSuccess()) {
        // 如果成功,显示ID
        System.debug('联系人插入成功; ID: ' + sr.getId());
    } else {
        // 如果失败,先获取这条记录上的全部Error信息(可能不止一个,所以要for)
        for(Database.Error err : sr.getErrors()) {
            System.debug('产生以下错误:');
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
            System.debug('导致错误的字段是: ' + err.getFields());
     }
    }
}

 

 

该使用DML语句还是Database方法?

  • DML用于你想让批量DML操作时的错误立即被抛出为Apex异常同时中断整个操作的情况下。
  • Database方法多用于你要支持‘部分成功’的情况下

 

posted @ 2017-03-05 10:17  AboveCloud  阅读(304)  评论(0编辑  收藏  举报