跳到主要内容

数据库

适用环境SaaS
私有部署

要求

ONES
v3.6.0+

概述

有时候插件希望可以持久化自己的数据。插件数据库能力可以让每个插件拥有自己独立的数据库,并提供访问和操作它的方法。

备注

该能力兼容 mysql 5.7.x 版本 SQL 语法

设计和使用规范

  • 不创建没有主键的表;
  • 库名、表名和字段名不使用驼峰形式;
  • 库名、表名、字段名中和索引名不出现 - * \ / # @ 等特殊字符;
  • 不向字符类型的字段插入 []byte 数据;
  • 不使用 json 类型字段;
  • 不使用 NULL 值做唯一键约束;
  • 使用 varchar 代替 char
  • 使用 INSERT 需显式写出要插入的列。比如 insert into values (1, 2); 应该写为 insert into (col1, col2) values (1, 2);
  • 使用占位符?的方式插入和更新数据。

使用

数据库能力使用:

第一步:安装依赖

进入插件工程的/backend目录,执行以下命令进行依赖安装:

npm i @ones-op/node-database

第二步:编写数据库 SQL 文件

创建插件数据库,需要先将数据库中所有表的表创建语句预先书写在 SQL 文件中并放到 workspace 目录下。

示例 SQL 文件

警告

语句中表名称需要使用小写字母,允许使用下划线_, 不允许使用-, 同时必需使用 {{ }} 将表名称括起来。

workspace/plugin.sql
CREATE TABLE IF NOT EXISTS `{{email_id_map}}`  (
`email` varchar(128) CHARACTER SET latin1 NOT NULL COMMENT '邮箱',
`id_number` varchar(128) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '工号',
PRIMARY KEY (`email`)
) ENGINE = InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;

第三步:数据库初始化

调用importSQL 函数创建数据库表,推荐在插件的 Install 函数中进行表的初始化。

示例用法

backend/src/index.ts
import { importSQL } from '@ones-op/node-database'

// 生命周期钩子 安装插件
export async function Install() {
// 初始化数据库
return importSQL('plugin.sql')
}

第四步:数据库操作

  • select

    查询数据使用 select 方法,方法接收 SQL 语句,并返回查询的结果。SQL 执行失败时会 throw error

    SQL 支持带占位符填充语句。占位符使用问号?,填充值使用可变参数,带占位符 SQL 语句支持版本:ONES v6.8.0+/v6.1.96+,@ones-op/node-database@0.70.1+

    示例用法

    import { select } from '@ones-op/node-database'
    import { Logger } from '@ones-op/node-logger'

    try {
    const result1 = await select('select * from email_id_map limit 10;')
    // 带占位符 SQL 语句
    const result2 = await select('select * from email_id_map where id_number = ?;', '001'))
    } catch (error) {
    Logger.error('ERROR: ', error)
    }
  • exec

    执行 SQL 语句可使用 exec 方法,该方法接收 SQL 操作类型和语句,不会返回结果。SQL 执行失败时会 throw error

    1. 目前支持的operate操作类型有:insert, update, delete, create, alter, drop
    2. 执行 SQL 的格式支持原始SQL语句和带占位符填充语句。占位符使用问号?,填充值使用可变参数,带占位符 SQL 语句支持版本:ONES v6.2.19+/v6.1.86+,@ones-op/node-database@0.46.5+

    示例用法

    import { exec } from '@ones-op/node-database'
    import { Logger } from '@ones-op/node-logger'

    try {
    // 执行原始 SQL 语句
    await exec(
    'insert',
    `INSERT INTO email_id_map(email,id_number) VALUES ("plugin1@ones.com", "001");`,
    )
    // 执行带占位符 SQL 语句
    await exec(
    'insert',
    `INSERT INTO email_id_map(email,id_number) VALUES (?,?);`,
    'plugin2@ones.com',
    '002',
    )
    const args = ['plugin3@ones.com', '003']
    await exec('insert', `INSERT INTO email_id_map(email,id_number) VALUES (?,?);`, ...args)
    } catch (error) {
    Logger.error('ERROR: ', error)
    }
  • count

    统计数量使用 count 方法,方法接收 SQL 语句,并返回统计的结果。SQL 执行失败时会 throw error

    1. count 函数仅支持统计单列数量的 SQL 语句;
    2. SQL 支持带占位符填充语句。占位符使用问号?,填充值使用可变参数,带占位符 SQL 语句支持版本:ONES v6.8.0+/v6.1.96+,@ones-op/node-database@0.70.1+

    示例用法

    import { count } from '@ones-op/node-database'
    import { Logger } from '@ones-op/node-logger'

    try {
    const cnt1 = await count('select count(*) from email_id_map;')
    // 带占位符 SQL 语句
    const cnt2 = await count('select count(*) from email_id_map where id_number = ?;', '001'))
    } catch (error) {
    Logger.error('ERROR: ', error)
    }

本地开发及配置

在本地开发时,为了方便开发和调试,也支持让数据库操作作用在本地。本地调试不影响能力的使用的方法,不需要修改代码,只要修改本地数据库相关配置。 修改config/local.yaml中的配置,再重新执行npx op invoke run命令重启插件

示例配置

config/local.yaml
  mysql_in_local: true # true 为使用您的本地数据库, false 为使用 ONES 系统内置数据库
  mysql_user_name: 'root'
  mysql_user_password: 'root123'
  mysql_database_name: 'test'
  mysql_host: '127.0.0.1'
  mysql_port: '3306'

相关 SDK

具体参数释义请参考:@ones-op/node-database

常见问题

插件升级时数据库如何迁移?

在插件的升级时,会调用生命周期方法中的升级方法,团队级别的插件为Upgrade,组织级别的插件为OrgUpgrade。插件升级前后数据库不变,可在该方法中实现迁移。