HarmonyOS 使用關系型數據庫進行增刪改查
HarmonyOS 中的關系型數據庫基于 SQLite 組件,提供了一套完整的對本地數據庫進行管理的機制。它支持事務、索引、視圖、觸發器、外鍵、參數化查詢和預編譯 SQL 語句等特性。關系型數據庫適用于存儲包含復雜關系數據的場景,例如學生信息或雇員信息,這些數據之間有較強的對應關系。
操作關系型數據庫的常見步驟
-
創建數據庫和表:使用 relationalStore.getRdbStore 方法創建數據庫,然后使用 executeSql 方法執行 SQL 語句來創建表。
-
插入數據:使用 insert 方法向表中插入數據。
-
批量插入數據:使用 batchInsert 方法向表中插入一組數據。
-
更新數據:使用 update 方法根據指定條件更新數據庫中的數據。
-
刪除數據:使用 delete 方法根據指定條件從數據庫中刪除數據。
-
查詢數據:使用 query 方法根據指定條件查詢數據庫中的數據。
此外,HarmonyOS 還提供了 ResultSet 對象來訪問查詢結果,提供靈活的數據訪問方式。
表的數據模型
定義Person類,作為數據模型,用于表示數據庫中的Person表的行。
// 常量類配置信息
export class Person {
id: number
name: string
age: number
constructor(id: number, name: string, age: number) {
this.id = id
this.name = name
this.age = age
}
}
數據庫配置信息
首先,定義數據庫和表的配置信息,包括數據庫名稱、安全級別、表名稱、創建表的SQL語句和列配置。
/**
* Rdb數據庫配置。
* name:數據庫名稱
* securityLevel:數據庫安全級別
*/
static readonly STORE_CONFIG: relationalStore.StoreConfig = {
name: 'database.db',
securityLevel: relationalStore.SecurityLevel.S1
};
/**
* 表配置信息
* tableName:表名稱
* sqlCreate:創建表的語句
* columns:表的列項目
*/
static readonly PERSON_TABLE: PersonTable = {
tableName: 'personTable',
sqlCreate: 'CREATE TABLE IF NOT EXISTS personTable(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, ' +
'age INTEGER)',
columns: ['id', 'name', 'age']
};
/**
* Log tag.
*/
static readonly RDB_TAG = '[Debug.Rdb]';
static readonly TABLE_TAG = '[Debug.PersonTable]';
static readonly INDEX_TAG = '[Debug.Index]';
封裝CRUD操作
封裝了對關系型數據庫(RDB)的一些基本操作,如創建、插入、刪除、更新和查詢數據。這個類使用了 @ohos.data.relationalStore 包。
import relationalStore from '@ohos.data.relationalStore';
import CommonConstants from '../constants/CommonConstants';
import Logger from '../utils/Logger';
export default class Rdb {
private rdbStore: relationalStore.RdbStore | null = null;
private tableName: string;
private sqlCreateTable: string;
private columns: Array<string>;
constructor(tableName: string, sqlCreateTable: string, columns: Array<string>) {
this.tableName = tableName;
this.sqlCreateTable = sqlCreateTable;
this.columns = columns;
}
getRdbStore(callback: Function = () => {
}) {
if (!callback || typeof callback === 'undefined' || callback === undefined) {
Logger.info(CommonConstants.RDB_TAG, 'getRdbStore() has no callback!');
return;
}
if (this.rdbStore !== null) {
Logger.info(CommonConstants.RDB_TAG, 'The rdbStore exists.');
callback();
return
}
let context: Context = getContext(this) as Context;
relationalStore.getRdbStore(context, CommonConstants.STORE_CONFIG, (err, rdb) => {
if (err) {
Logger.error(CommonConstants.RDB_TAG, `gerRdbStore() failed, err: ${err}`);
return;
}
this.rdbStore = rdb;
this.rdbStore.executeSql(this.sqlCreateTable);
Logger.info(CommonConstants.RDB_TAG, 'getRdbStore() finished.');
callback();
});
}
insertData(data: relationalStore.ValuesBucket, callback: Function = () => {
}) {
if (!callback || typeof callback === 'undefined' || callback === undefined) {
Logger.info(CommonConstants.RDB_TAG, 'insertData() has no callback!');
return;
}
let resFlag: boolean = false;
const valueBucket: relationalStore.ValuesBucket = data;
if (this.rdbStore) {
this.rdbStore.insert(this.tableName, valueBucket, (err, ret) => {
if (err) {
Logger.error(CommonConstants.RDB_TAG, `insertData() failed, err: ${err}`);
callback(resFlag);
return;
}
Logger.info(CommonConstants.RDB_TAG, `insertData() finished: ${ret}`);
callback(ret);
});
}
}
deleteData(predicates: relationalStore.RdbPredicates, callback: Function = () => {
}) {
if (!callback || typeof callback === 'undefined' || callback === undefined) {
Logger.info(CommonConstants.RDB_TAG, 'deleteData() has no callback!');
return;
}
let resFlag: boolean = false;
if (this.rdbStore) {
this.rdbStore.delete(predicates, (err, ret) => {
if (err) {
Logger.error(CommonConstants.RDB_TAG, `deleteData() failed, err: ${err}`);
callback(resFlag);
return;
}
Logger.info(CommonConstants.RDB_TAG, `deleteData() finished: ${ret}`);
callback(!resFlag);
});
}
}
updateData(predicates: relationalStore.RdbPredicates, data: relationalStore.ValuesBucket, callback: Function = () => {
}) {
if (!callback || typeof callback === 'undefined' || callback === undefined) {
Logger.info(CommonConstants.RDB_TAG, 'updateDate() has no callback!');
return;
}
let resFlag: boolean = false;
const valueBucket: relationalStore.ValuesBucket = data;
if (this.rdbStore) {
this.rdbStore.update(valueBucket, predicates, (err, ret) => {
if (err) {
Logger.error(CommonConstants.RDB_TAG, `updateData() failed, err: ${err}`);
callback(resFlag);
return;
}
Logger.info(CommonConstants.RDB_TAG, `updateData() finished: ${ret}`);
callback(!resFlag);
});
}
}
query(predicates: relationalStore.RdbPredicates, callback: Function = () => {
}) {
if (!callback || typeof callback === 'undefined' || callback === undefined) {
Logger.info(CommonConstants.RDB_TAG, 'query() has no callback!');
return;
}
if (this.rdbStore) {
this.rdbStore.query(predicates, this.columns, (err, resultSet) => {
if (err) {
Logger.error(CommonConstants.RDB_TAG, `query() failed, err: ${err}`);
return;
}
Logger.info(CommonConstants.RDB_TAG, 'query() finished.');
callback(resultSet);
resultSet.close();
});
}
}
}
具體表操作封裝
使用了之前定義的 Rdb 類來執行具體的Person數據庫操作。
import relationalStore from '@ohos.data.relationalStore';
import CommonConstants from '../../constants/CommonConstants';
import Rdb from '../rdb';
import { Person } from '../../bean/Person';
export default class PersonTable {
private accountTable = new Rdb(CommonConstants.PERSON_TABLE.tableName, CommonConstants.PERSON_TABLE.sqlCreate,
CommonConstants.PERSON_TABLE.columns);
constructor(callback: Function = () => {
}) {
this.accountTable.getRdbStore(callback);
}
getRdbStore(callback: Function = () => {
}) {
this.accountTable.getRdbStore(callback);
}
insert(person: Person, callback: Function) {
const valueBucket: relationalStore.ValuesBucket = generateBucket(person);
this.accountTable.insertData(valueBucket, callback);
}
deleteData(person: Person, callback: Function) {
let predicates = new relationalStore.RdbPredicates(CommonConstants.PERSON_TABLE.tableName);
predicates.equalTo('id', person.id);
this.accountTable.deleteData(predicates, callback);
}
updateData(person: Person, callback: Function) {
const valueBucket: relationalStore.ValuesBucket = generateBucket(person);
let predicates = new relationalStore.RdbPredicates(CommonConstants.PERSON_TABLE.tableName);
predicates.equalTo('id', person.id);
this.accountTable.updateData(predicates, valueBucket, callback);
}
// 查(查詢的字段,回調,是否查詢全部)
query(id: number, callback: Function, isAll: boolean = true) {
let predicates = new relationalStore.RdbPredicates(CommonConstants.PERSON_TABLE.tableName);
if (!isAll) {
predicates.equalTo('id', id);
}
this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
let count: number = resultSet.rowCount;
if (count === 0 || typeof count === 'string') {
console.log(`${CommonConstants.TABLE_TAG}` + 'Query no results!');
callback([]);
} else {
resultSet.goToFirstRow();
const result: Person[] = [];
for (let i = 0; i < count; i++) {
let tmp: Person = {
id: 0, name: '', age: 0
};
tmp.id = resultSet.getDouble(resultSet.getColumnIndex('id'));
tmp.name = resultSet.getString(resultSet.getColumnIndex('name'));
tmp.age = resultSet.getDouble(resultSet.getColumnIndex('age'));
result[i] = tmp;
resultSet.goToNextRow();
}
callback(result);
}
});
}
}
function generateBucket(person: Person): relationalStore.ValuesBucket {
let obj: relationalStore.ValuesBucket = {};
obj.name = person.name;
obj.age = person.age;
return obj;
}
使用示例
以下是如何使用上述封裝的CRUD操作的示例。
insertPerson() {
this.newPerson =
new Person(
0,
CommonConstants.NAMES[Math.floor(Math.random() * CommonConstants.NAMES.length)] + '某',
Math.floor(Math.random() * 99
))
this.PersonTable.insert(this.newPerson, (id: number) => {
this.newPerson.id = id;
Logger.info(TAG, `id = ${id}`);
this.persons.push(this.newPerson)
});
}
queryAllPerson() {
this.PersonTable.getRdbStore(() => {
this.PersonTable.query(0, (result: Person[]) => {
this.persons.length = 0;
this.persons = result;
Logger.info(TAG, "persons = " + JSON.stringify(this.persons))
}, true);
});
}
updatePerson(item: Person, index: number) {
// 修改數據
this.newPerson = { ...item,
name: CommonConstants.NAMES[Math.floor(Math.random() * CommonConstants.NAMES.length)] + '某',
age: Math.floor(Math.random() * 99) }
this.PersonTable.updateData(this.newPerson, () => {
})
//替換
this.persons.splice(index, 1, this.newPerson)
}
deletePerson(item: Person, index: number) {
this.PersonTable.deleteData(item, () => {
this.persons.splice(index, 1)
})
}
結語
通過封裝CRUD操作,可以顯著提高代碼的可讀性和可維護性。同時,它也簡化了數據庫操作的復雜性,使得開發者可以更專注于業務邏輯的實現。

浙公網安備 33010602011771號