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…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
