一、简介
关系数据库是一种基于关系模型来管理数据的数据库,鸿蒙基于SQLite组件提供了一套完整的本地数据库管理机制:
- 提供增删改查等接口
- 支持直接运行用户输入的SQL语句
- 满足复杂场景需求
二、基本概念
概念 | 说明 |
---|---|
关系数据库 | 以行和列形式存储数据,基于关系模型管理数据 |
谓词(RdbPredicates) | 定义数据库操作条件的词项,代表数据实体的性质、特征或关系 |
结果集(ResultSet) | 查询后的结果集合,提供灵活的数据访问方式 |
SQLite数据库 | 轻量级开源关系数据库,遵守ACID特性(原子性、一致性、隔离性、持久性) |
建议:单条数据不超过2MB
三、特点和优势
数据完整性
- 通过约束条件和外键关系确保数据一致性
- 防止数据损坏或不一致
事务处理
- 支持ACID特性(原子性、一致性、隔离性、持久性)
- 保障并发环境下的数据安全
复杂查询能力
- 支持多表关联查询
- 处理复杂分析操作
数据安全性
- 用户身份验证
- 权限控制
- 数据加密
四、系统能力
接口 | 功能 |
---|---|
RdbPredicates | 定义数据库操作条件 |
RdbStore | 管理关系数据库的核心接口 |
ResultSet | 封装查询结果集合 |
五、应用
- 导入模块
import { relationalStore, ValuesBucket} from '@kit.ArkData';
- 创建数据库
this.store = await relationalStore.getRdbStore(getContext(), {
name: 'first.db',
securityLevel: relationalStore.SecurityLevel.S1
});
- 创建表
await this.store?.executeSql(this.sql)
- 查询表的信息
const predicates = new relationalStore.RdbPredicates(this.tableName) // 传入表名
const resultSet = await this.store?.query(predicates)
- 新增数据
const id = await this.store?.insert('PrivacyNote', {
id: null,
title: '测试标题',
content: '测试标题',
date_added: Date.now(),
} as PrivacyNote)
- 查询数据 - query
const id = await this.store?.insert('PrivacyNote', {
id: null,
title: '测试标题',
content: '测试标题',
date_added: Date.now(),
} as PrivacyNote)
- 删除数据 - delete
const predicates = new relationalStore.RdbPredicates(this.tableName)
//predicates.in('id', [2,5,6]) 可以删除多条信息
predicates.equalTo('id', 1)
await this.store?.delete(predicates)
//要加上限定条件,不然就删库了
- 更新数据 - update
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('id', 4)
await this.store?.update({
content: '修改了'
} as PrivacyNote, predicates)
- 删除数据库
await relationalStore.deleteRdbStore(getContext(), 'first.db')
- 完整代码示例
import { relationalStore, ValuesBucket} from '@kit.ArkData';
import { promptAction } from '@kit.ArkUI';
// ValuesBucket 数据库值的类型
interface PrivacyNote extends ValuesBucket{
id: number | null
title: string
content: string
date_added: number
}
@Entry
@Component
struct DatabaseTestPage {
store: relationalStore.RdbStore | null = null
tableName: string = 'PrivacyNote'
sql:string = `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
);`
build() {
Navigation() {
Scroll() {
Column({space: 10}) {
Button('创建数据库')
.onClick(async () => {
//创建
this.store = await relationalStore.getRdbStore(getContext(),{
name: 'heima2.db',
securityLevel: relationalStore.SecurityLevel.S1
})
promptAction.showToast({message: '数据库文件创建成功'})
})
Button('创建表')
.onClick(async () => {
await this.store?.executeSql(this.sql)
promptAction.showToast({message: '建表成功'})
})
Button('查询表的信息')
.onClick(async () => {
// 查表,谓词传入表名
// this.store 数据库(文件操作对象)
// PrivacyNote 表名
const predicates = new relationalStore.RdbPredicates(this.tableName) // 传入表名
const resultSet = await this.store?.query(predicates)
promptAction.showToast({message: '表字段名称' + resultSet?.columnNames})
})
Button('新增数据')
.onClick(async () => {
// insert新增数据,返回值为新增数据的id
// 注意事项:insert新增时,对象的key:value 都要符合建表时的字段和类型
const id = await this.store?.insert('PrivacyNote', {
id: null,
title: '测试标题',
content: '测试标题',
date_added: Date.now(),
} as PrivacyNote)
promptAction.showToast({message: '新增数据成功, id为:' + id})
})
Button('查询数据- query')
.onClick(async () => {
// 查询总条总数
// predicates 谓词(查询条件)
const predicates = new relationalStore.RdbPredicates(this.tableName)
// predicates.orderByAsc('字段名') //正序 从小到大
// predicates.orderByDesc('字段名') //倒叙,从大到小
// predicates.orderByDesc('id')
// predicates.in('id', [1,2,3]) //提取一二三条
// predicates.equalTo('id', 3) //查询单条信息
// predicates.limitAs(3) //提取数量
// predicates.offsetAs(3) //偏移
// predicates.and()
// 结果集
const resultSet = await this.store?.query(predicates)
const rowCount = resultSet?.rowCount as number < 0 ? 0: resultSet?.rowCount
AlertDialog.show({message: '数据总条数' + rowCount})
// 查询列表
// resultSet?.goToNextRow() 移动指针到下一行,如果有数据则能返回true
const list: PrivacyNote[] = []
// goToNextRow 移动指针
while (resultSet?.goToNextRow()) {
//按列提取数据
const item: PrivacyNote = {
id: resultSet?.getLong(0), //列的下标
title: resultSet.getString(1),
content: resultSet.getString(2),
date_added: resultSet.getLong(3)
}
//追加到数组中
list.push(item)
}
AlertDialog.show({message: JSON.stringify(list, null, 2)})
})
Button('删除数据 - delete')
.onClick(async () => {
const predicates = new relationalStore.RdbPredicates(this.tableName)
//predicates.in('id', [2,5,6]) 可以删除多条信息
predicates.equalTo('id', 3)
await this.store?.delete(predicates) //要加上限定条件,不然就删库了
promptAction.showToast({message: '数据删除成功'})
})
Button('更新数据-update')
//记得加上限定条件,否则就是修改全部
.onClick(async () => {
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('id', 4)
await this.store?.update({
content: '傻傻呼呼'
} as PrivacyNote, predicates)
promptAction.showToast({message: '数据更新成功'})
})
Button('删除数据库')
.onClick(async () => {
await relationalStore.deleteRdbStore(getContext(), 'heima2.db')
promptAction.showToast({message: '删除成功'})
})
}
.constraintSize({minHeight: '100%'})
}
.width('100%')
.height('100%')
}
.title('关系型数据库')
.titleMode(NavigationTitleMode.Mini)
}
}
五、关键操作说明
- 条件查询(Predicates)
predicates.orderByAsc('字段名') //正序 从小到大
predicates.orderByDesc('字段名') //倒叙,从大到小
predicates.orderByDesc('id')
predicates.in('id', [1,2,3]) //提取一二三条
predicates.equalTo('id', 3) //查询单条信息
predicates.limitAs(3) //提取数量
predicates.offsetAs(3) //偏移
predicates.and()
- 结果集遍历
while (resultSet?.goToNextRow()) {
//按列提取数据
const item: PrivacyNote = {
id: resultSet?.getLong(0), //列的下标
title: resultSet.getString(1),
content: resultSet.getString(2),
date_added: resultSet.getLong(3)
}