HarmonyOS之sqlite数据库的使用
从API Version 9开始,鸿蒙开发中sqlite使用新接口@ohos.data.relationalStore
但是 relationalStore在 getRdbStore操作时,在预览模式运行或者远程模拟器运行都会报错,导致无法使用。查了一圈说只有在真机上可以正常使用,因此这里暂且使用 @ohos.data.rdb
二者的接口非常相似,会使用了ohos.data.rdb,自然也会使用ohos.data.relationalStore
在harmonyos开发中,操作数据库时,我们通常习惯将一个功能模块数据库操作全部写在一个ets文件中并export,在界面文件中直接导入使用。
1.数据库配置以及建表
新建userDb.ets文件并添加以下代码
import data_rdb from '@ohos.data.rdb'
const STORE_CONFIG = {name: "test.db"}
const TAB_USER = "user"
const CREATE_TABLE_CODE = "CREATE TABLE IF NOT EXISTS "+TAB_USER+" ("+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "+ "name TEXT , "+ "age TEXT , "+ "sex TEXT ) "
export function createTable(context) {data_rdb.getRdbStore(context,STORE_CONFIG, 1, function (err, rdbStore) {rdbStore.executeSql(CREATE_TABLE_CODE)console.info('create table done.')})
}
在User.ets界面导入并调用
import {createTable} from '../utils/userDb'aboutToAppear() {createTable(getContext(this))
}
2.插入数据
userDb.ets文件添加 insertData方法,这里需要注意的是promise的用法,因为需要将执行结果返回界面,所以方法里面多次使用了Promise来返回结果
插入的字段要和数据库字段保持一致。
export function insertData(context,list):any{const promise = data_rdb.getRdbStore(context,STORE_CONFIG, 1)return promise.then(async (rdbStore) => {let arr:any = [];for(let i:number=0; i<list.length; i++){const obj = list[i]const item ={name: obj.name,age: obj.age,sex: obj.sex}rdbStore.insert(TAB_USER, item);}console.log('--start')console.log('完了')return true;})
}
在User.ets界面导入并调用
import {insertData} from '../utils/userDb'addData(){let array = [];for(let i=0; i<20; i++){array.push({name:'张飞'+i,age: 20+i,sex: '男'})}insertData(getContext(this), array).then(res=>{if(res){this.loading = falsethis.showDialog('添加成功')this.search(true)}})}
3.查询
userDb.ets文件添加 queryDataPage方法,这里用了分页查询的方式,还有一种谓词的查询方式请参考官方文档。
export function queryDataPage(context,param):any {let promise = data_rdb.getRdbStore(context, STORE_CONFIG, 1)return promise.then(async (rdbStore) => {const sql: string = "select * from "+TAB_USER+" where name like ? " +"order by id asc limit ? OFFSET ? ";console.log('----sql---', sql)const pS = param.pageSizeconst page = param.pageconsole.log('param.code', param.code)console.log('pS', pS)console.log('(page-1)*pS', (page - 1) * pS)// param.code,pS,(page-1)*pS]let promisequery = rdbStore.querySql(sql, [param.code, pS, (page - 1) * pS])return promisequery.then(async (resultSet) => {const rowCount = resultSet.rowCount;let list = [];console.log("rowCount --" + rowCount)resultSet.goToFirstRow();for (let i = 0; i < rowCount; i++) {const name = resultSet.getString(resultSet.getColumnIndex("NAME"))const age = resultSet.getString(resultSet.getColumnIndex("AGE"))const sex = resultSet.getString(resultSet.getColumnIndex("SEX"))const id = resultSet.getString(resultSet.getColumnIndex("ID"))resultSet.goToNextRow();const data = {name,id,age,sex,}list.push(data);}resultSet.close();console.log('--array--', list.length)return list;})}).catch((err) => {console.log("Get RdbStore failed, err: " + err)})
}
在User.ets界面导入并调用
import {queryDataPage} from '../utils/userDb'@State list:Array<any> = []@State keyword:string = ""@State page:number = 1@State pageSize:number = 20
search(firstPage:boolean){if(firstPage){this.page = 1}const params = {code: '%'+this.keyword+'%',page: this.page,pageSize: this.pageSize,}queryDataPage(getContext(this), params).then(data=>{if(data){console.log('res',JSON.stringify(data));if(this.page == 1){this.list = data} else {this.list = this.list.concat(data);}}})}
4.更新数据
userDb.ets文件添加 updateData方法
export function updateData(context,newInfo):any{const promise = data_rdb.getRdbStore(context,STORE_CONFIG, 1)return promise.then(async (rdbStore) => {let predicates = new data_rdb.RdbPredicates(TAB_USER);predicates.equalTo("id", newInfo.id)let promiseUp = rdbStore.update(newInfo, predicates)return promiseUp.then(async (rows) => {if(rows == 1){return true}}).catch((err) => {console.info("Updated failed, err: " + err)return false})})
}
在User.ets界面导入并调用
import {updateData} from '../utils/userDb'updateOne(item:any){item.name = '张飞111'updateData(getContext(this), item).then(res=>{if(res){this.showDialog('更新成功')this.search(true)}})}
5.删除数据
userDb.ets文件添加 deleteOneData方法
export function deteteOneData(context,id):any{const promise = data_rdb.getRdbStore(context,STORE_CONFIG, 1)return promise.then(async (rdbStore) => {let predicates = new data_rdb.RdbPredicates(TAB_USER);predicates.equalTo("id", id)const result = rdbStore.delete(predicates);console.log('--result--'+JSON.stringify(result))return true;})
}
在User.ets界面导入并调用
import {deteteOneData} from '../utils/userDb'deleteOne(id:string){deteteOneData(getContext(this), id).then(res=>{if(res){this.showDialog('删除成功')this.search(true)}})}
6.界面效果
点击右上角Add按钮,插入数据;
点击删除按钮,删除一条数据;
点击编辑按钮,将该条数据姓名字段更新为 马超000。

7.完整代码
界面文件 User.ets
import {createTable,insertData,deteteOneData,updateData,queryDataPage} from '../utils/userDb'
@Entry
@Component
struct User {controller: SearchController = new SearchController()@State codeList:Array<any> = [];@State list:Array<any> = [];@State loading:boolean = false;@State keyword:string = "";@State page:number = 1;@State pageSize:number = 20;aboutToAppear() {createTable(getContext(this))}onReachEnd(){console.log('--------onReachEnd---');//this.page = this.page+1this.search(false)}search(firstPage:boolean){if(firstPage){this.page = 1}const params = {code: '%'+this.keyword+'%',page: this.page,pageSize: this.pageSize,}queryDataPage(getContext(this), params).then(data=>{if(data){console.log('res',JSON.stringify(data));if(this.page == 1){this.list = data} else {this.list = this.list.concat(data);}}})}addData(){let array = [];for(let i=0; i<20; i++){array.push({name:'张飞'+i,age: 20+i,sex: '男'})}insertData(getContext(this), array).then(res=>{if(res){this.loading = falsethis.showDialog('添加成功')this.search(true)}})}deleteOne(id:string){deteteOneData(getContext(this), id).then(res=>{if(res){this.showDialog('删除成功')this.search(true)}})}updateOne(item:any){item.name = '马超000'updateData(getContext(this), item).then(res=>{if(res){this.showDialog('更新成功')this.search(true)}})}showDialog(text:string){AlertDialog.show({title: '提示',message: text,autoCancel: true,alignment: DialogAlignment.Center,gridCount: 4,offset: { dx: 0, dy: -20 },primaryButton: {value: '确定',action: () => {console.info('Callback when the first button is clicked')}},})}toAddData(){AlertDialog.show({title: '提示',message: '确定要添加数据吗',autoCancel: true,alignment: DialogAlignment.Center,offset: { dx: 0, dy: -20 },gridCount: 5,primaryButton: {value: '确定',action: () => {console.info('确定 is clicked')this.loading = truethis.addData()}},secondaryButton: {value: '取消',action: () => {console.info('取消 is clicked')}},cancel: () => {console.info('Closed callbacks')}})}@Builder NavigationMenus() {Row() {Text("Add").width(32).height(28).onClick(()=>this.toAddData())}}@Builder buildList(){Row(){Text('姓名')Text('年龄')Text('性别')Text('操作')}.justifyContent(FlexAlign.SpaceAround).width('100%').padding({top:5,bottom: 10})List({ space: 20, initialIndex: 0 }) {ForEach(this.list, (item) => {ListItem() {Row(){Text(item.name)Text(item.age)Text(item.sex)Row(){Text('删除').onClick(()=>{this.deleteOne(item.id)}).fontColor(Color.Red).margin({right:5})Text('编辑').onClick(()=>{this.updateOne(item)}).fontColor(Color.Blue)}}.justifyContent(FlexAlign.SpaceAround).width('100%')}.editable(true)}, item => item.name)}.onScrollIndex((firstIndex: number, lastIndex: number) => {//console.info('first' + firstIndex)//console.info('last' + lastIndex)}).onReachEnd(()=>{this.onReachEnd()}).listDirection(Axis.Vertical) // 排列方向.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.None) // 滑动到边缘无效果.chainAnimation(false) // 联动特效关闭.width('100%')}@Builder buildSearch(){Search({ value: this.keyword, placeholder: '请输入姓名...', controller: this.controller }).searchButton('搜索').width('100%').height(40).backgroundColor('#F5F5F5').placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).textFont({ size: 14, weight: 400 }).onSubmit((value: string) => {console.log('---999')//this.submitValue = valuethis.keyword = valuethis.search(true)}).onChange((value: string) => {this.keyword = value})}build() {Column(){Navigation() {Column(){this.buildSearch()if(this.loading){Column(){LoadingProgress().color(Color.Blue)}.width('40%').height('40%')}this.buildList()}.height('100%')}.title("用户管理").menus(this.NavigationMenus).titleMode(NavigationTitleMode.Mini)}.height('100%')}
}
数据操作文件 userDb.ets
import data_rdb from '@ohos.data.rdb'
const STORE_CONFIG = {name: "test.db"}
const TAB_USER = "user"
const CREATE_TABLE_CODE = "CREATE TABLE IF NOT EXISTS "+TAB_USER+" ("+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "+ "name TEXT , "+ "age TEXT , "+ "sex TEXT ) "
export function createTable(context) {data_rdb.getRdbStore(context,STORE_CONFIG, 1, function (err, rdbStore) {rdbStore.executeSql(CREATE_TABLE_CODE)console.info('create table done.')})
}
export function updateData(context,newInfo):any{const promise = data_rdb.getRdbStore(context,STORE_CONFIG, 1)return promise.then(async (rdbStore) => {let predicates = new data_rdb.RdbPredicates(TAB_USER);predicates.equalTo("id", newInfo.id)let promiseUp = rdbStore.update(newInfo, predicates)return promiseUp.then(async (rows) => {if(rows == 1){return true}}).catch((err) => {console.info("Updated failed, err: " + err)return false})})
}
export function insertData(context,list):any{const promise = data_rdb.getRdbStore(context,STORE_CONFIG, 1)return promise.then(async (rdbStore) => {let arr:any = [];for(let i:number=0; i<list.length; i++){const obj = list[i]const item ={name: obj.name,age: obj.age,sex: obj.sex}rdbStore.insert(TAB_USER, item);}console.log('--start')console.log('完了')return true;})
}
export function deteteOneData(context,id):any{const promise = data_rdb.getRdbStore(context,STORE_CONFIG, 1)return promise.then(async (rdbStore) => {let predicates = new data_rdb.RdbPredicates(TAB_USER);predicates.equalTo("id", id)const result = rdbStore.delete(predicates);console.log('--result--'+JSON.stringify(result))return true;})
}
export function detelteAllCode(context){data_rdb.getRdbStore(context,STORE_CONFIG, 1, function (err, rdbStore) {rdbStore.executeSql("delete from "+TAB_USER)console.info('--delete code done.')})}
export function queryDataPage(context,param):any {let promise = data_rdb.getRdbStore(context, STORE_CONFIG, 1)return promise.then(async (rdbStore) => {const sql: string = "select * from "+TAB_USER+" where name like ? " +"order by id asc limit ? OFFSET ? ";console.log('----sql---', sql)const pS = param.pageSizeconst page = param.pageconsole.log('param.code', param.code)console.log('pS', pS)console.log('(page-1)*pS', (page - 1) * pS)// param.code,pS,(page-1)*pS]let promisequery = rdbStore.querySql(sql, [param.code, pS, (page - 1) * pS])return promisequery.then(async (resultSet) => {const rowCount = resultSet.rowCount;let list = [];console.log("rowCount --" + rowCount)resultSet.goToFirstRow();for (let i = 0; i < rowCount; i++) {const name = resultSet.getString(resultSet.getColumnIndex("NAME"))const age = resultSet.getString(resultSet.getColumnIndex("AGE"))const sex = resultSet.getString(resultSet.getColumnIndex("SEX"))const id = resultSet.getString(resultSet.getColumnIndex("ID"))resultSet.goToNextRow();const data = {name,id,age,sex,}list.push(data);}resultSet.close();console.log('--array--', list.length)return list;})}).catch((err) => {console.log("Get RdbStore failed, err: " + err)})
}
相关文章:
HarmonyOS之sqlite数据库的使用
从API Version 9开始,鸿蒙开发中sqlite使用新接口ohos.data.relationalStore 但是 relationalStore在 getRdbStore操作时,在预览模式运行或者远程模拟器运行都会报错,导致无法使用。查了一圈说只有在真机上可以正常使用,因此这里…...
网络抓包命令tcpdump
网络抓包命令tcpdump "tcpdump -i any -nn -vv tcp port 9095 -s 0 -w dump.cap"命令是一个网络抓包命令,用于捕获流经指定网络接口的TCP协议、端口号为9095的网络数据包,并将这些数据包写入到名为"dump.cap"的文件中。 具体参数解…...
iTMSTransporter上传ipa文件
背景 uni-app云打包之后生成的ipa包需要上传到app store上,applicationloader和香蕉云编都收费,转用iTMSTransporter上传 环境:mac 第1步 选择安装目录 xcode-select --switch /Applications/Xcode.app/Contents/Developer第2步 下载 xcru…...
2024华数杯国际数学建模A题思路模型详解
2024华数杯国际数学建模A题思路论文:1.17上午第一时间持续更新,详细内容见文末名片 建立一个模型来描述放射性废水在海水中的扩散速率和方向,考虑到涉及的物理过程和环境因素的复杂性,我们通常会使用一个简化的扩散模型作为起点…...
JS-定时器-间歇函数(一)
• 定时器函数介绍 定时器函数在开发中的使用场景 网页中经常会需要一种功能:每隔一段时间需要自动执行一段代码,不需要我们手动去触发例如:网页中的倒计时要实现这种需求,需要定时器函数定时器函数有两种,今天我先讲…...
AttributeError: module ‘openai‘ has no attribute ‘error‘解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...
每日一记:一个windows的bat脚本工具集
最近在工作上遇到要校验文件的问题,例如,下载了一个文件之后,通过查看文件的md5来校验文件是否完整,这个动作在linux上很简单,但在windows上也不难,可以通过 certutil 命令实现,该命令通常可用于…...
Apache Zeppelin学习记录2
Apache Zeppelin学习记录2 文章目录 Apache Zeppelin学习记录2前言一、基础调用二、带参数调用1.代码块要增加一行z.textbox("folder_path", "input")2.读取result 总结 前言 上一章讲了如何使用zeppelin来接入python,本节我们来看看如何使用R…...
[原创][R语言]股票分析实战[11]:读取股票数据文件的细节: 提取目标列数据
[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…...
【kafka】记录用-----------1
主题(topic):消息的第一次分类 根据人为的划分条件将消息分成不同的主题 主题的划分是人为的根据不同的任务情景去划分 比如,我们有两个主题,一个是"订单",另一个是"库存"。每个主题代…...
uniapp 实现tabBar-switchTab之间的传参
一、需求: tabbar之间跳转页面时,需要传递一个参数。 官方文档明确说明: 跳转tabBar栏的页面只能使用 uni.switchTab 并且url 路径后面不能传递参数。 二、解决方法: 方法1:setStorageSync(本地缓存) //index.vue 页 onclick …...
geemap学习笔记049:下载Landsat数据时遇到的一个问题
前言 最近在下载Landsat 8 地面反射率数据(Surface Reflectance)时,遇到了一个问题,无论是使用geemap.ee_export_image_to_drive() 函数还是geemap.download_ee_image() 函数下载的数据,易康都打不开,显示…...
基于pyqt5+scapy 根据ip 具体端口 进行扫描 的程序
先给出代码 import sysfrom PyQt5 import uic from PyQt5.QtWidgets import *from scapy.all import * import argparse import logging from scapy.layers.inet import IP, TCP from scapy.sendrecv import sr1class MyWindow(QWidget):def __init__(self):super().__init__(…...
Redis:原理速成+项目实战——Redis企业级项目实战终结篇(HyperLogLog实现UV统计)
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成项目实战——Redis实战14(BitMap实现用户签到功能) 📚订阅专栏&am…...
Python的集合set用法介绍与例子
用法简介 Python的集合(set)是一种无序且不重复的元素序列。它类似于列表和元组,但集合中的元素是唯一的,没有重复的值。集合在Python中用于执行一些特定的操作,例如消除重复元素、检查元素是否存在等。 下面是一些关…...
服务器感染了.pings勒索病毒,如何确保数据文件完整恢复?
导言: 随着科技的不断进步,网络犯罪也在不断演变。其中之一的.pings勒索病毒是一种危险的恶意软件,它能够加密用户的数据文件,并要求支付赎金以解密这些文件。在本文中,91数据恢复将介绍.pings勒索病毒,以…...
go语言(二)----常量
1、单个常量用const进行定义。 const a int 100 2、多个常量用const()进行定义。 const ( a 10 b 20 ) 3、iota 与const()来表示枚举类型 const( a iota b c ) package mainimp…...
VSC ctrl+鼠标左键点击后,返回原来位置的方法
windows 在使用VSC编写代码时,我们常常用到Ctrl鼠标左键的方式来查看类或变量名的定义声明,看完之后我们想回到程序原来的位置,此时可以通过Alt ←(方向左键)来返回到原来的位置。...
还在为crontab表达式发愁吗,快使用这个工具
是不是每次要定义cron表达式的时候,都去百度翻找资料,cron表达式难写难记真是苦天下程序员久已。有没有什么不拥记的办法就轻松掌握呢?最近发现这个CrontabGuru神器,强烈推荐,真是广大程序员的福音了。 简介 Crontab…...
61. Spring事务传播行为实现原理
61. Spring事务传播行为实现原理 Spring的事务信息是存在ThreadLocal中的, 所以一个线程永远只能有一个事务 融入:当传播行为是融入外部事务则拿到ThreadLocal中的Connection、共享一个数据库连接共同提交、回滚;创建新事务:当传播行为是创建新事务,会将嵌套新事务存入Th…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
MeshGPT 笔记
[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...
