Skip to content

对象

创建Object对象

使用db.object方法用于构造Object对象:

ts
import * as db from 'db';

@useObject(['student__cst'])
class Demo {
    test(): void {
        let student = db.object('student__cst');
    }
}

所有操作的object对象,需要使用useObject函数装饰一下, 参数必须是常量,用于打包app时分析脚本依赖了哪些对象。

单条操作

插入单条记录

ts
let s = db.object('Student__CST');

let record = {
    "name": "hello",
    "age__CST": "demotest"
};


let id = s.insert(record);
console.log("insert result = ", id);
let r = s.query(id);
console.log("insert record = ", r);

根据id查询记录

ts
let s = db.object('Student__CST');

let record = s.query(id);
console.log("query", record)

根据id更新记录

ts
let s = db.object('Student__CST');

let record = {name: "hello1"};
let count = s.update(id, record);
console.log("update result = ", count);
let r = s.query(id);
console.log("after update = ", r)

根据id删除记录

ts
let s = db.object('Student__CST');

let count = s.delete(id);
console.log("delete result = ", count);
let r = s.query(id);
console.log("after delete = ", r);

批量操作

批量插入记录

ts
let s = db.object('Student__CST');

let records = [];

for (let i = 0; i < 100; i++) {

    let name = "hello" + <string><any>(i);
    let age = "age" + <string><any>(i)
    let record = {
        "name": name,
        "age__CST": age
    }

    records.push(record);
}

let ids = s.batchInsert(records);
console.log("id list = ", ids);

count = s.count();
console.log("record count = ", count);

批量创建父子对象记录

批量创建的记录在一个完整的事务中,全部成功或全部失败。成功时返回父子对象记录id列表.

ts
let s = db.object('Customer__CST');

// 父子记录需要通过关联字段关联起来,如下面的记录通过`Contacts`关联在一起,形成一条组合记录。
let records = [ {
    "name": "hello",
    "count__CST": 123,
    "Contacts": {
        "records": [
            {
                "name": "hello_contact1"
            },
            {
                "name": "hello_contact2"
            }
        ]
    }
}];

let ids = s.compositeInsert(records);
console.log("id list = ", ids);

count = s.count();
console.log("record count = ", count);

条件操作

condition

单个condition

ts
{
    conjunction: db.Conjunction.AND,
    conditions: [
        {
            field: "f1",
            operator: db.Operator.eq,
            value: "123"
        },
        {
            field: "f2",
            operator: db.Operator.eq,
            value: "456"
        },
        {
            field: "f3",
            operator: db.Operator.in,
            value: [
                "a",
                "b",
                "c"
            ]
        }
    ]
}

组合condition

ts
{
  conjunction: db.Conjunction.AND,
  conditions: [
    {
      field: "f1",
      operator: db.Operator.eq,
      value: "123"
    },
    {
      field: "f2",
      operator: "eq",
      value: "456"
    },
    {
      field: "f3",
      operator: db.Operator.in,
      value: [
        "a",
        "b",
        "c"
      ]
    },
    {
      condition: {
        conjunction: db.Conjunction.OR,
        conditions: [
          {
            field: "f4",
            operator: db.Operator.eq,
            value: "789"
          },
          {
            field: "f5",
            operator: db.Operator.eq,
            value: "111"
          }
        ]
      }
    }
  ]
}

operator

各数据类型支持的operator见下表:

数据类型支持的操作符备注
AutoNumbereq, ne, le, ge, lt, gt, in, contains, startwith, endwith, isnull, isnotnull
CheckBoxeq, ne, isnull, isnotnull
Currencyeq, ne, le, ge, lt, gt, in, isnull, isnotnull
Dateeq, ne, le, ge, lt, gt, in, isnull, isnotnull
DateTimeeq, ne, le, ge, lt, gt, in, isnull, isnotnull
Emaileq, ne, le, ge, lt, gt, in, contains, startwith, endwith, isnull, isnotnull
Formula根据公式类型来决定支持的操作符
IDeq, ne, in, isnull, isnotnull
Lookupeq, ne, in, isnull, isnotnull
MasterDetaileq, ne, in, isnull, isnotnull
Nameeq, ne, le, ge, lt, gt, in, contains, startwith, endwith, isnull, isnotnull
Hierarchyeq, ne, in, isnull, isnotnull
Numbereq, ne, le, ge, lt, gt, in, isnull, isnotnull
Percenteq, ne, le, ge, lt, gt, in
Phoneeq, ne, le, ge, lt, gt, in, contains, startwith, endwith, isnull, isnotnull
SingleSelecteq, ne, isnull, isnotnull不支持 contains, startwith, endwith:没有实际业务意义
MultiSelecteq, ne, includes, excludes, isnull, isnotnull不支持 contains, startwith, endwith:没有实际业务意义
RollupSummarysum, min, max, count, isnull, isnotnull根据公式类型来决定支持的操作符
Texteq, ne, le, ge, lt, gt, contains, startwith, endwith, isnull, isnotnull, in
TextAreaisnull, isnotnull不支持任何操作
URLeq, ne, le, ge, lt, gt, in, contains, startwith, endwith, isnull, isnotnull
PostalCodeeq, ne, le, ge, lt, gt, in, contains, startwith, endwit, isnull, isnotnullh

特殊说明

  • in

in操作需要用数组传递value,比如:

ts
{
    value: ["hello", "hi"]
}

带条件查询记录

ts
let s = db.object('Student__CST');

let records = s.queryByCondition({
    conjunction: db.Conjunction.AND,
    conditions: [{
        field: "name",
        operator: db.Operator.eq,
        value: "hello1"
    }, {
        field: "age__CST",
        operator: db.Operator.eq,
        value: "age1"
    }]
});

console.log("name = ", records[0].name);
console.log("age__CST = ", records[0].age__CST);

带条件更新记录

ts
let s = db.object('Student__CST');

let record = {
    "name": "helloupdate",
    "age__CST": "ageupdate"
};

let count = s.updateByCondition({
    conjunction: db.Conjunction.AND,
    conditions: [{
        field: "name",
        operator: db.Operator.eq,
        value: "hello1"
    },
    {
        field: "age__CST",
        operator: db.Operator.eq,
        value: "age1"
    }
    ]
}, record);

带条件删除记录

ts
let s = db.object('Student__CST');

let count = s.deleteByCondition({
    conjunction: db.Conjunction.AND,
    conditions: [{
        field: "name",
        operator: db.Operator.eq,
        value: "test123"
    }]
});

console.log("delete count = ", count);
console.log("left count = ", s.count());

高级查询

指定查询字段集

ts
let s = db.object('student__cst');

let records = s.queryByCondition(
    {
        conjunction: db.Conjunction.AND,
        conditions: [{
            field: "name",
            operator: db.Operator.ne,
            value: "hello1"
        }]
    },

    {
        options: {
           fields: ["f1", "f2", "f3"],
        }
    });

结果排序

支持查询结果集按照指定字段的值进行升序(asc)或降序(desc)排序。

ts
let s = db.object('student__cst');

let records = s.queryByCondition(
    {
        conjunction: db.Conjunction.AND,
        conditions: [{
            field: "name",
            operator: db.Operator.ne,
            value: "hello1"
        }]
    },

    {
        options: {
            orderby: [
                {
                    field: "name",
                    order: db.Order.desc
                }
            ],
        }
    });

查询分组

支持查询结果集按照指定字段进行分组。

ts
let s = db.object('student__cst');

let records = s.queryByCondition(
    {
        conjunction: db.Conjunction.AND,
        conditions: [{
            field: "name",
            operator: db.Operator.ne,
            value: "hello1"
        }]
    },

    {
        options: {
            groupby: [
                {
                    field: "name",
                }
            ],
        }
    });

查询去重

ts
let s = db.object('student__cst');

let records = s.queryByCondition(
    {
        conjunction: db.Conjunction.AND,
        conditions: [{
            field: "name",
            operator: db.Operator.ne,
            value: "hello1"
        }]
    },

    {
        options: {
            distinct: true,
        }
    });

分页查询

支持限制查询返回的记录条数,通过skip值指定从第多少条开始,limit指定总共返回多少条记录。

在不指定skip, limit情况,默认值为skip=0, limit=5000,意味着查询返回结果集的前5000条。

limit最大值可设置为10000条,意味着该查询接口最多只能返回查询结果集的前10000条。

ts
let s = db.object('Student__CST');

let records = s.queryByCondition(
    {
        conjunction: db.Conjunction.AND,
        conditions: [{
            field: "name",
            operator: db.Operator.ne,
            value: "hello1"
        }]
    },

    {
        options: {
            skip: 100,
            limit: 100
        }
    });

聚合查询

支持常见的聚合函数:sum, max, min, avg

ts
{
    aggregate: [
      {
        alias:   "total",
        field:    "f3",
        function: db.Function.sum
      },
      {
        field:    "f3",
        function: db.Function.max
      },
      {
        field:    "f3",
        function: db.Function.min
      },
      {
        field:    "f3",
        function: db.Function.avg
      }
    ]
}

关联查询

ts
  {  
    //向上查询,可选
    parents: [  //第一级父对象
      {
        relatedField: "CarHolder__CST",  //当前对象的字段(Lookup/MasterDetail类型),据此确定父对象
        options: {
          fields: ["id", "name", "Age__CST"] //父对象的待查字段
        },
        parents: [ //(可选)第二级父对象
          {
            relatedField: "cust__CST", //父对象的字段(Lookup/MasterDetail类型),据此确定祖父对象
            options: {
              fields: ["id", "name", "Email__CST"] //祖父对象的待查字段
            }
          }
        ]
      }
    ],

    //向下查询,可选
    childs: [   //第一级子对象
      {
        relationName: "Contacts", //子对象关系名(子对象定义Lookup/MasterDetail时指定),据此确定子对象
        options: {
          fields: ["id", "name", "Age__CST", "cust__CST"] //子对象的待查字段
      },
      childs: [  //(可选)第二级子对象
        {
            relationName: "ContactCars", //孙子对象关系名
            options: {
              fields: ["id", "name", "Price__CST", "CarHolder__CST"]  //孙子对象待查字段
            }
        }
      ]
      }
    ]
  }

事务操作

在下面几种脚本的触发方式下:

  • http请求触发脚本
  • http请求触发flow, flow再调用脚本
  • http请求触发对象的触发器,触发器再调用脚本
  • 定时任务触发脚本
  • 事件消息触发脚本
  • http请求触发工作流,工作流再调用脚本
  • ...

在这些情况下,脚本执行时,是在一个公共的外部事务上下文中,请求流程执行完后:

如果请求执行成功:则提交事务。 如果请求执行失败:则回滚事务。

如果需要在脚本中控制事务,可以调用db模块的如下几个api:

  • transaction封装独立事务

transaction可以将一系列数据库操作封装在一个独立的事务中进行,要么全成功,要么全失败。

且成功与失败不影响外部的操作,外部的操作的成功失败也不影响transaction的结果。

ts
import { object, transaction } from 'db';

@useObject(['student__cst'])
class Demo {
    test(): void {
        let student = object('student__cst');

        // 进行一些数据库操作
        // ...

        let op = function(): void {
            // 进行另外一些数据库操作
        };

        // op的里面数据库操作是独立事务,与op外面的事务操作互相不影响。
        transaction(op)
    }
}
  • commit提交当前事务
ts
import { object, commit } from 'db';

@useObject(['student__cst'])
class Demo {
    test(): void {
        let student = object('student__cst');

        // ...进行一些数据库操作

        // 提交当前事务
        commit();
    }
}
  • rollback回滚当前事务
ts
import { object, rollback } from 'db';

@useObject(['student__cst'])
class Demo {
    test(): void {
        let student = object('student__cst');

        // ...进行一些数据库操作

        // 回滚当前事务
        rollback();
    }
}

commit, rollback操作的事务可以是触发脚本的公共外部事务,也可以是transaction触发的独立事务,取决于它们执行时候的事务上下文。

系统对象操作

使用db.setup支持系统对象的CRUD操作。

setup针对系统对象,object针对标准对象,定制对象。

两者的核心区别:系统对象为了性能,大部分都会缓存在进程私有缓存中,而标准对象,定制对象不会缓存。

如果是依据id的单独查询一条记录,setup直接从缓存查询结果,object需要从数据库查询结果,setup会快很多。

批量删除,更新时,setup反而性能很差, setup对象删除,更新记录时,需要作很多特殊处理,所以不能直接从数据库层面批量删除。

setup.updateByConditionsetup.deleteByCondition的实现方式是:

先调用object.queryByCondition从数据库查询出所有的满足条件的id, 然后依据id一个一个的去delete, update。