【鸿蒙学习笔记】关系型数据库概述

news2024/9/24 17:12:06

目录标题

  • 关系型数据库的运行机制
  • 样例代码
    • 共通方法 DBUtils
    • Index 代码
    • 效果

关系型数据库的运行机制

1、 关系型数据库对应用提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。
在这里插入图片描述

样例代码

共通方法 DBUtils

import relationalStore from '@ohos.data.relationalStore'
import { common } from '@kit.AbilityKit'

export class DBUtils {
  // 数据库名称
  private tableName: string = 'accountTable'
  // 建表语句
  private sqlCreate: string = 'CREATE TABLE IF NOT EXISTS accountTable(id INTEGER PRIMARY KEY AUTOINCREMENT, accountType INTEGER, typeText TEXT, amount INTEGER)'
  // 表字段
  private columns: string[] = ['id', 'accountType', 'typeText', 'amount']
  // 数据库核心类
  private rdbStore: relationalStore.RdbStore | null = null
  // 数据库配置
  DB_CONFIG: relationalStore.StoreConfig = {
    name: 'RdbTest.db', // 数据库文件名
    securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别
  };

  /**
   * 获取rdb
   * @param context:上下文
   * @param callback:回调函数,我们第一次获取数据时,需要在获取到rdb之后才能获取,所以有此回调
   */
  getRdbStore(context: common.UIAbilityContext, callback: Function) {
    relationalStore.getRdbStore(context, this.DB_CONFIG, (error, store) => {
      if (this.rdbStore !== null) {
        //如果已经有rdb,直接建表
        store.executeSql(this.sqlCreate)
        return
      }
      //保存rdb,下边会用
      this.rdbStore = store
      //建表
      store.executeSql(this.sqlCreate)
      console.log("test", "successed get dbStore")
      if (callback) callback()
    })
  }

  /**
   * 插入数据
   * @param data:数据对象
   * @param callback:回调函数,这里的结果是通过回调函数返回的(也可使用返回值)
   */
  insertData(data: AccountData, callback: Function) {
    //将数据对象,转换为ValuesBucket类型
    const valueBucket: relationalStore.ValuesBucket = generateValueBucket(data);
    // 调用insert插入数据
    this.rdbStore && this.rdbStore.insert(this.tableName, valueBucket, (err, res) => {
      if (err) {
        console.log("test,插入失败", err)
        callback(-1)
        return
      }
      console.log("test,插入成功", res)
      callback(res) //res为行号
    })
  }

  /**
   * 获取数据
   * @param callback:接收结果的回调函数
   */
  query(callback: Function) {
    //predicates是用于添加查询条件的
    let predicates = new relationalStore.RdbPredicates(this.tableName)

    // 查询所有,不需要条件
    // predicates.equalTo("字段",数据)
    this.rdbStore && this.rdbStore.query(predicates, this.columns, (error, resultSet: relationalStore.ResultSet) => {
      if (error) {
        console.log("test,获取数据失败", JSON.stringify(error))
        return
      }

      let rowCount: number = resultSet.rowCount
      console.log("test", "数据库中数据数量:" + rowCount) //没数据时返回-1或0
      if (rowCount <= 0 || typeof rowCount === 'string') {
        callback([])
        return
      }

      let result: AccountData[] = []
      //上来必须调用一次goToNextRow,让游标处于第一条数据,while(resultSet.goToNextRow())是最有写法
      while (resultSet.goToNextRow()) {
        let accountData: AccountData = { id: 0, accountType: 0, typeText: '', amount: 0 }
        accountData.id = resultSet.getDouble(resultSet.getColumnIndex('id'));
        accountData.typeText = resultSet.getString(resultSet.getColumnIndex('typeText'))
        accountData.accountType = resultSet.getDouble(resultSet.getColumnIndex('accountType'))
        accountData.amount = resultSet.getDouble(resultSet.getColumnIndex('amount'))
        result.push(accountData)
      }
      callback(result)
      resultSet.close() //释放数据集内容
    })
  }
}

function generateValueBucket(account: AccountData): relationalStore.ValuesBucket {
  let obj: relationalStore.ValuesBucket = {};
  obj.accountType = account.accountType;
  obj.typeText = account.typeText;
  obj.amount = account.amount;
  return obj;
}

export class AccountData {
  id: number = -1;
  accountType: number = 0;
  typeText: string = '';
  amount: number = 0;
}

Index 代码

import { AccountData, DBUtils } from '../uitls/DBUtils';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct Index_DBPage {
  // 数据库工具类
  private dbUtils: DBUtils = new DBUtils()
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext

  // 账户数据数组
  @State accountDataArray: AccountData[] = []
  // 列表的图片数组
  imageArr: Resource[] = [$r('app.media.foods'), $r('app.media.games'), $r('app.media.fuel')]

  // 添加数据弹框
  addDialogController: CustomDialogController = new CustomDialogController({
    builder: AddDialog({
      //点击确定的回调
      confirm: (insertData: AccountData) => {
        this.onConfirm(insertData)
      }
    })
  })

  // 界面打开时,查询数据,展示胡静
  aboutToAppear(): void {
    this.dbUtils.getRdbStore(this.context, () => {
      this.queryData()
    })
  }

  // 查询数据方法
  queryData() {
    this.dbUtils.query((result: AccountData[]) => {
      this.accountDataArray = result
      console.log("test,获取数据成功:", JSON.stringify(this.accountDataArray))
    })
  }

  // 点击确定回调
  onConfirm(insertData: AccountData) {
    console.log("test", JSON.stringify(insertData))
    // 插入数据
    this.dbUtils.insertData(insertData, (res: number) => {
      if (res > 0) {
        // AlertDialog.show({ message: "添加成功" })
        this.queryData()
      } else {
        AlertDialog.show({ message: "添加失败" })
      }
    })
  }

  build() {
    Stack() {
      Column() {
        Row() {
          Text('关系型数据库').height(33).fontSize(24).margin({ left: 24 }).fontColor(Color.Red)
        }.width('100%').justifyContent(FlexAlign.SpaceBetween).margin(12).backgroundColor(Color.Grey)

        //数据列表
        List({ space: 20 }) {
          ForEach(this.accountDataArray, (item: AccountData, index: number) => {
            ListItem() {
              Row() {
                // 图片
                Image(this.imageArr[item.accountType]).width(40).aspectRatio(1).margin({ right: 16 })
                // 内容
                Text(item.typeText).height(22).fontSize(16)
                Blank().layoutWeight(1)
                // 金额
                Text("¥: " + String(item.amount)).height(22).fontSize(16)
              }
              .width('90%')
              .padding({ left: 12, right: 12 })
              .margin({ left: 20 })
              .backgroundColor('#f1f3f5')
              .padding(10)
              .borderRadius(30)
            }
          })
        }
      }.width('100%')

      Button() {
        Image($r('app.media.add'))
      }.width(48).height(48).position({ x: '80%', y: '90%' })
      .onClick(() => {
        this.addDialogController.open()
      })
    }
  }
}

interface Item {
  icon: Resource;
  text: string;
}

@CustomDialog
struct AddDialog {
  controller: CustomDialogController;
  //确认回调
  confirm?: (insertData: AccountData) => void

  items: Array<Item> = [
    { icon: $r('app.media.foods'), text: '吃饭' },
    { icon: $r('app.media.games'), text: '娱乐' },
    { icon: $r('app.media.fuel'), text: '加油' },
  ]

  @State currentIndex: number = -1
  @State money: number = 0

  build() {
    Column() {
      Row() {
        ForEach(this.items, (item: Item, index) => {
          Column() {
            Image(item.icon).width(40).height(40)
            Text(item.text).fontSize(12).fontColor('#FF007DFF').margin({ top: 8 })
          }
          .width(86)
          .aspectRatio(1) //指定当前组件的宽高比
          .padding({ top: 12 })
          .margin({ top: 16, left: 12 })
          .align(Alignment.TopStart)
          .backgroundColor(this.currentIndex === index ? '#ccc' : '#FFF1F3F5')
          .borderRadius(16)
          .onClick(() => {
            this.currentIndex = index
          })
        })
      }.width('100%').justifyContent(FlexAlign.Center)

      Row() {
        Column() {
          Text('金额').width('100%').fontSize(20).fontColor(Color.Black)

          Column() {
            TextInput({
              placeholder: '请输入金额'
            })
              .padding({ left: 0, top: 0, bottom: 0 })
              .borderRadius(0)
              .backgroundColor(Color.White)
              .type(InputType.Number)
              .onChange((value: string) => {
                this.money = Number(value)
              })
          }.height(48).padding({ top: 15, bottom: 11 }).borderWidth({ bottom: 1 }).borderColor('#33182431')

          Button("确定").onClick((event: ClickEvent) => {
            if (this.currentIndex === -1) {
              AlertDialog.show({ message: "请选择种类" })
              return
            }
            if (this.money === 0) {
              AlertDialog.show({ message: "请输入金额" })
              return
            }
            let insertData: AccountData = {
              id: 0,
              accountType: this.currentIndex,
              typeText: this.items[this.currentIndex].text,
              amount: this.money
            }
            this.confirm && this.confirm(insertData)
            this.controller.close()
          }).width('90%').margin(20)
        }.width('100%').padding({ left: 12, right: 12 })
      }.width('100%').margin(20)
    }
  }
}

效果

在这里插入图片描述

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

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

相关文章

MongoDB教程(一):Linux系统安装mongoDB详细教程

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、Ubuntu…

【单片机毕业设计选题24059】-太阳能嵌入式智能充电系统研究

系统功能: 系统由太阳能电池板提供电源&#xff0c; 系统上电后显示“欢迎使用智能充电系统请稍后”&#xff0c; 两秒钟后进入主页面显示。 第一行显示太阳能电池板输入的电压值 第二行显示系统输出的电压值 第三行显示采集到的太阳能电池板温度 第四行显示设置的太阳能…

【Linux杂货铺】1.环境变量

1.环境变量基本概念 环境变量&#xff08; environment variables &#xff09;一般是指在操作系统中用来指定操作系统运行环境的一些参数。如&#xff1a;我们在编写 C / C &#xff0b;代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪…

信创会不会烂尾

最近又有不少人开始忽悠信创概念了&#xff0c;感觉这又是部分人发财的噱头&#xff0c;集体资源浪费的开始! 我们软件业几代人和全世界的差距能短时间内追上?人家会本着友谊第一比赛第二的原则&#xff0c;站在原地等你追&#xff1f;然后和你一起相扶到美好的未来&#xff1…

华为HCIP Datacom H12-821 卷37

1.多选题 下面关于Network- Summary-LSA 描述正确的是 A、Network- Summary-LSA中的Metric被设置成从该ABR到达目的网段的开销值 B、Network- Sumary-LSA中的Net mask 被设置成目的网段的网络掩码 C、Network- Summary-LSA 是由ASBR产生的 D、Network- Summary-LSA 中的Li…

年度必看|2024全球工业网络市场份额预测报告

重点摘要 每年&#xff0c;HMS Networks 都会对工业网络市场进行全面分析&#xff0c;旨在估计工厂自动化中按类型和协议划分的新连接节点的分布情况。最新研究表明&#xff0c;工业网络市场继续扩张&#xff0c;预计 2024 年将增长 7%。值得注意的是&#xff0c;工业以太网仍然…

python 实验八 数据分析与展示

一、实验目的 掌握掌握matplotlib库中pyplot模块的使用。 二、实验环境 Window10&#xff08;x64&#xff09;&#xff0c;Python 3.8&#xff08;x64&#xff09;&#xff0c;PyCharm Community Edition 2020.3.2&#xff08;x64&#xff09; 三、实验内容 现有列表hight…

WAV 和 FLAC 哪个音质好?常见音频格式又如何转换?

音频文件的格式种类繁多&#xff0c;每种格式都有其独特的优势和应用场景。其中&#xff0c;WAV 和 FLAC 作为两种常见的无损音频格式&#xff0c;备受音频发烧友和专业人士的青睐。它们不仅能够保留原始录音的全部细节&#xff0c;还为听众提供了近乎 CD 品质的听觉体验。然而…

文字转语音免费工具有哪些?嘎嘎好使的配音工具推荐

每天刷视频看多了大家随手创作的各种生活小段子&#xff0c;自己不免也心痒痒地想玩上一把&#xff0c;可奈何却搞不懂各种旁白配音怎么弄。 好在经过一番摸索之后&#xff0c;可算是被我整明白免费文字转语音该怎么操作了&#xff01;接下来就把我搜集到的4款宝藏配音神器整理…

Windows 怎么删除D盘?多种方法详解!

有关Windows电脑的文件整理&#xff0c;文章详细介绍了怎么删除D盘的多种方法&#xff0c;释放不必要的空间。 “我最近在整理电脑文件的时候遇到一个问题&#xff0c;我想请教一下大家。我的Windows电脑上有一个D盘&#xff0c;里面存放了一些不需要的文件&#xff0c;我想彻…

PE73_D_E6_BLE

产品参数 产品型号 PE73_D_E6_BLE 尺寸(mm) 176.2*137.15*80mm 显示技术 电子墨水屏双面显示 显示区域(mm) 163.2(H) * 97.92(V) 分辨率(像素) 800*480 外观颜色 银色 显示颜色 黑/白/红/黄/蓝/绿 视觉角度 180 工作温度 15-35℃ 产品重量 268g 电池容…

ABAQUS广东正版代理商:亿达四方——达索官方授权

在粤港澳大湾区建设的浪潮中&#xff0c;广东作为中国改革开放的前沿阵地&#xff0c;始终走在科技创新的最前线。亿达四方&#xff0c;作为国际领先的仿真软件ABAQUS在广东地区的官方授权代理商&#xff0c;正以先进的技术和服务&#xff0c;推动着广东地区制造业向智能化、高…

自然语言处理:第四十二章 RAG与LLM原先知识冲突时,大模型会如何处理?

文章链接:7B&#xff1f;13B&#xff1f;175B&#xff1f;解读大模型的参数 (qq.com) 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新…

vue 使用腾讯地图 标点 自定义瓦片 折线配置

vue 使用腾讯地图 标点 自定义瓦片 折线配置 申请腾讯地图秘钥 key 腾讯地图开发者 https://lbs.qq.com/dev/console/application/mine 腾讯地图开发文档 https://lbs.qq.com/webApi/javascriptGL/glGuide/glOverview 添加 key 代码中引入 // 入口文件 index.html // 填…

Ambari Hive 创建函数无权限

作者&#xff1a;櫰木 1、创建udf函数 参考文档&#xff1a;https://blog.csdn.net/helloxiaozhe/article/details/102498567 如果已经编写好&#xff0c;请使用自己的。如果没有请参考以上链接进行udf函数编写。 2、创建函数遇到的问题 由于集群开启了kerberos&#xff0…

UART编程

Q:为什么使用串口前要先在电脑上安装CH340驱动&#xff1f; 三种编程方式简介 也可以通过DMA方式减小CPU资源的消耗 直接把数据在SRAM内存和UART模块进行传输 &#xff0c;流程&#xff1a; 把数据在DMA中配置好数据传输产生中断&#xff0c;CPU介入 编程方式改进 1、查询…

求职学习笔记day1

自己一直算是一个内耗拖延的人&#xff0c;内耗着考了研&#xff0c;内耗着拖着不找工作&#xff0c;一直拖到了毕业。研究生没考上&#xff0c;工作没有&#xff0c;也羡慕着别人成功的生活&#xff0c;最后毕业的也不太开心。 一、最近总结 游戏 高考结束以来和大学期间作息…

Proteus + Keil单片机仿真教程(六)多位LED数码管的动态显示

上一节我们通过锁存器和八个八位数码管实现了多个数码管的静态显示,这节主要讲解多位数码管的动态显示,所谓的动态显示就是对两个锁存器的控制。考虑一个问题,现在给WS位锁存器增加一个循环,让它从1111 1110到0111 1111会发生什么事情?话不多说,先上代码: #include<…

护(H)网(W)行动正当时:你对HW知多少,一文带你全面了解护网行动

引言&#xff1a;2016年我国发布了《网络安全法》&#xff08;于2017年6月1日正式生效&#xff09;&#xff0c;明确规定了关键信息基础设施的运营者必须制定网络安全事件应急预案&#xff0c;并定期进行演练&#xff0c;为HW行动的开展提供了法律依据&#xff0c;通过红蓝对抗…

加入鲲鹏原生开发训练营,共驭技术创新巨浪

随着生态的不断成熟&#xff0c;鲲鹏逐渐从迁移为主发展到原生开发阶段&#xff0c;与此同时&#xff0c;鲲鹏也面临着让开发者能够在变道后提档加速的新任务&#xff0c;从应用迁移走向原生开发。 开发者是计算技术创新的关键力量。为了让开发者全面了解鲲鹏原生开发理论知识…