移动端开发,数据存储是非常重要的,鸿蒙也不例外,说到数据存储,首要的就是数据库了,数据库的存储机制是否完善,提供的功能是否简单方便,直接影响开发者的开发速度和性能。
作为鸿蒙开发者,最近就深入学习了鸿蒙的数据库知识点,了解了存储机制并且尝试了使用,发现鸿蒙的数据库真的做到了应有尽有,操作还简单的地步。
鸿蒙关系型数据库
先来看看鸿蒙的关系型数据库(relational database,rdb)概念。
鸿蒙的 rdb 是一种基于关系模型来管理数据的数据库。harmonyos 关系型数据库基于 sqlite 组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查接口,也可以直接运行用户输入的 sql 语句来满足复杂的场景需要。
harmonyos 提供的关系型数据库功能更加完善,查询效率更高。
概念中一句话很重要,harmonyos 提供的关系型数据库功能更加完善,查询效率更高。
看到这里我当时是非常激动的,作为开发者难道不是最希望使用的 api 在什么情况下都适用吗?
下面看看鸿蒙数据库的运作机制,了解机制才能了解数据库开发的核心,也有利于扩展。
运作机制
harmonyos 关系型数据库对外提供通用的操作接口,底层使用 sqlite 作为持久化存储引擎,支持 sqlite 具有的所有数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译 sql 语句。
看到上面的鸿蒙数据库的运行机制不难发现,主要工作还是在 framework 层做的封装,然后调用 jni,使用的还是 sqlite 组件。
不管底层怎么做的开发,只要功能完善,体验到位,鸿蒙应用端直接使用不是很香吗?
约束与限制
①数据库中连接池的最大数量是 4 个,用以管理用户的读写操作。
连接池的数量是有限制的 ,最大时 4 个,不过 4 个已经足够使用了。
②为保证数据的准确性,数据库同一时间只能支持一个写操作。
同一时间支持一个写操作时非常重要的,为了防止数据存储的正确性,鸿蒙做了这一个限制,但是作为多年的移动端开发者,一般这种多操作或者大数据操作,都会使用多线程,异步线程,或者放在线程池中,这样就更完美了。
数据库操作 dataability
鸿蒙在创建类的时候有一个 dataability,不知道各位开发者使用过了没,其实这个就是为了数据库操作而来的。
添加步骤很简单:添加类的时候选择 empty dataability 即可。
①配置
添加类后,会自动生成如下配置:
{
“permissions”: [
“com.huawei.codelab.dataabilityshellprovider.provider”
],
“name”: “com.hadiidbouk.databasemanager.database.dataability”,
“icon”: “$media:icon”,
“description”: “$string:dataability_description”,
“type”: “data”,
“uri”: “dataability://com.huawei.codelab.persondataability”
}
操作数据库需要权限信息:
“permissions”: [
“com.huawei.codelab.dataabilityshellprovider.provider”
]
需要配置 url,url 很重要,在进行数据库表操作的时候需要保持一致。
②dataability 操作内容
默认创建的 dataability 类会自动重写 数据库的增,删,改,查 几种操作的函数。
可以看下面:
添加 dataability 会自动重写四个接口函数,有关数据库的增,删,改,查。
该 dataability 在运行项目后会自行执行 onstart 方法进行数据库及其数据表的创建工作。
通过 rdbpredicates 数据库进行数据库关系的关联进行操作。
public class dataability extends ability {
private static final hiloglabel label_log = new hiloglabel(3, 0xd001100, “demo”);
private static final string db_name = “persondataability.db”;
private static final string db_tab_name = “person”;
private static final string db_column_person_id = “id”;
private static final string db_column_name = “name”;
private static final string db_column_gender = “gender”;
private static final string db_column_age = “age”;
private static final int db_version = 1;
private storeconfig config = storeconfig.newdefaultconfig(db_name);
private rdbstore rdbstore;
private rdbopencallback rdbopencallback = new rdbopencallback() {
@override
public void oncreate(rdbstore store) {
store.executesql(“create table if not exists ”
+ db_tab_name + “ (”
+ db_column_person_id + “ integer primary key, ”
+ db_column_name + “ text not null, ”
+ db_column_gender + “ text not null, ”
+ db_column_age + “ integer)”);
}
@override
public void onupgrade(rdbstore store, int oldversion, int newversion) {
}
};
@override
public void onstart(intent intent) { //创建数据库操作
super.onstart(intent);
hilog.info(label_log, “dataability onstart”);
databasehelper databasehelper = new databasehelper(this);
rdbstore = databasehelper.getrdbstore(config, db_version, rdbopencallback, null);
}
// 数据库 查询操作
@override
public resultset query(uri uri, string[] columns, dataabilitypredicates predicates) {
rdbpredicates rdbpredicates = dataabilityutils.createrdbpredicates(predicates, db_tab_name);
resultset resultset = rdbstore.query(rdbpredicates, columns);
if (resultset == null) {
hilog.info(label_log, “resultset is null”);
}
return resultset;
}
// 数据库 插入操作
@override
public int insert(uri uri, valuesbucket value) {
hilog.info(label_log, “dataability insert”);
string path = uri.getlastpath();
if (!“person”.equals(path)) {
hilog.info(label_log, “dataability insert path is not matched”);
return -1;
}
valuesbucket values = new valuesbucket();
values.putinteger(db_column_person_id, value.getinteger(db_column_person_id));
values.putstring(db_column_name, value.getstring(db_column_name));
values.putstring(db_column_gender, value.getstring(db_column_gender));
values.putinteger(db_column_age, value.getinteger(db_column_age));
int index = (int) rdbstore.insert(db_tab_name, values);
dataabilityhelper.creator(this, uri).notifychange(uri);
return index;
}
// 数据库 删除操作
@override
public int delete(uri uri, dataabilitypredicates predicates) {
rdbpredicates rdbpredicates = dataabilityutils.createrdbpredicates(predicates, db_tab_name);
int index = rdbstore.delete(rdbpredicates);
hilog.info(label_log, “delete: ” + index);
dataabilityhelper.creator(this, uri).notifychange(uri);
return index;
}
// 数据库 更新操作
@override
public int update(uri uri, valuesbucket value, dataabilitypredicates predicates) {
rdbpredicates rdbpredicates = dataabilityutils.createrdbpredicates(predicates, db_tab_name);
int index = rdbstore.update(value, rdbpredicates);
hilog.info(label_log, “update: ” + index);
dataabilityhelper.creator(this, uri).notifychange(uri);
return index;
}
@override
public filedescriptor openfile(uri uri, string mode) {
return null;
}
@override
public string[] getfiletypes(uri uri, string mimetypefilter) {
return new string[0];
}
@override
public pacmap call(string method, string arg, pacmap extras) {
return null;
}
@override
public string gettype(uri uri) {
return null;
}
}
③数据库操作
这里的数据库操作时,开发需求做的数据库操作,可以通过自己的需求来开发数据库的调用操作,最终还是通过使用 dataability 直接调用系统的数据库。
public class databaseabilityslice extends abilityslice {
private static final hiloglabel label_log = new hiloglabel(3, 0xd001100, “demo”);
private dataabilityhelper databasehelper;
private static final string base_uri = “dataability:///com.huawei.codelab.persondataability”;
private static final string data_path = “/person”;
private static final string db_column_person_id = “id”;
private static final string db_column_name = “name”;
private static final string db_column_gender = “gender”;
private static final string db_column_age = “age”;
@override
public void onstart(intent intent) {
super.onstart(intent);
super.setuicontent(resourcetable.layout_ability_data_base);
databasehelper = dataabilityhelper.creator(this);
text text = (text)findcomponentbyid(resourcetable.id_text_helloworld);
text.setclickedlistener(new component.clickedlistener() {
@override
public void onclick(component component) {
query();
insert(100, “tom”, “male”, 20);
insert(101, “jerry”, “female”, 21);
insert(102, “bob”, “male”, 22);
query(); // 查看插入后的结果
update();
query(); // 查看更新后的结果
delete();
query(); // 查看删除后的结果
}
});
}
@override
public void onactive() {
super.onactive();
}
@override
public void onforeground(intent intent) {
super.onforeground(intent);
}
private void insert(int id, string name, string gender, int age) {
valuesbucket valuesbucket = new valuesbucket();
valuesbucket.putinteger(db_column_person_id, id);
valuesbucket.putstring(db_column_name, name);
valuesbucket.putstring(db_column_gender, gender);
valuesbucket.putinteger(db_column_age, age);
try {
if (databasehelper.insert(uri.parse(base_uri + data_path), valuesbucket) != -1) {
// if (databasehelper.insert(uri.parse(base_uri + data_path), valuesbucket) != -1) {
hilog.info(label_log, “insert successful”);
}
} catch (dataabilityremoteexception | illegalstateexception exception) {
hilog.error(label_log, “insert: dataremote exception|illegalstateexception”);
}
}
private void delete() {
dataabilitypredicates predicates = new dataabilitypredicates()
.equalto(db_column_person_id, 100);
try {
if (databasehelper.delete(uri.parse(base_uri + data_path), predicates) != -1) {
hilog.info(label_log, “delete successful”);
}
} catch (dataabilityremoteexception | illegalstateexception exception) {
hilog.error(label_log, “delete: dataremote exception | illegalstateexception”);
}
}
private void update() {
dataabilitypredicates predicates = new dataabilitypredicates();
predicates.equalto(db_column_person_id, 102);
valuesbucket valuesbucket = new valuesbucket();
valuesbucket.putstring(db_column_name, “zhangsanplus”);
valuesbucket.putinteger(db_column_age, 28);
try {
if (databasehelper.update(uri.parse(base_uri + data_path), valuesbucket, predicates) != -1) {
hilog.info(label_log, “update successful”);
}
} catch (dataabilityremoteexception | illegalstateexception exception) {
hilog.error(label_log, “update: dataremote exception | illegalstateexception”);
}
}
private void query() {
string[] columns = new string[] {db_column_person_id,
db_column_name, db_column_gender, db_column_age};
// 构造查询条件
dataabilitypredicates predicates = new dataabilitypredicates();
predicates.between(db_column_age, 15, 40); // 查询时间段
try {
resultset resultset = databasehelper.query(uri.parse(base_uri + data_path),
columns, predicates);
if (resultset == null || resultset.getrowcount() == 0) {
hilog.info(label_log, “query: resultset is null or no result found”);
return;
}
resultset.gotofirstrow();
do {
int id = resultset.getint(resultset.getcolumnindexforname(db_column_person_id));
string name = resultset.getstring(resultset.getcolumnindexforname(db_column_name));
string gender = resultset.getstring(resultset.getcolumnindexforname(db_column_gender));
int age = resultset.getint(resultset.getcolumnindexforname(db_column_age));
hilog.info(label_log, “query: id :” + id + “ name :” + name + “ gender :” + gender + “ age :” + age);
} while (resultset.gotonextrow());
} catch (dataabilityremoteexception | illegalstateexception exception) {
hilog.error(label_log, “query: dataremote exception | illegalstateexception”);
}
}
}
数据插入使用对象类 valuesbucket;使用 dataabilitypredicates 实例进行数据查询的条件设置。
到此有关数据库的关系型数据库操作基本就完成了,是不是非常,非常简单,可以直接拿来主义验证一下。
2019中国物联网CEO千人大会在苏州国际金鸡湖会议中心隆重举办
中国雷达市场两倍于国际增长,汽车电子传统供应链模式受挑战!
步进电机控制器和驱动器功能区别
生物传感器助力血糖监测行业变革
双工器隔离度怎么测 双工器的工作原理分析
鸿蒙的数据库知识点学习
无缝拼接屏能做到没有拼缝吗
怎样取出iPhone里的SIM卡
嵌入式必懂的CAN总线讲解
2022年有哪些好用的蓝牙耳机推荐?盘点四款实用的蓝牙耳机
贴片Y电容1206的特性、用途以及选购建议
曙光计算服务助力山大创新 雷蛇推出生产力系列三款新产品
深度学习技术与自动驾驶设计的结合
罗奇泰克:加快智能化全自动流水线生产,力争完成工业产值6亿元以上
厉害了!《撩妹日记VR:天堂岛》除了嘿嘿啥都行
车规级IGBT延续高景气度,国内品牌2023年前难挑大梁
普通市民怎样在比特币上投资
滨松新的指尖大小的小型光谱仪即将开启新应用
高压功率放大器ATA-7020基于液晶生物光电传感器中的应用
M2M无线医疗在医院中的应用