Teknologian jakaminen

[Hongmeng Study Notes] Relaatiotietokannan yleiskatsaus

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Relaatiotietokannan toimintamekanismi

1. Relaatiotietokanta tarjoaa yhteisen käyttöliittymän sovelluksille Taustalla oleva kerros käyttää SQLitea pysyvänä tallennusmoottorina ja tukee SQLiten tietokantaominaisuuksia, mukaan lukien, mutta ei rajoittuen, tapahtumat, indeksit, näkymät, triggerit, vierasavaimet, parametroidut kyselyt ja niihin rajoittumatta. SQL-käskyjen kääntäminen.
Lisää kuvan kuvaus tähän

Esimerkkikoodi

Yleinen menetelmä 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112

Indeksikoodi

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)
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176

Vaikutus

Lisää kuvan kuvaus tähän