一、官方介绍
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。不支持Worker线程。 ArkTS侧支持的基本数据类型:number、string、二进制类型数据、boolean。为保证插入并读取数据成功,建议一条数据不要超过2M。超出该大小,插入成功,读取失败。
该模块提供以下关系型数据库相关的常用功能:
- RdbPredicates: 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
- RdbStore:提供管理关系数据库(RDB)方法的接口。
- ResultSet:提供用户调用关系型数据库查询接口之后返回的结果集合。
二、准备阶段
1、准备一个数据类
用@Observe装饰器是因为需要跟使用的页面进行双向的数据绑定,定义了id跟name两个变量
@Observed
export default class TaskInfo {
id: number
name: string
constructor(id: number, name: string) {
this.id = id
this.name = name
}
}
2、在common目录下新建rdbStore.ets文件
定义一个TaskModel类,定义初始化、读取、新增、删除来完善数据库的功能
class TaskModel {
// 初始化任务表
initTaskDB(context) {}
// 查询任务表
getTaskList() {}
/*
* 添加新任务
* @param name 任务名称
* @return 任务id
* */
addTask(name: string) {}
/*
* 根据id更新任务状态
* @param id 任务id
* */
updataTaskStatus(id: number, name: string) {}
/*
* 根据id删除任务
* @param id 任务id
* */
deleteTaskById(id: number) {}
}
const taskModel = new TaskModel()
export default taskModel as TaskModel
初始化table
配置rdb,取名+设置安全级别
初始化sql语句,创建一个table
import relationalStore from '@ohos.data.relationalStore';
通过引入的relationalStore的getRdbStore获取rdb
private rdbStore: relationalStore.RdbStore
并在初始化之后,保存rdbStore,以供后面的方法使用
// 初始化任务表
initTaskDB(context) {
// 1、rdb配置
const config = {
name: 'MyAppRdbStore.db',
// 设置数据库的安全级别s1 s2 s3 s4 从低到高
securityLevel: relationalStore.SecurityLevel.S1
}
// 2、初始化sql语句
const sql = `CREATE TABLE IF NOT EXISTS TASK (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
NAME TEXT NOT NULL
)`
// 3、获取rdb
relationalStore.getRdbStore(context, config, (err, rdbStore) => {
if (err) {
console.log('testTag', '获取rdbStore失败')
return
}
// 执行sql
rdbStore.executeSql(sql)
console.log('testTag', '创建task表成功')
// 保存rdbStore
this.rdbStore = rdbStore
})
}
查询
import TaskInfo from '../../common/rdbStore/taskModel'
class TaskModel {
private tableName: string = 'TASK'
}
引入提前准备的数据类,并自定义table的name
// 查询任务表
async getTaskList() {
// 1.构建查询条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
// 2.查询
const result = await this.rdbStore.query(predicates, ['ID', 'NAME'])
// 3.解析查询结果
// 3.1 定义一个数组,用于组装最终的查询结果,导入事先准备好的TaskInfo类
const tasks: TaskInfo[] = []
// 3.2 遍历封装
while (!result.isAtLastRow) {
// 3.3 指针移动到下一行
result.goToNextRow()
// 3.4 获取数据
const id = result.getLong(result.getColumnIndex('ID'))
const name = result.getString(result.getColumnIndex('NAME'))
// 封装到数组
tasks.push({ id, name })
}
console.log('testTag', '查询到数据', JSON.stringify(tasks));
return tasks
}
新增
/*
* 添加新任务
* @param name 任务名称
* @return 任务id
* */
addTask(name: string): Promise<number> {
console.log('testTag', '新增的数据', name);
return this.rdbStore.insert(this.tableName, { name })
}
更新
/*
* 根据id更新任务状态
* @param id 任务id
* */
updataTaskStatus(id: number, name: string) {
// 1. 要更新的数据
const data = { name }
// 2. 要更新的条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('ID', id)
// 3. 更新操作
return this.rdbStore.update(data, predicates)
}
删除
/*
* 根据id删除任务
* @param id 任务id
* */
deleteTaskById(id: number) {
// 1. 删除的条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('ID', id)
// 2. 删除操作
return this.rdbStore.delete(predicates)
}
完整的代码
import relationalStore from '@ohos.data.relationalStore';
import TaskInfo from '../../common/rdbStore/taskModel'
class TaskModel {
private rdbStore: relationalStore.RdbStore
private tableName: string = 'TASK'
// 初始化任务表
initTaskDB(context) {
// 1、rdb配置
const config = {
name: 'MyAppRdbStore.db',
// 设置数据库的安全级别s1 s2 s3 s4 从低到高
securityLevel: relationalStore.SecurityLevel.S1
}
// 2、初始化sql语句
const sql = `CREATE TABLE IF NOT EXISTS TASK (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
NAME TEXT NOT NULL
)`
// 3、获取rdb
relationalStore.getRdbStore(context, config, (err, rdbStore) => {
if (err) {
console.log('testTag', '获取rdbStore失败')
return
}
// 执行sql
rdbStore.executeSql(sql)
console.log('testTag', '创建task表成功')
// 保存rdbStore
this.rdbStore = rdbStore
})
}
// 查询任务表
async getTaskList() {
// 1.构建查询条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
// 2.查询
const result = await this.rdbStore.query(predicates, ['ID', 'NAME'])
// 3.解析查询结果
// 3.1 定义一个数组,用于组装最终的查询结果,导入事先准备好的TaskInfo类
const tasks: TaskInfo[] = []
// 3.2 遍历封装
while (!result.isAtLastRow) {
// 3.3 指针移动到下一行
result.goToNextRow()
// 3.4 获取数据
const id = result.getLong(result.getColumnIndex('ID'))
const name = result.getString(result.getColumnIndex('NAME'))
// 封装到数组
tasks.push({ id, name })
}
console.log('testTag', '查询到数据', JSON.stringify(tasks));
return tasks
}
/*
* 添加新任务
* @param name 任务名称
* @return 任务id
* */
addTask(name: string): Promise<number> {
console.log('testTag', '新增的数据', name);
return this.rdbStore.insert(this.tableName, { name })
}
/*
* 根据id更新任务状态
* @param id 任务id
* */
updataTaskStatus(id: number, name: string) {
// 1. 要更新的数据
const data = { name }
// 2. 要更新的条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('ID', id)
// 3. 更新操作
return this.rdbStore.update(data, predicates)
}
/*
* 根据id删除任务
* @param id 任务id
* */
deleteTaskById(id: number) {
// 1. 删除的条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('ID', id)
// 2. 删除操作
return this.rdbStore.delete(predicates)
}
}
const taskModel = new TaskModel()
export default taskModel as TaskModel
三、使用
1、在EntryAbility.ets(需要把文件后缀改为ets文件)中的onCreate钩子中传入context初始化table
import TaskModel from '../common/rdbStore/rdbStore'
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
// 初始化TaskModel
TaskModel.initTaskDB(this.context)
}
2、使用的页面,仅调用了方法,并未实现页面功能
import TaskModel from '../../common/rdbStore/rdbStore'
import TaskInfo from '../../common/rdbStore/taskModel'
@Entry
@Component
struct SearchExample {
@State hisSearchArr: TaskInfo[] = []
aboutToAppear() {
TaskModel.getTaskList().then((tasks) => {
this.hisSearchArr = tasks
console.log('testTag', JSON.stringify(this.hisSearchArr), '查询到的数据')
}).catch((e) => [
console.log('testTag', e, '查询失败')
])
}
// 新增数据
addTask(value: string) {
TaskModel.addTask(value).then(id => {
this.hisSearchArr.push(new TaskInfo(id, value))
console.log('testTag', JSON.stringify(this.hisSearchArr), '更新后的数据')
}).catch((e) => [
console.log('testTag', '新增失败', JSON.stringify(e))
])
}
build() {
Column() {
}.width('100%')
}
}
删除、更新操作同理
PS:
1、ts文件不能被ets文件引用,同理,ets文件也不能被ts文件引用
2、持久化效果在预览器中不生效,仅在模拟机以及真机中有效