关系型数据库(RDB)
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。不支持Worker线程。 ArkTS侧支持的基本数据类型:number、string、二进制类型数据、boolean。为保证插入并读取数据成功,建议一条数据不要超过2M。超出该大小,插入成功,读取失败。
该模块提供以下关系型数据库相关的常用功能:
-
RdbPredicates: 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
-
RdbStore:提供管理关系数据库(RDB)方法的接口。
-
ResultSet:提供用户调用关系型数据库查询接口之后返回的结果集合。
说明:
1、导入模块
包不要导错了,API9的版本:
import relationalStore from '@ohos.data.relationalStore'; //旧版API,不建议使用
-
建议使用最新的API11:
import { relationalStore, ValuesBucket } from '@kit.ArkData'
2、创建数据库文件
Button('创建数据库文件').onClick(async () => {// 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)const store = await relationalStore.getRdbStore(getContext(), {name: 'RDB.db', // 数据库文件名securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别})// 执行创建表的语句 execute 执行store.executeSql(this.sqlCreate)AlertDialog.show({ message: '创建成功' })})
注意:需要获取数据库管理对象,才能进行增删改查操作
// 获取数据库管理对象async getStoreInstance() {// 如果已经存在,直接返回if (this.store) {return this.store}// 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)this.store = await relationalStore.getRdbStore(getContext(), {name: 'RDB.db', // 数据库文件名securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别})// 执行创建表的语句 execute 执行this.store.executeSql(this.sqlCreate)// 返回 store 对象return this.store}
3、查询数据库表的字段
Button('查询数据库表的字段').onClick(async () => {// 获取操作数据库的对象const store = await this.getStoreInstance()// 谓词(条件),谓词类需要 new 实例化,传入表名 privacy_noteconst predicates = new relationalStore.RdbPredicates(this.tableName)// query 查询,传入必传参数 谓词const resultSet = await store.query(predicates)AlertDialog.show({ message: '数据库的字段名:' + resultSet.columnNames })})
4、新插入一条数据
Button('新建一条数据').onClick(async () => {// 获取操作数据库的对象const store = await this.getStoreInstance()// 添加一条数据const id = await store.insert(this.tableName, {id: null, // 新增时设置 id 为空值 null,用于自增 idtitle: '关键的问题',content: '111',date_added: Date.now()} as NoteItem)AlertDialog.show({ message: '新增数组成功,数据的id为:' + id })// 批量添加,传入数组// store.batchInsert(表名, 数组)})
5、修改数据
Button('更新(修改)数据').onClick(async () => {// 获取操作数据库对象const store = await this.getStoreInstance()// 谓词(条件)const predicates = new relationalStore.RdbPredicates(this.tableName)// 注意!!!:记得添加 predicates 限定条件,否者修改全部predicates.equalTo('id', 10)// 待更新数据const value = {title: '新的标题',content: '新的内容'} as NoteItemconst affectedRows = await store.update(value, predicates)AlertDialog.show({ message: '更新(修改)数据 - 受影响行数:' + affectedRows })})
5、删除数据库文件(不推荐使用delete,建议设置为空值即可)
Button('删除数据库文件').enabled(false).onClick(async () => {try {await relationalStore.deleteRdbStore(getContext(), 'heima.db')AlertDialog.show({ message: '删除成功' })} catch (error) {AlertDialog.show({ message: JSON.stringify(error, null, 2) })}})
6、最后,献上完整代码
import { relationalStore, ValuesBucket } from '@kit.ArkData'
// ValuesBucket 数据库支持的类型
interface NoteItem extends ValuesBucket {id: number | null // 新增时设置 id 为空值 null,用于自增 idtitle: stringcontent: stringdate_added: number
}
@Entry
@Component
struct RdbStoreTestPage {// 表名tableName: string = 'privacy_note'// SQL 语法:(SQL语法的数据类型关键词不一样,可通过AI生成SQL语句)// 解释说明:// CREATE TABLE IF NOT EXISTS 如果表不存在才创建新的表// INTEGER -> number INTEGER 整数型 FLOAT 浮点数// PRIMARY KEY 主键(唯一标识)// AUTOINCREMENT 自增// TEXT -> string 字符串型// NOT NULL 不允许空sqlCreate: 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)`// 操作数据库的管理对象store: relationalStore.RdbStore | null = null
// 获取数据库管理对象async getStoreInstance() {// 如果已经存在,直接返回if (this.store) {return this.store}// 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)this.store = await relationalStore.getRdbStore(getContext(), {name: 'rdb.db', // 数据库文件名securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别})// 执行创建表的语句 execute 执行this.store.executeSql(this.sqlCreate)// 返回 store 对象return this.store}
build() {Navigation() {Scroll() {Column({ space: 10 }) {Button('创建数据库文件').onClick(async () => {// 获取操作数据库的管理对象(如果数据库文件不存在,会自动创建数据库文件)const store = await relationalStore.getRdbStore(getContext(), {name: 'heima.db', // 数据库文件名securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别})// 执行创建表的语句 execute 执行store.executeSql(this.sqlCreate)AlertDialog.show({ message: '创建成功' })})Button('查询数据库表的字段').onClick(async () => {// 获取操作数据库的对象const store = await this.getStoreInstance()// 谓词(条件),谓词类需要 new 实例化,传入表名 privacy_noteconst predicates = new relationalStore.RdbPredicates(this.tableName)// query 查询,传入必传参数 谓词const resultSet = await store.query(predicates)AlertDialog.show({ message: '数据库的字段名:' + resultSet.columnNames })})Button('新建一条数据').onClick(async () => {// 获取操作数据库的对象const store = await this.getStoreInstance()// 添加一条数据const id = await store.insert(this.tableName, {id: null, // 新增时设置 id 为空值 null,用于自增 idtitle: '哈哈哈呵呵呵',content: '111',date_added: Date.now()} as NoteItem)AlertDialog.show({ message: '新增数组成功,数据的id为:' + id })// 批量添加,传入数组// store.batchInsert(表名, 数组)})Button('查询所有数据').onClick(async () => {// 获取操作数据库的对象const store = await this.getStoreInstance()// 谓词(条件)const predicates = new relationalStore.RdbPredicates(this.tableName)predicates.orderByDesc('id') // 倒序(由大到小,常用于排序)// predicates.orderByAsc('id') // 正序(小到大,常用于排序)// predicates.equalTo('id', 1) // 等于(常用于详情页)// predicates.in('id', [1, 3, 5]) // 查找多项(常用批量删除)// predicates.like('title', '%哈%') // 模糊匹配(常用于搜索)// 还有很多...// predicates.greaterThan('id', 3)// resultSet 结果集const resultSet = await store.query(predicates)// 准备一个数组,用于存储数据库提取的数据const list: NoteItem [] = []// resultSet.goToNextRow() 指针移动到下一行while (resultSet.goToNextRow()) {// 移动指针的时候提取数据,按列下标提取数据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) })})
Button('查询数据总条数').onClick(async () => {// 获取操作数据库对象const store = await this.getStoreInstance()// 谓词(条件)const predicates = new relationalStore.RdbPredicates(this.tableName)// 结果集const resultSet = await store.query(predicates)AlertDialog.show({ message: '数据总条(行)数 rowCount:' + resultSet.rowCount })})
Button('删除数据').onClick(async () => {// 获取操作数据库对象const store = await this.getStoreInstance()const predicates = new relationalStore.RdbPredicates(this.tableName)// 注意!!!:记得添加 predicates 限定条件,否者会删除所有数据// predicates.equalTo('id', 2) // equalTo 删除一条predicates.in('id', [1, 2, 3, 4, 5]) // in 批量删除const affectedRows = await store.delete(predicates)AlertDialog.show({ message: '受影响行数:' + affectedRows })})
Button('更新(修改)数据').onClick(async () => {// 获取操作数据库对象const store = await this.getStoreInstance()// 谓词(条件)const predicates = new relationalStore.RdbPredicates(this.tableName)// 注意!!!:记得添加 predicates 限定条件,否者修改全部predicates.equalTo('id', 10)// 待更新数据const value = {title: '新的标题',content: '新的内容'} as NoteItemconst affectedRows = await store.update(value, predicates)AlertDialog.show({ message: '更新(修改)数据 - 受影响行数:' + affectedRows })})// Button('删除数据库文件')// .enabled(false)// .onClick(async () => {// try {// await relationalStore.deleteRdbStore(getContext(), 'heima.db')// AlertDialog.show({ message: '删除成功' })// } catch (error) {// AlertDialog.show({ message: JSON.stringify(error, null, 2) })// }// })}.constraintSize({ minHeight: '100%' })}.width('100%').height('100%')}.title('关系型数据库').titleMode(NavigationTitleMode.Mini)}
}