ArkTS,关系类数据库的封装

前言

这个类的封装是我在做一个手机助手的项目时遇到的一个封装,在这个项目里有需要创建三个表去存储数据,达到数据持久化的效果(因为存储的数据大于8k所以使用数据库的方法进行存储)

封装方法讲解

在封装这个类的时候,一共是有两个方法,一个是用枚举值的形式去判断表名来达到建立不同的表(枚举值判断),一个是先封装一个基础的类然后将不同的地方提取出来,用继承类的方法去封装这个类(泛型类方法)。
两个方法都可以实现我所需要的效果,但是第一种方法对于使用的局限性是比较大,在调用这个方法时需要至少传入一个枚举值,从而起到判断的作用,而且因为是三个表,每个表所对应的数据类型是不一样的,当我们要传入或者返回一个相应的值的时候,往往需要用断言的方式去进行。而第二个方法就没有这方面的困扰,你不需要用所谓的枚举去进行判断,也不需要对返回值进行断言,泛型类的方法主要是通过一个通用的不需要更改的部分先进行封装,然后用继承的方式去封装不同的地方。

数据持久化及数据库API分析

应用数据持久化

应用数据持久化,是指应用将内存中的数据通过文件或数据库的形式保存到设备上。
HarmonyOS 标准系统支持典型的存储数据形态,包括用户首选项、键值型数据库、关系型数据库。

数据库级别概念

关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。不支持Worker线程。
ArkTS侧支持的基本数据类型:number、string、二进制类型数据、boolean。为保证插入并读取数据成功,建议一条数据不要超过2M。超出该大小,插入成功,读取失败。
该模块提供以下关系型数据库相关的常用功能:

  • RdbPredicates: 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
  • RdbStore:提供管理关系数据库(RDB)方法的接口。
  • ResultSet:提供用户调用关系型数据库查询接口之后返回的结果集合

接口说明

以下是关系型数据库持久化功能的相关接口,大部分为异步接口。

异步接口均有 callback 和 Promise 两种返回形式,更多接口及使用方式请见关系型数据库

接口名称描述
getRdbStore获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作。
executeSql执行包含指定参数但不返回值的SQL语句。
insert向目标表中插入一行数据。
update根据RdbPredicates的指定实例对象更新数据库中的数据。
delete根据RdbPredicates的指定实例对象从数据库中删除数据。
query根据指定条件查询数据库中的数据。
deleteRdbStore删除数据库。

开始封装

枚举值判断法

准备封装

封装前的准备工作,定义一些在封装中需要用到的常量、变量等

import { relationalStore, ValuesBucket } from '@kit.ArkData'

//笔记文件关键信息
export interface PrivacyNoteDBInfo extends ValuesBucket {
  id: number | null,
  title: string,
  content: string,
  date_added: number,
}

// 隐私录音的字段
export interface PrivacyRecorderDBInfo extends ValuesBucket {
  id: number | null // 新增时 id 为 null ,自动生成自增 id
  filePath: string
  title: string
  date_added: number
  duration: number
}

// 图片和视频文件关键信息。(PhotoKeys)
export interface PrivacyPhotoDBInfo extends ValuesBucket {
  id: number | null // 新增时 id 为 null ,自动生成自增 id
  mediaUri: string // 文件uri
  privacyUri: string // 沙箱文件uri
  media_type: number // 媒体文件类型
  date_added: number // 添加日期
}

//隐私类型枚举
export enum secret {
  NOTE,
  RECORDER,
  PHOTO
}

class PrivacyDB {
  // SQL 语法:(SQL语法的数据类型关键词不一样,可通过AI生成SQL语句)
  // 解释说明:
  //   CREATE TABLE IF NOT EXISTS     如果表不存在才创建新的表
  //   INTEGER -> number              INTEGER 整数型   FLOAT 浮点数
  //   PRIMARY KEY                    主键(唯一标识)
  //   AUTOINCREMENT                  自增
  //   TEXT -> string                 字符串型
  //   NOT NULL                       不允许空
  private privacy: string = ''//表名
  //隐私笔记初始化数据库
  private noteContent: string = `CREATE TABLE IF NOT EXISTS PRIVACY_NOTE (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        content TEXT NOT NULL,
        date_added INTEGER NOT NULL
      )`
  //隐私录音初始化数据库
  private recorderContent: string = `CREATE TABLE IF NOT EXISTS PRIVACY_RECORDER (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        filePath TEXT,
        title TEXT,
        date_added INTEGER,
        duration INTEGER
      )`
  //隐私相册初始化数据库
  private photoContent: string = `CREATE TABLE IF NOT EXISTS PRIVACY_PHOTO (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        mediaUri TEXT,
        privacyUri TEXT,
        media_type INTEGER,
        date_added INTEGER
      )`
  // 操作数据库的管理对象
  private store: relationalStore.RdbStore | null = null
  }
判断表名方法封装
// 判断表名
 getPrivacy(ilk: secret) {
  let privacy: string = ''
  if (ilk === secret.NOTE) {
    privacy = 'PRIVACY_NOTE'
  }
  if (ilk === secret.RECORDER) {
    privacy = 'PRIVACY_RECORDER'
  }
  if (ilk === secret.PHOTO) {
    privacy = 'PRIVACY_PHOTO'
  }
  return privacy
}
初始化数据库
//初始化数据库
async getStoreInstance(ilk: secret) {
  try {
    //当 store 有值时,直接返回 store 的值
    if (this.store) {
      return this.store
    }
    // 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)
    this.store = await relationalStore.getRdbStore(getContext(), {
      name: 'aaa.db',
      securityLevel: relationalStore.SecurityLevel.S1
    })
    // 执行创建表的语句 execute 执行
    this.store.executeSql(this.noteContent)
    this.store.executeSql(this.photoContent)
    this.store.executeSql(this.recorderContent)
    //返回 store 的值
    return this.store
  } catch (err) {
    return Promise.reject('initDB error')
  }
}
新增数据

新增数据不需要传入id,当你传入的id为 null 时,数据库的API会自动根据上一个id进行自增(如果没有上一个,则为1)

// 新增数据库
async insert(item: PrivacyNoteDBInfo | PrivacyRecorderDBInfo | PrivacyPhotoDBInfo, ilk: secret) {
  //判断是哪个表
  this.privacy = await this.getPrivacy(ilk)
  // 获取相应的表
  const store = await this.getStoreInstance(ilk)
  // 将数据添加入表,并赋值给 rowId
  const rowId = await store.insert(this.privacy, item)
  // 返回 rowId
  return rowId > -1 ? Promise.resolve(rowId) : Promise.reject('insert error')
}

这里补充一个批量新增数据,这个方法其实与新增是一样的,只是传入值有所不同

// 批量新增数据库
async batchInsert(items: PrivacyNoteDBInfo[] | PrivacyRecorderDBInfo[] | PrivacyPhotoDBInfo[], ilk: secret) {
  this.privacy = await this.getPrivacy(ilk)
  const store = await this.getStoreInstance(ilk)
  const rowId = await store.batchInsert(this.privacy, items)
  return rowId ? Promise.resolve(rowId) : Promise.reject('insert error')
}
查询
查询表内数据总数
//查询数据库总数
async queryCount(ilk: secret) {
  //判断是哪个表
  this.privacy = await this.getPrivacy(ilk)
  // 获取相应的表
  const store = await this.getStoreInstance(ilk)
  const predicates = new relationalStore.RdbPredicates(this.privacy)
  const resultSet = await store.query(predicates)
  return resultSet.rowCount > 0 ? resultSet.rowCount : 0
}
查询数据
//查询数据
async query(ilk: secret, id?: number) {
  this.privacy = await this.getPrivacy(ilk)
  const store = await this.getStoreInstance(ilk)
  const predicates = new relationalStore.RdbPredicates(this.privacy)
  // 倒序排列
  predicates.orderByDesc('id')
  // 如果有 id,添加 id 作为查询条件
  if (id) {
    predicates.equalTo('id', id)
  }
  const resultSet = await store.query(predicates)
  const note: PrivacyNoteDBInfo[] = []
  const recorder: PrivacyRecorderDBInfo[] = []
  const photo: PrivacyPhotoDBInfo[] = []
  while (resultSet.goToNextRow()) {
    // 移动指针的时候提取数据,按列下标提取数据
    if (ilk === secret.NOTE) {
      note.push(
        {
          id: resultSet.getLong(0),
          title: resultSet.getString(1),
          content: resultSet.getString(2),
          date_added: resultSet.getLong(3),
        }
      )
    }
    if (ilk === secret.RECORDER) {
      recorder.push(
        {
          id: resultSet.getLong(0),
          filePath: resultSet.getString(1),
          title: resultSet.getString(2),
          date_added: resultSet.getLong(3),
          duration: resultSet.getLong(4),
        }
      )
    }
    if (ilk === secret.PHOTO) {
      photo.push(
        {
          id: resultSet.getLong(0),
          mediaUri: resultSet.getString(1),
          privacyUri: resultSet.getString(2),
          media_type: resultSet.getLong(3),
          date_added: resultSet.getLong(4),
        }
      )
    }
  }
  // 循环结束,释放结果集的内存空间(性能优化)
  resultSet.close()
  // 循环结束后,返回结果
  if (ilk === secret.NOTE) {
    return note
  } else
    if (ilk === secret.RECORDER) {
      return recorder
    } else
    if (ilk === secret.PHOTO) {
      return photo
    } else {
    return 
  }
}
知识补充 谓词
RdbPredicates

表示关系型数据库(RDB)的谓词,主要用来定义数据库的操作条件。

使用说明

RdbPredicates 为构造函数类,需要通过 new 关键词创建类的实例,参数为 数据库表名

参数:

参数名类型必填说明
namestring数据库表名
知识补充 结果集
ResultSet

提供通过查询数据库生成的数据库结果集的访问方法。结果集是指用户调用关系型数据库查询接口之后返回的结果集合,提供了多种灵活的数据访问方式,以便用户获取各项数据。

属性

名称类型必填说明
columnNamesArray获取结果集中所有列的名称。
columnCountnumber获取结果集中的列数。
rowCountnumber获取结果集中的行数。
删除数据
//删除数据
async delete(id: number, ilk: secret) {
 this.privacy = await this.getPrivacy(ilk)
 const store = await this.getStoreInstance(ilk)
 const predicates = new relationalStore.RdbPredicates(this.privacy)
 predicates.equalTo('id', id)
 // 删除完成,返回受影响的行数
 const rowCount = await store.delete(predicates)
 return rowCount ? Promise.resolve(rowCount) : Promise.reject('delete error')

}

补充批量删除

//批量删除数据
async batchDelete(ids: number[], ilk: secret) {
  this.privacy = await this.getPrivacy(ilk)
  const store = await this.getStoreInstance(ilk)
  const predicates = new relationalStore.RdbPredicates(this.privacy)
  predicates.in('id', ids)
  // 删除完成,返回受影响的行数
  const rowCount = await store.delete(predicates)
  return rowCount ? Promise.resolve(rowCount) : Promise.reject('delete error')

}
更新数据
//更新数据
  async update(item: PrivacyNoteDBInfo | PrivacyRecorderDBInfo | PrivacyPhotoDBInfo, ilk: secret) {
    // 如果没有 id 直接退出
    if (!item.id) {
      return Promise.reject('id error')
    }
    this.privacy = await this.getPrivacy(ilk)
    const store = await this.getStoreInstance(ilk)
    const predicates = new relationalStore.RdbPredicates(this.privacy)
    predicates.equalTo('id', item.id)
    // 更新完成,返回受影响的行数
    const rowCount = await store.update(item, predicates)
    return rowCount ? Promise.resolve(rowCount) : Promise.reject('delete error')
  }
}
最后通过 new 实例的方法导出
export const privacyNoteDB = new PrivacyNoteDB()
完整封装代码
import { relationalStore, ValuesBucket } from '@kit.ArkData'

//笔记文件关键信息
export interface PrivacyNoteDBInfo extends ValuesBucket {
  id: number | null,
  title: string,
  content: string,
  date_added: number,
}

// 隐私录音的字段
export interface PrivacyRecorderDBInfo extends ValuesBucket {
  id: number | null // 新增时 id 为 null ,自动生成自增 id
  filePath: string
  title: string
  date_added: number
  duration: number
}

// 图片和视频文件关键信息。(PhotoKeys)
export interface PrivacyPhotoDBInfo extends ValuesBucket {
  id: number | null // 新增时 id 为 null ,自动生成自增 id
  mediaUri: string // 文件uri
  privacyUri: string // 沙箱文件uri
  media_type: number // 媒体文件类型
  date_added: number // 添加日期
}

//隐私类型枚举
export enum secret {
  NOTE,
  RECORDER,
  PHOTO
}

class PrivacyDB {
  // SQL 语法:(SQL语法的数据类型关键词不一样,可通过AI生成SQL语句)
  // 解释说明:
  //   CREATE TABLE IF NOT EXISTS     如果表不存在才创建新的表
  //   INTEGER -> number              INTEGER 整数型   FLOAT 浮点数
  //   PRIMARY KEY                    主键(唯一标识)
  //   AUTOINCREMENT                  自增
  //   TEXT -> string                 字符串型
  //   NOT NULL                       不允许空
  //表名
  private privacy: string = ''
  //隐私笔记初始化数据库
  private noteContent: string = `CREATE TABLE IF NOT EXISTS PRIVACY_NOTE (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        content TEXT NOT NULL,
        date_added INTEGER NOT NULL
      )`
  //隐私录音初始化数据库
  private recorderContent: string = `CREATE TABLE IF NOT EXISTS PRIVACY_RECORDER (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        filePath TEXT,
        title TEXT,
        date_added INTEGER,
        duration INTEGER
      )`
  //隐私相册初始化数据库
  private photoContent: string = `CREATE TABLE IF NOT EXISTS PRIVACY_PHOTO (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        mediaUri TEXT,
        privacyUri TEXT,
        media_type INTEGER,
        date_added INTEGER
      )`
  // 操作数据库的管理对象
  private store: relationalStore.RdbStore | null = null

  // 判断表名
  getPrivacy(ilk: secret) {
    let privacy: string = ''
    if (ilk === secret.NOTE) {
      privacy = 'PRIVACY_NOTE'
    }
    if (ilk === secret.RECORDER) {
      privacy = 'PRIVACY_RECORDER'
    }
    if (ilk === secret.PHOTO) {
      privacy = 'PRIVACY_PHOTO'
    }
    return privacy
  }

  //初始化数据库
  async getStoreInstance(ilk: secret) {
    try {
      //当 store 有值时,直接返回 store 的值
      if (this.store) {
        return this.store
      }
      // 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)
      this.store = await relationalStore.getRdbStore(getContext(), {
        name: 'aaa.db',
        securityLevel: relationalStore.SecurityLevel.S1
      })
      // 执行创建表的语句 execute 执行
      this.store.executeSql(this.noteContent)
      this.store.executeSql(this.photoContent)
      this.store.executeSql(this.recorderContent)
      //返回 store 的值
      return this.store
    } catch (err) {
      return Promise.reject('initDB error')
    }
  }

  // 新增数据库
  async insert(item: PrivacyNoteDBInfo | PrivacyRecorderDBInfo | PrivacyPhotoDBInfo, ilk: secret) {
    //判断是哪个表
    this.privacy = await this.getPrivacy(ilk)
    // 获取相应的表
    const store = await this.getStoreInstance(ilk)
    // 将数据添加入表,并赋值给 rowId
    const rowId = await store.insert(this.privacy, item)
    // 返回 rowId
    return rowId > -1 ? Promise.resolve(rowId) : Promise.reject('insert error')
  }

  // 批量新增数据库
  async batchInsert(items: PrivacyNoteDBInfo[] | PrivacyRecorderDBInfo[] | PrivacyPhotoDBInfo[], ilk: secret) {
    this.privacy = await this.getPrivacy(ilk)
    const store = await this.getStoreInstance(ilk)
    const rowId = await store.batchInsert(this.privacy, items)
    return rowId ? Promise.resolve(rowId) : Promise.reject('insert error')
  }

  //查询数据库总数
  async queryCount(ilk: secret) {
    //判断是哪个表
    this.privacy = await this.getPrivacy(ilk)
    // 获取相应的表
    const store = await this.getStoreInstance(ilk)
    const predicates = new relationalStore.RdbPredicates(this.privacy)
    const resultSet = await store.query(predicates)
    return resultSet.rowCount > 0 ? resultSet.rowCount : 0
  }

  //查询数据
  async query(ilk: secret, id?: number) {
    this.privacy = await this.getPrivacy(ilk)
    const store = await this.getStoreInstance(ilk)
    const predicates = new relationalStore.RdbPredicates(this.privacy)
    // 倒序排列
    predicates.orderByDesc('id')
    // 如果有 id,添加 id 作为查询条件
    if (id) {
      predicates.equalTo('id', id)
    }
    const resultSet = await store.query(predicates)
    const note: PrivacyNoteDBInfo[] = []
    const recorder: PrivacyRecorderDBInfo[] = []
    const photo: PrivacyPhotoDBInfo[] = []
    while (resultSet.goToNextRow()) {
      // 移动指针的时候提取数据,按列下标提取数据
      if (ilk === secret.NOTE) {
        note.push(
          {
            id: resultSet.getLong(0),
            title: resultSet.getString(1),
            content: resultSet.getString(2),
            date_added: resultSet.getLong(3),
          }
        )
      }
      if (ilk === secret.RECORDER) {
        recorder.push(
          {
            id: resultSet.getLong(0),
            filePath: resultSet.getString(1),
            title: resultSet.getString(2),
            date_added: resultSet.getLong(3),
            duration: resultSet.getLong(4),
          }
        )
      }
      if (ilk === secret.PHOTO) {
        photo.push(
          {
            id: resultSet.getLong(0),
            mediaUri: resultSet.getString(1),
            privacyUri: resultSet.getString(2),
            media_type: resultSet.getLong(3),
            date_added: resultSet.getLong(4),
          }
        )
      }
    }
    // 循环结束,释放结果集的内存空间(性能优化)
    resultSet.close()
    // 循环结束后,返回结果
    if (ilk === secret.NOTE) {
      return note
    } else
      if (ilk === secret.RECORDER) {
        return recorder
      } else
      if (ilk === secret.PHOTO) {
        return photo
      } else {
      return
    }
  }

  //删除数据
  async delete(id: number, ilk: secret) {
    this.privacy = await this.getPrivacy(ilk)
    const store = await this.getStoreInstance(ilk)
    const predicates = new relationalStore.RdbPredicates(this.privacy)
    predicates.equalTo('id', id)
    // 删除完成,返回受影响的行数
    const rowCount = await store.delete(predicates)
    return rowCount ? Promise.resolve(rowCount) : Promise.reject('delete error')

  }

  //批量删除数据
  async batchDelete(ids: number[], ilk: secret) {
    this.privacy = await this.getPrivacy(ilk)
    const store = await this.getStoreInstance(ilk)
    const predicates = new relationalStore.RdbPredicates(this.privacy)
    predicates.in('id', ids)
    // 删除完成,返回受影响的行数
    const rowCount = await store.delete(predicates)
    return rowCount ? Promise.resolve(rowCount) : Promise.reject('delete error')

  }

  //更新数据
  async update(item: PrivacyNoteDBInfo | PrivacyRecorderDBInfo | PrivacyPhotoDBInfo, ilk: secret) {
    // 如果没有 id 直接退出
    if (!item.id) {
      return Promise.reject('id error')
    }
    this.privacy = await this.getPrivacy(ilk)
    const store = await this.getStoreInstance(ilk)
    const predicates = new relationalStore.RdbPredicates(this.privacy)
    predicates.equalTo('id', item.id)
    // 更新完成,返回受影响的行数
    const rowCount = await store.update(item, predicates)
    return rowCount ? Promise.resolve(rowCount) : Promise.reject('delete error')
  }
}

export const privacyNoteDB = new PrivacyNoteDB()

继承法

准备封装
import { relationalStore, ValuesBucket } from '@kit.ArkData'

// 数据库名和表名
const tableName = 'privacy_note'

// 创建数据库的语句
const sqlCreate = `CREATE TABLE IF NOT EXISTS qwe (

        id INTEGER PRIMARY KEY AUTOINCREMENT,

        title TEXT NOT NULL,

        content TEXT NOT NULL,

        date_added INTEGER NOT NULL

      )`
    
// RdbModule类用于封装对关系型数据库的操作
class RdbModule {

  // 操作数据库的实例
  private store: relationalStore.RdbStore | null = null;
  private tableName: string; // 数据库表的名称
  private sqlCreate: string; // 创建数据库表的SQL语句
  private securityLevel: relationalStore.SecurityLevel; // 数据库的安全等级

  // 构造函数,初始化表名、创建语句和安全等级
  constructor(tableName: string, sqlCreate: string, securityLevel: relationalStore.SecurityLevel) {
    if (sqlCreate.includes(tableName)) {
      this.tableName = tableName;
      this.sqlCreate = sqlCreate;
      this.securityLevel = securityLevel;
    } else {
      // 如果表名和建表语句内的表名不匹配,则抛出错误
      console.error("The table name does not match the statement that created the table")
      throw new Error("The table name does not match the statement that created the table");
    }
  }
}
初始化数据库
// 获取数据库操作实例,如果已存在则直接返回,否则创建新的实例
  async getStoreInstance() {
    if (this.store) {
      return this.store;
    }
    const store = await relationalStore.getRdbStore(getContext(), {
      name: this.tableName + '.db', // 数据库名称
      securityLevel: this.securityLevel // 安全等级
    });
    store.executeSql(this.sqlCreate); // 执行创建表的SQL语句
    this.store = store; // 存储实例以便后续使用
    return this.store; // 返回数据库操作实例
  }
新增数据
// 插入一条数据到数据库
  async setData<T extends ValuesBucket>(value: T) {
    const store = await this.getStoreInstance();
    return store.insert(this.tableName, value);
  }
查询
查询表内总数
 // 查询数据库中的数据量
  async getTotal() {
    const store = await this.getStoreInstance();
    const predicates = new relationalStore.RdbPredicates(this.tableName);
    const results = await store.query(predicates);
    return results.rowCount <= 0 ? 0 : results.rowCount;
  }
查询数据(可批量查询)
// 查询数据库列表,可以指定单个或多个ID,返回一个数组
  async getTheList<T>(id?: number | number[]) {
    const store = await this.getStoreInstance();
    const predicates = new relationalStore.RdbPredicates(this.tableName);
    if (typeof id === 'number') {
      id = [id];
    }
    id !== undefined ? predicates.in("id", id) : predicates.orderByDesc("id");
    const results = await store.query(predicates);
    const list: T[] = [];
    while (results.goToNextRow()) {
      list.push(results.getRow() as T);
    }
    return list;
  }
删除数据
// 删除数据库中的数据
  async delData(id: number) {
    const store = await this.getStoreInstance();
    const predicates = new relationalStore.RdbPredicates(this.tableName);
    predicates.equalTo("id", id);
    return store.delete(predicates);
  }
更新数据
// 更新数据库中的数据
 async upData<T extends ValuesBucket>(id: number, val: T) {
   const store = await this.getStoreInstance();
   const predicates = new relationalStore.RdbPredicates(this.tableName);
   predicates.equalTo("id", id);
   return store.update(val, predicates);
 }
完整封装代码
import { relationalStore, ValuesBucket } from '@kit.ArkData'



// 数据库名和表名

const tableName = 'privacy_note'

// 创建数据库的语句

const sqlCreate = `CREATE TABLE IF NOT EXISTS qwe (

        id INTEGER PRIMARY KEY AUTOINCREMENT,

        title TEXT NOT NULL,

        content TEXT NOT NULL,

        date_added INTEGER NOT NULL

      )`





// RdbModule类用于封装对关系型数据库的操作

class RdbModule {

  // 操作数据库的实例

  private store: relationalStore.RdbStore | null = null;

  private tableName: string; // 数据库表的名称

  private sqlCreate: string; // 创建数据库表的SQL语句

  private securityLevel: relationalStore.SecurityLevel; // 数据库的安全等级



  // 构造函数,初始化表名、创建语句和安全等级

  constructor(tableName: string, sqlCreate: string, securityLevel: relationalStore.SecurityLevel) {

    if (sqlCreate.includes(tableName)) {

      this.tableName = tableName;

      this.sqlCreate = sqlCreate;

      this.securityLevel = securityLevel;

    } else {

      // 如果表名和建表语句内的表名不匹配,则抛出错误

      console.error("The table name does not match the statement that created the table")

      throw new Error("The table name does not match the statement that created the table");

    }

  }



  // 获取数据库操作实例,如果已存在则直接返回,否则创建新的实例

  async getStoreInstance() {

    if (this.store) {

      return this.store;

    }

    const store = await relationalStore.getRdbStore(getContext(), {

      name: this.tableName + '.db', // 数据库名称

      securityLevel: this.securityLevel // 安全等级

    });

    store.executeSql(this.sqlCreate); // 执行创建表的SQL语句

    this.store = store; // 存储实例以便后续使用

    return this.store; // 返回数据库操作实例

  }



  // 插入一条数据到数据库

  async setData<T extends ValuesBucket>(value: T) {

    const store = await this.getStoreInstance();

    return store.insert(this.tableName, value);

  }



  // 查询数据库中的数据量

  async getTotal() {

    const store = await this.getStoreInstance();

    const predicates = new relationalStore.RdbPredicates(this.tableName);

    const results = await store.query(predicates);

    return results.rowCount <= 0 ? 0 : results.rowCount;

  }



  // 查询数据库列表,可以指定单个或多个ID,返回一个数组

  async getTheList<T>(id?: number | number[]) {

    const store = await this.getStoreInstance();

    const predicates = new relationalStore.RdbPredicates(this.tableName);

    if (typeof id === 'number') {

      id = [id];

    }

    id !== undefined ? predicates.in("id", id) : predicates.orderByDesc("id");

    const results = await store.query(predicates);



    const list: T[] = [];

    while (results.goToNextRow()) {

      list.push(results.getRow() as T);

    }

    return list;

  }



  // 更新数据库中的数据

  async upData<T extends ValuesBucket>(id: number, val: T) {

    const store = await this.getStoreInstance();

    const predicates = new relationalStore.RdbPredicates(this.tableName);

    predicates.equalTo("id", id);

    return store.update(val, predicates);

  }



  // 删除数据库中的数据

  async delData(id: number) {

    const store = await this.getStoreInstance();

    const predicates = new relationalStore.RdbPredicates(this.tableName);

    predicates.equalTo("id", id);

    return store.delete(predicates);

  }

}



// 创建RdbModule实例,并传入表名、创建语句和安全等级

// 如果需要多个数据库,可以导出多个实例

export const rdbModule = new RdbModule(tableName, sqlCreate, relationalStore.SecurityLevel.S1);
  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt是一种广泛应用的C++跨平台开发框架,它为开发人员提供了丰富的工具和库来简化软件开发过程。Qt还提供了对数据库的支持,允许开发者使用数据库进行数据的存储和管理。为了进一步简化开发过程,我们可以封装一个数据库工具数据库工具的主要目的是封装数据库的操作,使其易于使用、可重用,并提供错误处理和异常处理机制。以下是一个可能的Qt数据库工具的实现示例。 首先,我们需要一个来代表数据库连接。我们可以创建一个名为Database的,其中包含连接数据库、断开数据库、执行查询等功能的成员函数。 其次,我们可以创建一个Table,用于代表数据库中的表。Table可以提供一些功能,如创建表、插入数据、更新数据、删除数据等。 我们还可以为每个表创建对应的模型,用于与Qt的模型视图框架进行交互。模型可以继承自Qt的QAbstractTableModel,并实现一些必要的函数,如rowCount、columnCount、data等。这样,我们可以方便地将表中的数据展示在Qt的ListView或TableView等控件上。 在封装数据库工具时,我们还可以考虑使用单例模式,确保整个应用程序中只有一个数据库实例存在。这样做可以避免重复创建数据库连接和占用过多资源。 总的来说,Qt数据库工具封装可以大大简化数据库操作的编写过程,提高代码的可读性和可维护性。通过对数据库连接的封装,我们可以更方便地进行数据库操作,同时减少错误和异常处理的工作量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值