{"id":27852028,"url":"https://github.com/yongoe1024/RdbPlus","last_synced_at":"2025-05-04T03:01:58.288Z","repository":{"id":258127615,"uuid":"873132064","full_name":"yongoe1024/RdbPlus","owner":"yongoe1024","description":"一个sqlite的增强工具，无需编写sql代码，一行搞定增删改查，为简化开发、提高效率而生","archived":false,"fork":false,"pushed_at":"2025-03-19T05:22:33.000Z","size":166,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-19T06:25:56.079Z","etag":null,"topics":["arkts","harmonyos","sqlite","util"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yongoe1024.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-15T16:49:21.000Z","updated_at":"2025-03-19T05:22:37.000Z","dependencies_parsed_at":"2025-03-19T12:31:49.316Z","dependency_job_id":null,"html_url":"https://github.com/yongoe1024/RdbPlus","commit_stats":null,"previous_names":["yongoe1024/rdbplus"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yongoe1024%2FRdbPlus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yongoe1024%2FRdbPlus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yongoe1024%2FRdbPlus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yongoe1024%2FRdbPlus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yongoe1024","download_url":"https://codeload.github.com/yongoe1024/RdbPlus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252280890,"owners_count":21723055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arkts","harmonyos","sqlite","util"],"created_at":"2025-05-04T03:01:57.035Z","updated_at":"2025-05-04T03:01:58.276Z","avatar_url":"https://github.com/yongoe1024.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# rdb-plus 使用文档\n\n## 简介\n\n这是一个sqlite的增强工具，无需编写sql代码，通过继承BaseMapper类，一行搞定增删改查，为简化开发、提高效率而生。（类似Mybatis-plus）\n\n## 版本说明\n### 2.0.1\n1. 优化生成的sql\n\n### 2.0.0\n1. 修改命名 wapper-\u003ewrapper\n2. 使用API 5.0.3(15)\n\n## 下载安装\n\n`ohpm i rdbplus`  \nOpenHarmony ohpm\n环境配置等更多内容，请参考[如何安装 OpenHarmony ohpm 包](https://ohpm.openharmony.cn/#/cn/help/downloadandinstall)\n\n## 使用案例\n\nhttps://gitee.com/yongoe/RdbPlus/tree/main/entry/src/main/ets\n\nhttps://github.com/yongoe1024/RdbPlus/tree/main/entry/src/main/ets\n\n## 功能介绍\n\n| 函数名            | 介绍                    |\n|----------------|-----------------------|\n| count          | 查询符合条件的记录总数           |\n| getList        | 查询符合条件的记录             |\n| getPage        | 分页查询符合条件的记录           |\n| getObject      | 查询符合条件的记录，返回对象数组      |\n| getObjectBySql | 输入SQL查询符合条件的记录，返回对象数组 |\n| getById        | 根据 ID 查询              |\n| insert         | 插入一条记录                |\n| updateById     | 根据 ID 更新数据            |\n| update         | 更新符合条件的记录             |\n| deleteById     | 根据 ID 删除              |\n| delete         | 删除符合条件的记录             |\n\n## 引入教程\n\n1. 首先引入ohpm依赖：`ohpm i rdbplus`\n2. 创建一个数据库表对应的实体类，推荐ts格式，比如`Employee.ts`\n3. 创建一个mapper类，比如 `EmpMapper.ets`\n4. 直接在页面中`new出EmpMapper`，就可以调用增删改查的方法，无需编写SQL代码\n\n### 第一步：创建实体类\n\n推荐在`src/main/ets/entity`路径中，创建ts文件`Employee.ts`(可以不写默认值)  \n！！！字段名要与数据库字段一一对应，完全一致！！！\n\n```typescript\nexport class Employee {\n   id: number\n   name: string\n\n   constructor() {\n   }\n}\n```\n\n### 第二步：创建Mapper类\n\n推荐在`src/main/ets/mapper`路径中，创建ets文件`EmpMapper.ets`\n\n1. 首先创建`EmpMapper类`，然后继承`BaseMapper`，传入泛型`Employee`\n2. 创建构造函数，调用super方法。  \n   第一个参数是`一个对象`，包含`表名`、`主键字段名`两项内容  \n   第二个参数是`回调函数`:`(res: relationalStore.ResultSet)=\u003e T`，返回一个泛型对象，本意是为了从ResultSet中得到一行数据  \n   第三个参数是`可选值`，传入`relationalStore.StoreConfig`，比如数据库名、安全级别等。默认库名`demo.db`\n\n```typescript\nimport { Employee } from '../entity/Employee'\nimport { relationalStore } from '@kit.ArkData'\nimport { BaseMapper } from 'rdbplus'\n\nconst getRow = (res: relationalStore.ResultSet) =\u003e {\n   const emp = new Employee()\n   emp.id = res.getLong(res.getColumnIndex('id'))\n   emp.name = res.getString(res.getColumnIndex('name'))\n   return emp\n}\n\nexport class EmpMapper extends BaseMapper\u003cEmployee\u003e {\n   constructor() {\n      super(\n         { tableName: 't_emp', primaryKey: 'id' },\n         getRow,\n         // 可选参数\n         { name: 'demo.db', securityLevel: relationalStore.SecurityLevel.S1 }\n      )\n   }\n}\n```\n\n### 第三步：页面中调用\n\n```\nimport { EmpMapper } from '../mapper/EmpMapper'\n\n@Entry\n@Component\nstruct Index {\n  empMapper = new EmpMapper()\n\n  build()\n  {\n    Button('查询全部数据').onClick(() =\u003e {\n       // 查询全部\n       let list:1 Employee[]  = await this.empMapper.getList(new Wrapper())\n       // 条件查询\n       let list2: Employee[]  = await this.empMapper.getList(new Wrapper().eq('name', '李四'))\n       // 统计总数\n       const num:number = await this.empMapper.count(new Wrapper())\n    })\n  }\n}\n```\n\n### 建表、连接查询等复杂SQl，采用手写SQL方法\n\n1. 调用`EmpMapper`对象中的`getConnection()`方法，得到一个`Connection`对象\n2. `Connection`有两个函数：`execDML`、`execDQL`  \n   `execDML`是数据操纵函数，执行创建、添加、修改 语句  \n   `execDQL`是数据查询函数，执行查询语句\n\n#### 示例\n\n在`EmpMapper.ets`中，添加一个函数`createTable`，用来创建表\n\n```javascript\nexport class EmpMapper extends BaseMapper\u003cEmployee\u003e {\n   /**\n    ...其余省略\n    ...\n    */\n\n\n   async createTable() {\n      const db = await this.getConnection()\n      await db.execDML(`DROP TABLE IF EXISTS t_emp  ;`)\n      await db.execDML(\n         `create table if not exists \"t_emp\" (\n             id integer primary key autoincrement,\n             name varchar(20)\n        )`)\n      await db.execDML(`INSERT INTO t_emp (id,name)  VALUES (null, ? );`, ['111'])\n      await db.close()\n   }\n}\n```\n\n## API介绍\n\n以下代码示例的前提条件是：已经实现了一个mapper类，例如`EmpMapper`\n\n### count\n\n查询符合条件的记录总数  \n返回值： 符合条件的记录总数。\n\n| 入参             | 说明   |\n|----------------|------|\n| wrapper: Wrapper | 查询条件 |\n\n| 返回值    | 说明  |\n|--------|-----|\n| number | 统计值 |\n\n```typescript\n// 统计总数\nconst num:number = await this.empMapper.count(new Wrapper())\n```\n\n### getObject\n\n查询符合条件的记录  \n返回值： 查询结果，一个对象类型的数组\n\n| 入参             | 说明   |\n|----------------|------|\n| wrapper: Wrapper | 搜索条件 |\n\n| 返回值         | 说明   |\n|-------------|------|\n| AnyObject[] | 对象数组 |\n\n```typescript\n// 查询name等于111的数据\nconst objList = await this.empMapper.getObject(new Wrapper().eq('name', '111'))\n```\n\n### getObjectBySql\n\n通过SQL，查询符合条件的记录  \n返回值： 查询结果，一个对象类型的数组\n\n| 入参                                  | 说明    |\n|-------------------------------------|-------|\n| sql: string                         | sql语句 |\n| params: relationalStore.ValueType[] | 占位符参数 |\n\n| 返回值         | 说明   |\n|-------------|------|\n| AnyObject[] | 对象数组 |\n\n```typescript\n// 统计行数\nconst res = await this.mapper.getObjectBySql('select count(*) from t_emp', [])\n```\n\n### getList\n\n查询符合条件的记录  \n返回值： 查询结果，泛型T的数组\n\n| 入参             | 说明   |\n|----------------|------|\n| wrapper: Wrapper | 搜索条件 |\n\n| 返回值 | 说明     |\n|-----|--------|\n| T[] | 泛型T的数组 |\n\n```typescript\n// 查询name等于111的数据，返回数组\nconst list = await this.empMapper.getList(new Wrapper().eq('name', '111'))\n```\n\n### getPage\n\n分页查询符合条件的记录  \n返回值：分页查询结果，包含记录列表和总记录数\n\n| 入参             | 说明   |\n|----------------|------|\n| wrapper: Wrapper | 搜索条件 |\n\n| 返回值     | 说明     |\n|---------|--------|\n| Page\u003cT\u003e | 分页查询结果 |\n\n| Page    | 说明   |\n|---------|------|\n| total   | 总数   |\n| current | 当前页  |\n| size    | 每页数量 |\n| record  | 结果集  |\n\n```typescript\n// 查询第一页的数据，返回Page对象\nconst page = await this.empMapper.getPage(1, 10)\n// 总数\nconst total = page.total\n// 当前页\nconst current = page.current\n// 每页条数\nconst size = page.size\n// 结果集\nconst record = page.record\n```\n\n### getById\n\n根据主键ID查询  \n返回值： 查询结果，可能是undefined或泛型T的对象\n\n| 入参            | 说明  |\n|---------------|-----|\n| id: ValueType | 主键值 |\n\n| 返回值            | 说明                    |\n|----------------|-----------------------|\n| T 或  undefined | 存在返回结果，不存在返回undefined |\n\n```typescript\n// 查询主键ID等于14的数据\nthis.empMapper.getById(14)\n```\n\n### insert\n\n插入一条记录\n返回值：void，失败则抛出异常\n注：若插入的某个字段为空，可以设置为 `undefined或null`\n\n| 入参     | 说明       |\n|--------|----------|\n| obj: T | 一个泛型T的对象 |\n\n| 返回值  | 说明       |\n|------|----------|\n| void | 执行失败抛出异常 |\n\n```typescript\nconst emp = new Employee()\nemp.name = '新添加的'\n// 如果是自增，id可以不用赋值\nthis.empMapper.insert(emp)\n```\n\n### updateById\n\n根据 ID ，更新符合条件的记录\n返回值：void，失败则抛出异常\n注：不想更新的字段必须设置为`undefined`，其他值包括null，都会更新到数据库\n\n| 入参     | 说明              |\n|--------|-----------------|\n| obj: T | 一个泛型T的对象，主键不能为空 |\n\n| 返回值  | 说明       |\n|------|----------|\n| void | 执行失败抛出异常 |\n\n```typescript\nconst emp = new Employee()\nemp.id = 20\nemp.name = '张三'\n// 根据主键id修改\nthis.empMapper.updateById(emp)\n```\n\n### update\n\n通过指定条件更新数据  \n返回值：void，失败则抛出异常\n\n| 入参             | 说明   |\n|----------------|------|\n| wrapper: Wrapper | 更新条件 |\n\n| 返回值  | 说明       |\n|------|----------|\n| void | 执行失败抛出异常 |\n\n```typescript\n// 将name等于张三的数据，改为name等于李四\nthis.empMapper.update(new Wrapper().set('name', '李四').eq('name', '张三'))\n```\n\n### deleteById\n\n根据 ID ，删除数据  \n返回值：void，失败则抛出异常\n\n| 入参            | 说明  |\n|---------------|-----|\n| id: ValueType | 主键值 |\n\n| 返回值  | 说明       |\n|------|----------|\n| void | 执行失败抛出异常 |\n\n```typescript\n// 删除主键ID等于5的数据\nthis.empMapper.deleteById(5)\n```\n\n### delete\n\n通过指定条件删除数据  \n返回值：void，失败则抛出异常\n\n| 入参             | 说明   |\n|----------------|------|\n| wrapper: Wrapper | 删除条件 |\n\n| 返回值  | 说明       |\n|------|----------|\n| void | 执行失败抛出异常 |\n\n```typescript\n// 删除name等于111的数据\nthis.empMapper.delete(new Wrapper().eq('name', '111'))\n```\n\n### getConnection\n\n获取一个数据库的连接对象`Connection`，可以直接进行SQL语句的调用  \n参考上面的`建表、连接查询等复杂SQl，采用手写SQL方法`\n\n#### init\n\n获取一个新的数据库连接\n\n| 入参                                  | 说明    |\n|-------------------------------------|-------|\n| config: relationalStore.StoreConfig | 数据库配置 |\n\n| 返回值        | 说明           |\n|------------|--------------|\n| Connection | Connection对象 |\n\n#### execDML\n\n`execDML`是数据操纵函数（DML），执行创建、添加、修改语句\n\n| 入参          | 说明                                  |\n|-------------|-------------------------------------|\n| sql: string | SQL语句                               |\n| params      | 数组，SQL语句中参数的值。该值与sql参数语句中的`？`占位符相对应 |\n\n| 返回值  | 说明       |\n|------|----------|\n| void | 执行失败抛出异常 |\n\n#### execDQL\n\n`execDQL`是数据查询函数，执行查询语句\n\n| 入参          | 说明                                  |\n|-------------|-------------------------------------|\n| sql: string | SQL语句                               |\n| params      | 数组，SQL语句中参数的值。该值与sql参数语句中的`？`占位符相对应 |\n\n| 返回值                       | 说明          |\n|---------------------------|-------------|\n| relationalStore.ResultSet | 返回ResultSet |\n\n#### beginTransaction\n\n开启事务\n\n#### commit\n\n提交事务\n\n#### rollBack\n\n回滚事务\n\n#### close\n\n关闭当前的Connection连接\n\n## 条件构造器介绍\n\n### set\n\n在update语句中，用于指定要修改的列及其新值\n\n```typescript\n// 更新`name`等于`张三`的数据，将`name`值更改为`李四`\nnew Wrapper()\n   .set('name', '李四')\n   .eq('name', '张三')\n```\n\n### eq\n\n等于\n\n```typescript\n// 查询`name`等于`王二`，并且`age`为`18`的数据\nnew Wrapper().eq('name', '王二').eq('age', 18)\n```\n\n### notEq\n\n不等于\n\n```typescript\n// 查询`name`不等于`王二`的数据\nnew Wrapper().notEq('name', '王二')\n```\n\n### lt\n\n小于\n\n```typescript\n// 查询`age`小于`50`的数据\nnew Wrapper().lt('age', 50)\n```\n\n### lte\n\n小于等于\n\n```typescript\n// 查询`age`小于等于`50`的数据\nnew Wrapper().lte('age', 50)\n```\n\n### gt\n\n大于\n\n```typescript\n// 查询`age`大于`50`的数据\nnew Wrapper().gt('age', 50)\n```\n\n### gte\n\n大于等于\n\n```typescript\n// 查询`age`大于等于`50`的数据\nnew Wrapper().gte('age', 50)\n```\n\n### in\n\n设置单个字段的值，在给定的集合中\n\n```typescript\n// 查询`age`在`18、19、20`之中的数据\nnew Wrapper().in('age', [18, 19, 20])\n```\n\n### notIn\n\n设置单个字段的值，不在给定的集合中\n\n```typescript\n// 查询`age`不在`18、19、20`之中的数据\nnew Wrapper().notIn('age', [18, 19, 20])\n```\n\n### between\n\n设置单个字段的 BETWEEN 条件\n\n```typescript\n// 查询 age 在 18-60之间的数据\nnew Wrapper().between('age', 18, 60)\n\n```\n\n### notBetween\n\n设置单个字段的 NOT BETWEEN 条件\n\n```typescript\n// 查询 age 不在 18-60之间的数据\nnew Wrapper().notBetween('age', 18, 60)\n\n```\n\n### like\n\n单个字段的模糊匹配条件\n\n```typescript\n// 匹配 `name` 的第一个字是`张`的数据\nnew Wrapper().like('name', '张%')\n```\n\n### notLike\n\n单个字段的非模糊匹配条件\n\n```typescript\n// 匹配 `name` 的第一个字，不是`张`的数据\nnew Wrapper().notLike('name', '张%')\n```\n\n### isNull\n\n单个字段为null\n\n```typescript\n// 查询 `title` 等于null的数据\nnew Wrapper().isNull('title')\n```\n\n### isNotNull\n\n单个字段不为null\n\n```typescript\n// 查询 `title` 不等于null的数据\nnew Wrapper().isNotNull('title')\n```\n\n### orderByAsc\n\n将查询结果根据某字段进行升序排序，可以多次调用，按顺序拼接order内容\n\n```typescript\n// 将查询结果根据id升序排列\nnew Wrapper().orderByAsc('id')\n```\n\n### orderByDesc\n\n将查询结果根据某字段进行降序排序，可以多次调用，按顺序拼接order内容\n\n```typescript\n// 将查询结果根据id降序排列\nnew Wrapper().orderByDesc('id')\n```\n\n### groupBy\n\n设置查询结果的分组条件。通过指定一个或多个字段\n\n```typescript\n// 依次根据id、name进行分组\nnew Wrapper().groupBy('id', 'name')\n```\n\n生成的sql\n\n```\nSELECT * FROM user GROUP BY id, name\n```\n\n### having\n\n设置 HAVING 子句，过滤分组后的结果。通常与 GROUP BY 一起使用，用于对分组后的数据进行条件筛选\n\n```typescript\n// 根据name分组，过滤分组条件是name不等于张三\nnew Wrapper().groupBy('name').having(`name != '张三'`)\n```\n\n生成的sql\n\n```\nSELECT * FROM user GROUP BY name HAVING name != '张三'\n```\n\n### or\n\n用于在查询条件中添加 OR 逻辑。通过调用 or 方法，可以改变后续查询条件的连接方式，从默认的 AND 连接变为 OR 连接\n\n```typescript\nnew Wrapper().eq('name', '111')\n   .or(new Wrapper().eq('name', '222').eq('age', 18))\n```\n\n生成SQL为\n\n```\nname = '111' or ( name = '222' and age=18 )\n```\n\n### and\n\n用于在查询条件中添加 AND 逻辑。通过调用 and 方法，可以创建 AND 嵌套条件，即在一个 AND 逻辑块中包含多个查询条件\n\n```typescript\nnew Wrapper()\n   .eq('name', '111')\n   .and(new Wrapper().notEq('name', '222'))\n```\n\n生成SQL为\n\n```\nname = '111' and ( name != '222' )\n```\n\n### select\n\n默认查询为： `select *`\n调用select函数，将默认的 `*` 更改为指定内容  \n注：若添加了额外内容，例如聚合函数、字段别名，建议使用`getObject`方法，将结果从对象中取出（getObjectBySql也可以）\n\n```typescript\n//指定字段\nnew Wrapper().select('id,name,age')\n//使用函数\nnew Wrapper().select('count(*),sum(age)')\n//字段别名\nnew Wrapper().select('age as nianling')\n```\n\n## 其他功能\n\n### 多数据源\n\n参考如下示例\n\n```typescript\nimport { Employee } from '../entity/Employee'\nimport { relationalStore } from '@kit.ArkData'\nimport { BaseMapper, MapperParam } from 'rdbplus'\n\n// 实现一个 getRow\nconst getRow = (res: relationalStore.ResultSet) =\u003e {\n   const emp = new Employee()\n   emp.id = res.getLong(res.getColumnIndex('id'))\n   emp.name = res.getString(res.getColumnIndex('name'))\n   return emp\n}\n\nexport class EmpMapper extends BaseMapper\u003cEmployee\u003e {\n   // 构造函数，仅接收参数，将参数传给super\n   private constructor(config: relationalStore.StoreConfig) {\n      super({ tableName: 't_emp', primaryKey: 'id' }, getRow, config)\n   }\n\n   // 手动 new出EmpMapper\n   // 数据库1\n   static getDemo1DB(): EmpMapper {\n      return new EmpMapper(\n         {\n            name: 'Demo1DB.db',\n            securityLevel: relationalStore.SecurityLevel.S1\n         }\n      )\n   }\n\n   // 数据库2\n   static getDemo2DB(): EmpMapper {\n      return new EmpMapper(\n         {\n            name: 'Demo2DB.db',\n            securityLevel: relationalStore.SecurityLevel.S1\n         }\n      )\n   }\n}\n```\n\n### 事务\n\n参考如下代码\n\n```\nimport { Employee } from '../entity/Employee'\nimport { EmpMapper } from '../mapper/EmpMapper'\n\n@Entry\n@Component\nstruct Index {\n  empMapper = new EmpMapper()\n\n  build() {\n\n    Row() {\n\n      Button('事务成功').onClick(async (event: ClickEvent) =\u003e {\n      \n        // 获取一个db连接\n        const db = await this.empMapper.getConnection()\n        try {\n          //开启事务\n          db.beginTransaction()\n          const emp = new Employee()\n          emp.name = '事务'\n          // 将 db 传进去，保持所有操作在同一连接上\n          this.empMapper.insert(emp, db)\n          //提交事务\n          db.commit()\n        } catch (e) {\n          // 回滚\n          db.rollBack()\n        } finally {\n          // 关闭连接\n          db.close()\n        }\n        \n      })\n\n      Button('事务失败').onClick(async (event: ClickEvent) =\u003e {\n      \n        // 获取一个db连接\n        const db = await this.empMapper.getConnection()\n        try {\n          db.beginTransaction()\n          const emp = new Employee()\n          emp.name = '事务失败'\n          // 将 db 传进去，保持所有操作在同一连接上\n          this.empMapper.insert(emp, db)\n          // 抛出异常，回滚事务\n          throw new Error()\n          //提交事务\n          db.commit()\n        } catch (e) {\n          // 回滚\n          db.rollBack()\n        } finally {\n          // 关闭连接\n          db.close()\n        }\n        \n      })\n    }\n  }\n}\n```\n\n## 贡献代码\n\n使用过程中发现任何问题都可以提 `Issue`，也欢迎您发 `PR`\n\nhttps://gitee.com/yongoe/RdbPlus\n\nhttps://github.com/yongoe1024/RdbPlus `(以github为主)`\n\n## 开源协议\n\n本项目基于 [MIT License](https://mit-license.org)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyongoe1024%2FRdbPlus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyongoe1024%2FRdbPlus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyongoe1024%2FRdbPlus/lists"}