鸿蒙关系型数据库详解增删改查
温馨提示:本文最后更新于2024年10月12日 08:43,若内容或图片失效,请在下方留言或联系博主。
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。支持通过ResultSet.getSendableRow方法获取Sendable数据,进行跨线程传递。
1. 创建数据库文件:
新建之后的保存目录 /data/app/el2/100/database/(项目名)/entry/rdb
// 定义变量 存放管理对象
store: relationalStore.RdbStore | null = null
// 数据库表名
private tableName = 'privacy_note'
// SQL 语法:(不同语法的数据类型关键词不一样)
// 解释说明:
// CREATE TABLE IF NOT EXISTS 如果表不存在就创建新的表
// INTEGER -> number 整数型 FLOAT 浮点数
// PRIMARY KEY 主键(唯一标识)
// AUTOINCREMENT 自增
// TEXT -> string 字符串型
// NOT NULL 非空
// 创建数据库的语句
private sqlCreate = `CREATE TABLE IF NOT EXISTS ${this.tableName} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT NOT NULL,
date_added INTEGER NOT NULL
)`
2. 封装数据库管理对象:
// 封装 数据库管理对象
async getStoreInstance() {
// 如果 store 有对象 就返回 没有的话就创建数据库文件
if (this.store) {
return this.store
}
// store = 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)
this.store = await relationalStore.getRdbStore(getContext(), {
name: "RdbTest.db", // 数据库文件名
securityLevel: relationalStore.SecurityLevel.S1 // 数据库安全级别
})
// 执行创建表的语句 executeSql(执行) this.sqlCreate(执行的SQL语句)
this.store.executeSql(this.sqlCreate)
// 返回 store 对象
return this.store
}
3. 删除数据库文件(删除需谨慎:亲人两行泪):
.onClick(async () => {
try {
// 两个参数 获取上下文 删除的数据库名字
await relationalStore.deleteRdbStore(getContext(), 'RdbTest.db')
promptAction.showToast({ message: '删除成功' })
} catch (err) {
promptAction.showToast({ message: err })
}
})
===步入正题:
1. 查询数据库表中的字段:
// 调用封装的 数据库管理对象 把返回值保存起来
const store = await this.getStoreInstance()
// 谓词(条件)------是表名不是数据库名
const predicates = new relationalStore.RdbPredicates(this.tableName)
// query(谓词) 查询 resultSet 结果集
const resultSet = await store.query(predicates)
AlertDialog.show({ message: '数据库字段名:' + resultSet.columnNames })
2. 新建一条数据:
// 调用封装的 数据库管理对象 把返回值保存起来
const store = await this.getStoreInstance()
// 添加一条数据 两个参数(表名,新增的数据信息)
const id = await store.insert(this.tableName, {
id: null, // null 可以实现自增
title: '王硕杰',
content: '东北彭于晏',
date_added: Date.now() // 时间是一个时间戳
} as NoteItem) // 使用 as 类型的原因是为了 输入时有提示(避免写错)
AlertDialog.show({ message: '数据库字段名:' + id })
// store.batchInsert() // 批量添加数据 传入数组类型
3. 查询所有数据:
// 调用封装的 数据库管理对象 把返回值保存起来
const store = await this.getStoreInstance()
// 谓词(条件)------是表名不是数据库名
const predicates = new relationalStore.RdbPredicates(this.tableName)
// ====== 根据要求筛选 ======
// orderByDesc (字段) // 倒序(由大到小)
// orderByAsc (字段) // 倒序(由小到大)
predicates.orderByDesc('id') // 倒序 (常用于排序) !*!
// predicates.equalTo('id', 1) // 等于 (常用于详情页) !*!
// predicates.in('id', [1, 3]) // 查找多项 (常用于批量删除) !*!
// predicates.like('title', '%王硕杰%') // 模糊匹配 (常用于搜索)--去掉%%准确搜索 !*!
// predicates.greaterThan('id', 3) // 大于XX
// ====== 根据要求筛选 ======
// query(谓词) 根据指定条件查询数据库中的数据 resultSet 结果集
const resultSet = await store.query(predicates)
// 准备一个数组 存放数据库中提取的数据
const list: NoteItem[] = []
// resultSet.goToNextRow() 指针移动到下一行(按 行 提取数据)
while (resultSet.goToNextRow()) { // 返回值是布尔 使用 while 循环
// 移动指针的时候提取数据 按 列 提取数据
list.push({
// resultSet.getColumnIndex() 根据列名称动态获取下标(索引)
id: resultSet.getLong(resultSet.getColumnIndex('id')), // (内传入列的下标)
title: resultSet.getString(resultSet.getColumnIndex('title')),
content: resultSet.getString(resultSet.getColumnIndex('content')),
date_added: resultSet.getLong(resultSet.getColumnIndex('date_added'))
})
}
AlertDialog.show({ message: JSON.stringify(list, null, 2) })
4. 删除某个数据:
// 调用封装的 数据库管理对象 把返回值保存起来
const store = await this.getStoreInstance()
// 谓词(条件)------是表名不是数据库名
const predicates = new relationalStore.RdbPredicates(this.tableName)
// predicates.equalTo('id', 1)
predicates.in('id', [1, 2]) // in 删除多个
// 返回类型是 Promise 所以用异步
const affectedRows = await store.delete(predicates)
// affectedRows 返回值就是 删除的个数
AlertDialog.show({ message: '受影响的行数:' + affectedRows })
5. 更新(修改)某个数据:
// 调用封装的 数据库管理对象 把返回值保存起来
const store = await this.getStoreInstance()
// 谓词(条件)------是表名不是数据库名
const predicates = new relationalStore.RdbPredicates(this.tableName)
// !!!注意!!! 记得添加 predicates 限定条件 否则 就会修改全部
predicates.in('id', [4])
// value 抽取出来 可以写在 update中 但是可读性较差!
const value = {
title: '修改后的标题',
content: '修改后的内容'
} as NoteItem
// 返回类型是 Promise 所以用异步
const affectedRows = await store.update(value, predicates)
// affectedRows 返回值就是 删除的个数
AlertDialog.show({ message: '更新(修改)数据--受影响的行数:' + affectedRows })
7. 查询数据总条数:
// 调用封装的 数据库管理对象 把返回值保存起来
const store = await this.getStoreInstance()
// 谓词(条件)------是表名不是数据库名
const predicates = new relationalStore.RdbPredicates(this.tableName)
// query(谓词) 根据指定条件查询数据库中的数据 resultSet 结果集
const resultSet = await store.query(predicates)
// resultSet.rowCount 总条数
AlertDialog.show({ message: '总条(行RowCount)数:' + resultSet.rowCount })