HarmonyOS之sqlite数据库的使用

news2024/11/16 9:25:42

从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 = false
          this.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.pageSize
    const page = param.page
    console.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+1
    this.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 = false
          this.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 = true
            this.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 = value
        this.keyword = value
        this.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.pageSize
    const page = param.page
    console.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)
  })
}




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1390874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis原理(四)数据安全之数据持久化

一、将数据持久化至硬盘 1、介绍&#xff1a;Redis是一个基于内存的数据库&#xff0c;它的数据是存放在内存中&#xff0c;内存有个问题就是关闭服务或者断电会丢失。Redis的数据也支持写到硬盘中&#xff0c;这个过程就叫做持久化。 2、Redis持久化选项&#xff1a;Redis提…

Pycharm无法刷新远程解释器的框架: Can‘t get remote credentials for deployment server

在Pycharm上部署项目到远程服务器&#xff0c;有时候需要启动SSH会话&#xff0c;启动的时候发现没反应&#xff0c;且事件日志显示&#xff1a;无法刷新远程解释器的框架: Can’t get remote credentials for deployment server 观察pycharm界面最下边&#xff0c;发现“无默…

Typora概述

Typora概述 1 下载Typora2 Typra大纲视图3 标题4 引用5 列表6 代码7 图片 各位小伙伴想要博客相关资料的话关注公众号&#xff1a;chuanyeTry即可领取相关资料&#xff01; 作为程序员平时编写笔记和开发文档时一般都使用Markdown格式&#xff0c;为了让你能成为更加专业的程序…

DApp:去中心化的革命与挑战

DApp&#xff08;去中心化应用&#xff09;是一种基于区块链技术的应用程序&#xff0c;与传统的中心化应用程序不同&#xff0c;DApp具有去中心化、透明、不可篡改等特性。本文将介绍DApp的前世今生&#xff0c;以及它的优势和未来发展。 DApp的前世可以追溯到区块链技术的出现…

【华为 ICT HCIA eNSP 习题汇总】——题目集1

1、&#xff08;多选&#xff09;根据下面所示的命令输出&#xff0c;下列描述中正确的是&#xff1f; A、GigabitEthernet0/0/1 允许VLAN1通过 B、GigabitEthernet0/0/1 不允许VLAN1通过 C、如果要把 GigabitEthernet0/0/1 变为 Access 端口&#xff0c;首先 需要使用命令“un…

Linux系统——yum仓库及NFS共享

目录 一、yum仓库 1.yum简介 2.yum实现过程 3.如何实现安装服务 4.yum配置文件及命令 4.1yum配置文件 4.1.1主配置文件 4.1.2仓库设置文件 4.1.3日志文件 4.2yum命令详解 4.2.1查询 4.2.2yum安装升级 4.2.3软件卸载 4.2.4操作安装历史记录 5.搭建本地yum仓库 5…

vue2使用qiankun微前端(跟着步骤走可实现)

需求&#xff1a;做一个vue2的微前端&#xff0c;以vue2为主应用&#xff0c;其他技术栈为子应用&#xff0c;比如vue3&#xff0c;本文章只是做vue2一套的微前端应用实现&#xff0c;之后解决的一些问题。vue3子应用可以看我另一篇vue3vitets实现qiankun微前端子应用-CSDN博客…

WebKit工程组织与结构随笔

1.WebKit结构 1.1 三个模块 概括地说&#xff0c;WebKit由主要由三个模块组成&#xff1a;JavaScriptCore、WebCore 和 WebKit。WebKit作为了整个项目的名称。 1). WebCore&#xff0c; 2). WebKit&#xff0c; 3). JavaScriptCore。 WebCore&#xff1a;排版引擎核心&…

leetcode-344. 反转字符串、9. 回文数

题目1&#xff1a; 解题方法 直接用reverse()即可 代码&#xff1a; class Solution(object):def reverseString(self, s):""":type s: List[str]:rtype: None Do not return anything, modify s in-place instead."""return s.reverse()如果不…

STC8H8K蓝牙智能巡线小车——3.按键开关状态获取

电路分析 引脚为P37开关未按下时&#xff0c;P37是高电平开关按下时&#xff0c;GND导通&#xff0c;P37是低电平 编程思路 Driver目录中添加KEY.h文件&#xff0c;应包含引脚定义、开关GPIO实例化函数、开关状态获取函数以及当按下和未按下时执行不同的函数&#xff08;函数…

用Python“自动连发消息”

自动连发消息&#xff0c;基本上C和Python的思路都是不停的模拟“击键”操作&#xff0c;还有一种VB的脚本写法&#xff0c;反成每种语言都能写&#xff0c;更厉害的可以用java做出个GUI界面&#xff0c;先上代码。 一 代码 import pyautogui # 鼠标 import p…

掌握Spring缓存-全面指南与最佳实践

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天来聊聊缓存&#xff0c;在Java和Spring里&#xff0c;缓存可是个大角色。咱们在网上购物&#xff0c;每次查看商品详情时&#xff0c;如果服务器都要去数据库里翻箱倒柜&#xff0c;那速度得慢成什么样&…

线性回归理论+实战

线性回归 什么是线性回归 3.1. 线性回归 — 动手学深度学习 2.0.0 documentation (d2l.ai) 模型 损失函数 模型拟合&#xff08;fit&#xff09;数据之前&#xff0c;我们需要确定一个拟合程度的度量。 损失函数&#xff08;loss function&#xff09;能够量化目标的实际值…

仿真机器人-深度学习CV和激光雷达感知(项目2)day01【项目介绍与环境搭建】

文章目录 前言项目介绍功能与技术简介硬件要求环境配置虚拟机运行项目demo 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本文内容是我为复试准备的第二个项目 &#x1f4ab;欢迎大家的关注&#xff0c;我的博客主要关注…

Unity Shader 的模板测试效果

模板测试是渲染管线中逐片元操作的一环&#xff0c;它的作用是筛选出指定模板的片元&#xff0c;而不符合模板的片元会被舍弃&#xff0c;从而做到一个遮罩的效果。 以下是Unity中实践的一个效果&#xff1a; 场景中可以看出&#xff0c;熊模型和茶壶模型都在差不多的位置&am…

力扣labuladong一刷day61天动态规划最小下降路径

力扣labuladong一刷day61天动态规划最优子结构 一、931. 下降路径最小和 题目链接&#xff1a;https://leetcode.cn/problems/minimum-falling-path-sum/description/ 如下图所示&#xff0c;求最小下降路径&#xff0c;定义dp[i][j]表示从最上面那行的任意位置抵达到nums[i]…

vtk9.3 + Visual Studio2019 + Cmake3.28 win11 上的环境安装(这个过程网上比较多,自己记录下过程加深下印象)

开始 介绍 欢迎来到 VTK&#xff01;我们建议您首先阅读《VTK book》&#xff0c;这是一本全面的 VTK 指南&#xff0c;涵盖了其功能的所有方面。此外&#xff0c;您可能会发现探索 VTK 示例很有帮助&#xff0c;这是一组有用的参考资料&#xff0c;演示了如何使用 VTK 的不同模…

【电力电子】1 Cuk仿真电路

【仅供参考】 【2022.11西南交大电力电子仿真】 参考博客&#xff1a; [1] Cuk电路的参数计算及仿真_cuk电路参数计算-CSDN博客 目录 1 仿真电路搭建及波形记录 1.1 DCM工作模式 1.2 CCM工作模式 2 PI控制器的设计 1 仿真电路搭建及波形记录 仿真要求&#xff1a;建立输入…

通过OpenIddict设计一个授权服务器02-创建asp.net项目

在这一部分中&#xff0c;我们将创建一个ASPNET核心项目&#xff0c;作为我们授权服务器的最低设置。我们将使用MVC来提供页面&#xff0c;并将身份验证添加到项目中&#xff0c;包括一个基本的登录表单。 创建一个空的asp.net core项目 正如前一篇文章中所说&#xff0c;授权…

从零开始:Golang中JSON解析与生成的完全指南

从零开始&#xff1a;Golang中JSON解析与生成的完全指南 引言Golang与JSON&#xff1a;基础概念JSON简介为何在Golang中使用JSON Golang中JSON数据的解析使用encoding/json解析JSON解析成基本数据类型解析成自定义结构体错误处理和常见问题 Golang中生成JSON数据将Golang对象转…