基本概念
關系型數據庫基于SQLite組件,適用于存儲包含復雜關系數據的場景,比如一個班級的學生信息,需要包括姓名、學號、各科成績等,又或者公司的雇員信息,需要包括姓名、工號、職位等,由于數據之間有較強的對應關系,復雜程度比鍵值型數據更高,此時需要使用關系型數據庫來持久化保存數據。
接口說明
以下是關系型數據庫持久化功能的相關接口,大部分為異步接口。異步接口均有callback和Promise兩種返回形式,下表均以callback形式為例,更多接口及使用方式請見關系型數據庫。
接口名稱 |
描述 |
getRdbStore(context: Context, config: StoreConfig, callback: AsyncCallback<RdbStore>): void |
獲得一個相關的RdbStore,操作關系型數據庫,用戶可以根據自己的需求配置RdbStore的參數,然后通過RdbStore調用相關接口可以執(zhí)行相關的數據操作。 |
executeSql(sql: string, bindArgs: Array<ValueType>, callback: AsyncCallback<void>):void |
執(zhí)行包含指定參數但不返回值的SQL語句。 |
insert(table: string, values: ValuesBucket, callback: AsyncCallback<number>):void |
向目標表中插入一行數據。 |
update(values: ValuesBucket, predicates: RdbPredicates, callback: AsyncCallback<number>):void |
根據RdbPredicates的指定實例對象更新數據庫中的數據。 |
delete(predicates: RdbPredicates, callback: AsyncCallback<number>):void |
根據RdbPredicates的指定實例對象從數據庫中刪除數據。 |
query(predicates: RdbPredicates, columns: Array<string>, callback: AsyncCallback<ResultSet>):void |
根據指定條件查詢數據庫中的數據。 |
deleteRdbStore(context: Context, name: string, callback: AsyncCallback<void>): void |
刪除數據庫。 |
快速使用指南
1. 導入模塊
import relationalStore from '@ohos.data.relationalStore'; // 導入模塊
2. 獲得一個相關的RdbStore
在項目文件中的EntryAbility
在該代碼的生命周期函數onWindowStageCreat中添加代碼:
const STORE_CONFIG = {
name: 'RdbTest.db', // 數據庫文件名
securityLevel: relationalStore.SecurityLevel.S1 // 數據庫安全級別
};
relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
if (err) {
console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
return;
}
console.info(`Succeeded in getting RdbStore.`);
});
relationalStore.getRdbStore接口說明:
getRdbStore(context: Context, config: StoreConfig, callback: AsyncCallback<RdbStore>): void
獲得一個相關的RdbStore,操作關系型數據庫,用戶可以根據自己的需求配置RdbStore的參數,然后通過RdbStore調用相關接口可以執(zhí)行相關的數據操作,使用callback異步回調。
參數:
參數名 |
類型 |
必填 |
說明 |
context |
Context |
是文章來源:http://www.zghlxwxcb.cn/news/detail-793160.html |
應用的上下文。 FA模型的應用Context定義見Context。 Stage模型的應用Context定義見Context。 |
config |
StoreConfig |
是 |
與此RDB存儲相關的數據庫配置。 |
callback |
AsyncCallback<RdbStore> |
是 |
指定callback回調函數,返回RdbStore對象。 |
在該代碼中:STORE_CONFIG為數據庫的配置參數,更詳細的說明在官方文檔,在執(zhí)行getRdbStore時,需要提供context,以及配置參數。
當執(zhí)行getRdbStore后,通過回調函數獲取到RdbStore(store)對象,該對象可以用來操作數據庫,如創(chuàng)建數據庫,增刪改查、創(chuàng)建數據表等操作。
注意:
- 應用創(chuàng)建的數據庫與其上下文(Context)有關,即使使用同樣的數據庫名稱,但不同的應用上下文,會產生多個數據庫,例如每個UIAbility都有各自的上下文。
- 當應用首次獲取數據庫(調用getRdbStore)后,在應用沙箱內會產生對應的數據庫文件。使用數據庫的過程中,在與數據庫文件相同的目錄下可能會產生以-wal和-shm結尾的臨時文件。此時若開發(fā)者希望移動數據庫文件到其它地方使用查看,則需要同時移動這些臨時文件,當應用被卸載完成后,其在設備上產生的數據庫文件及臨時文件也會被移除。
3. 創(chuàng)建RdbUtils工具包
為了方便我們后面在UI中操作數據庫,我們在項目文件中創(chuàng)建common/rdbUtils/RdbUtils.ts文件,作為數據庫操作工具包:
代碼如下:
import relationalStore from '@ohos.data.relationalStore';
export default class RdbUtils {
private static rdbStore: relationalStore.RdbStore;
static setStore(store: relationalStore.RdbStore) {
RdbUtils.rdbStore = store;
}
static getStore(): relationalStore.RdbStore {
return RdbUtils.rdbStore;
}
}
之后,我們需要在剛才的EntryAbility中的生命周期函數onWindowStageCreat中添加RdbUtils.setStore(store),代碼如下:
const STORE_CONFIG = {
name: 'RdbTest.db', // 數據庫文件名
securityLevel: relationalStore.SecurityLevel.S1 // 數據庫安全級別
};
relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
if (err) {
console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
return;
}
console.info(`Succeeded in getting RdbStore.`);
//保存store, 方便后面我們對數據庫的操作
RdbUtils.setStore(store)
});
4. 創(chuàng)建數據庫表
通過relationalStore.getRdbStore獲得RdbStore(store)對象后 , 將其保存到我們的工具包中的靜態(tài)變量中,方便我們后面執(zhí)行創(chuàng)建數據庫的操作。
在我們的工具包代碼RdbUtils.ts文件中,添加 executeSql方法:
import relationalStore from '@ohos.data.relationalStore';
export default class RdbUtils {
...
static executeSql(sql: string): Promise<void> {
return RdbUtils.getStore().executeSql(sql);
}
...
}
RdbStore.executeSql接口說明:
executeSql(sql: string, bindArgs?: Array<ValueType>):Promise<void>
執(zhí)行包含指定參數但不返回值的SQL語句,使用Promise異步回調。
參數:
參數名 |
類型 |
必填 |
說明 |
sql |
string |
是 |
指定要執(zhí)行的SQL語句。 |
bindArgs |
Array<ValueType> |
否 |
SQL語句中參數的值。當sql參數語句完整時,該參數不填。 |
在我們UI頁面index.ets
import RdbUtils from '../common/rdbUtils/RdbUtils';
@Entry
@Component
struct Index {
build() {
Row() {
Column() {
Button('創(chuàng)建數據庫表')
.onClick(() => {
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, SALARY REAL, CODES BLOB)'; // 建表Sql語句
RdbUtils.executeSql(SQL_CREATE_TABLE)
.then(() =>{
openDialog('successfully created table')
}).catch((err) => {
openDialog(err);
})
})
}
.width('100%')
}
.height('100%')
}
}
function openDialog(text: string) {
AlertDialog.show(
{
title: 'title',
message: text,
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx: 0, dy: -20 },
}
)
}
這個代碼中,我們綁定了一個按鈕,用來點擊執(zhí)行創(chuàng)建數據庫表的操作。當執(zhí)行RdbUtils.executeSql時,將返回Promise對象,將其處理之后。通過彈窗的形式將其展示。
效果如下:
表結構說明:
這是一個SQL語句,用于在數據庫中創(chuàng)建一個名為"EMPLOYEE"的表。以下是該表的結構說明:
表名: EMPLOYEE
列名及類型:
- ID: 這是一個整數類型的列,被設置為主鍵,并且自動遞增。這意味著每次添加新記錄時,此列的值會自動增加,不允許重復。
- NAME: 這是一個文本類型的列,不允許為空。這意味著在插入或更新記錄時,必須為這一列提供值。
- AGE: 這是一個整數類型的列,可以包含任何整數值。
- SALARY: 這是一個浮點數類型的列,可以用于存儲工資或薪水的值。
- CODES: 這是一個BLOB類型的列,通常用于存儲二進制數據。它可以用于存儲代碼、數據或其他二進制格式的信息。
約束:
- 由于"ID"列被指定為主鍵,所以每個"ID"值必須是唯一的,并且不能為空。
- "NAME"列被設置為"NOT NULL",這意味著每次插入或更新記錄時,必須為這一列提供值。
5. 插入數據
在插入數據之前,需要再工具包中添加insert()方法:
import relationalStore from '@ohos.data.relationalStore';
export default class RdbUtils {
...
static insert(tableName: string, data: any): Promise<number> {
return RdbUtils.getStore().insert(tableName, data);
}
...
}
接口說明:
insert:
insert(table: string, values: ValuesBucket):Promise<number>
向目標表中插入一行數據,使用Promise異步回調。
參數:
參數名 |
類型 |
必填 |
說明 |
table |
string |
是 |
指定的目標表名。 |
values |
ValuesBucket |
是 |
表示要插入到表中的數據行。 |
返回值:
類型 |
說明 |
Promise<number> |
Promise對象。如果操作成功,返回行ID;否則返回-1。 |
之后,在我們的UI中調用RdbUtils中的insert()方法插入數據。示例代碼如下所示:、
import RdbUtils from '../common/rdbUtils/RdbUtils';
@Entry
@Component
struct Index {
build() {
Row() {
Column() {
...
Button('插入數據')
.onClick(() => {
const valueBucket = {
'NAME': 'Lisa',
'AGE': 18,
'SALARY': 100.5,
'CODES': new Uint8Array([1, 2, 3, 4, 5])
};
RdbUtils.insert('EMPLOYEE', valueBucket)
.then((updateNumber) => {
openDialog('已插入數據:' + updateNumber)
}).catch((error) => {
openDialog('error: ' + error)
})
})
...
}
.width('100%')
}
.height('100%')
}
}
...
效果如圖所示:
6. 查詢數據
查詢數據可以通過RdbStore中的query()方法執(zhí)行查詢,返回ResultSet:
接口說明:
query(predicates: RdbPredicates, columns?: Array<string>):Promise<ResultSet>
根據指定條件查詢數據庫中的數據,使用Promise異步回調。
參數:
?
參數名 |
類型 |
必填 |
說明 |
predicates |
RdbPredicates |
是 |
RdbPredicates的實例對象指定的查詢條件。 |
columns |
Array<string> |
否 |
表示要查詢的列。如果值為空,則查詢應用于所有列。 |
在我們的工具包中添加代碼:
static queryAll(): Promise<Array<Employee>> {
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
return new Promise<Array<Employee>>((resolve, reject) => {
RdbUtils.getStore().query(predicates).then((result) => {
let employees = new Array<Employee>();
while (result.goToNextRow()) {
let employee = new Employee(
result.getLong(0),
result.getString(1),
result.getLong(2),
result.getDouble(3),
result.getBlob(4)
);
employees.push(employee);
}
resolve(employees);
}).catch((error) => {
reject(error)
})
})
}
該方法將通過RdbUtils.getStore().query(predicates)獲取的結果集封裝到Employee類中,然后通過Promise進行返回。
實體類Employee:
export default class Employee {
id: number; // 員工ID
name: string; // 姓名
age: number | null; // 年齡,允許為null
salary: number | null; // 工資,允許為null
codes: Uint8Array | null; // 二進制數據,用于存儲 BLOB 類型,允許為null
constructor(id: number, name: string, age: number | null, salary: number | null, codes: Uint8Array | null) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.codes = codes;
}
}
在UI方面代碼如下:
import RdbUtils from '../common/rdbUtils/RdbUtils';
@Entry
@Component
struct Index {
build() {
Row() {
Column() {
...
Button('查詢數據')
.onClick(() => {
RdbUtils.queryAll()
.then((employees: Array<Employee>) => {
openDialog('employees: ' + JSON.stringify(employees))
}).catch((error) => {
openDialog('error' + error.toString())
})
})
...
}
.width('100%')
}
.height('100%')
}
}
...
效果圖:
7. 修改和刪除數據
接口說明:
update
update(values: ValuesBucket, predicates: RdbPredicates):Promise<number>
根據RdbPredicates的指定實例對象更新數據庫中的數據,使用Promise異步回調。
參數:
參數名 |
類型 |
必填 |
說明 |
values |
ValuesBucket |
是 |
values指示數據庫中要更新的數據行。鍵值對與數據庫表的列名相關聯。 |
predicates |
RdbPredicates |
是 |
RdbPredicates的實例對象指定的更新條件。 |
在工具包中添加:
...
static deleteById(id: number) {
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
predicates.equalTo('ID', id)
return RdbUtils.getStore().delete(predicates);
}
static updateById(id: number, data: any) {
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
predicates.equalTo('ID', id)
return RdbUtils.getStore().update(data, predicates);
}
...
這兩個方法,一個是通過id刪除數據,另一個是通過id修改數據
在UI層面:
Button('修改數據')
.onClick(() => {
const valueBucket = {
'NAME': 'Rose',
'AGE': 999,
'SALARY': 100.5,
'CODES': new Uint8Array([1, 2, 3, 4, 5])
};
RdbUtils.updateById(1, valueBucket)
.then((updateNumber) => {
openDialog('已更新數據:' + updateNumber.toString())
}).catch((err) => {
openDialog(err)
})
})
Button('刪除數據')
.onClick(() => {
RdbUtils.deleteById(1)
.then((updateNumber) => {
openDialog('已刪除數據:' + updateNumber.toString())
}).catch((err) => {
openDialog(err)
})
})
8. 刪除數據庫
調用deleteRdbStore()方法,刪除數據庫及數據庫相關文件。示例代碼如下:
?
export default class EntryAbility extends UIAbility {
...
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
relationalStore.deleteRdbStore(this.context, 'RdbTest.db', (err) => {
if (err) {
console.error(`Failed to delete RdbStore. Code:${err.code}, message:${err.message}`);
return;
}
console.info('Succeeded in deleting RdbStore.');
});
}
....
}
這里我在EntryAbility中的onDestroy生命周期函數中調用了刪除數據庫的操作,這意味著當我們的Ability被銷毀的時候,自動將數據庫刪除。
接口說明:
relationalStore.deleteRdbStore
deleteRdbStore(context: Context, name: string, callback: AsyncCallback<void>): void
刪除數據庫,使用callback異步回調。
參數:
參數名 |
類型 |
必填 |
說明 |
context |
Context |
是 |
應用的上下文。 FA模型的應用Context定義見Context。 Stage模型的應用Context定義見Context。 |
name |
string |
是 |
數據庫名稱。 |
callback |
AsyncCallback<void> |
是 |
指定callback回調函數文章來源地址http://www.zghlxwxcb.cn/news/detail-793160.html |
到了這里,關于Harmony鴻蒙應用開發(fā)——關系型數據庫(RelationalStore)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!