找回密码
 立即注册
首页 业界区 安全 HarmonyOS NEXT 使用 relationalStore 实现数据库操作 ...

HarmonyOS NEXT 使用 relationalStore 实现数据库操作

闻人莹华 2025-5-30 20:24:43
大家好,我是V哥。在 HarmonyOS NEXT 开发中,如何操作数据库,V 哥在测试中总结了以下学习代码,分享给你,如何想要系统学习鸿蒙开发,可以了解一下 V 哥最近刚刚上架出版的 《HarmonyOS 鸿蒙开发之路 卷2 从入门到应用篇》,V 哥在这本书里系统的介绍纯血鸿蒙的细枝末节,可以让零基础的朋友快速上手鸿蒙应用开发。
1.jpeg

在鸿蒙开发中,系统 API 提供了基于SQLite组件的一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。支持通过ResultSet.getSendableRow方法获取Sendable数据,进行跨线程传递。
这里要注意一下,为保证插入并读取数据成功,建议一条数据不超过2MB。如果数据超过2MB,插入操作将成功,读取操作将失败。
大数据量场景下查询数据可能会导致耗时长甚至应用卡死,如有相关操作可参考文档批量数据写数据库场景,且有建议如下:

  • 单次查询数据量不超过5000条。
  • 在TaskPool中查询。
  • 拼接SQL语句尽量简洁。
  • 合理地分批次查询。
该模块提供以下关系型数据库相关的常用功能:

  • RdbPredicates:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
  • RdbStore:提供管理关系数据库(RDB)方法的接口。
  • ResultSet:提供用户调用关系型数据库查询接口之后返回的结果集合。
  • Transaction:提供管理事务对象的接口。
案例代码

接下来,V 哥通一个完整案例来介绍如何使用。
  1. import relationalStore from '@ohos.data.relationalStore';
  2. import promptAction from '@ohos.promptAction';
  3. @Entry
  4. @Component
  5. struct RdbStoreExample {
  6.   @State userList: Array<{ id: number; name: string; age: number }> = [];
  7.   @State nameInput: string = '';
  8.   @State ageInput: string = '';
  9.   private rdbStore: relationalStore.RdbStore | null = null;
  10.   private rdbConfig: relationalStore.RdbStoreConfig = {
  11.     name: 'UserData.db',
  12.     securityLevel: relationalStore.SecurityLevel.S1
  13.   };
  14.   private CREATE_TABLE_USER =
  15.     'CREATE TABLE IF NOT EXISTS User (' +
  16.     'id INTEGER PRIMARY KEY AUTOINCREMENT, ' +
  17.     'name TEXT NOT NULL, ' +
  18.     'age INTEGER NOT NULL)';
  19.   aboutToAppear() {
  20.     this.openRdbStore();
  21.   }
  22.   aboutToDisappear() {
  23.     this.closeRdbStore();
  24.   }
  25.   // 打开数据库
  26.   async openRdbStore() {
  27.     try {
  28.       this.rdbStore = await relationalStore.getRdbStore(this.rdbConfig, 1,
  29.         (version: number, rdbStore: relationalStore.RdbStore) => {
  30.           if (version === 1) {
  31.             rdbStore.executeSql(this.CREATE_TABLE_USER, []);
  32.           }
  33.         });
  34.       await this.queryUsers();
  35.     } catch (error) {
  36.       console.error(`Failed to open RDB store: ${error}`);
  37.       promptAction.showToast({ message: '数据库打开失败' });
  38.     }
  39.   }
  40.   // 关闭数据库
  41.   async closeRdbStore() {
  42.     if (this.rdbStore) {
  43.       try {
  44.         await this.rdbStore.close();
  45.         this.rdbStore = null;
  46.       } catch (error) {
  47.         console.error(`Failed to close RDB store: ${error}`);
  48.       }
  49.     }
  50.   }
  51.   // 插入数据
  52.   async insertUser() {
  53.     if (!this.nameInput || !this.ageInput) {
  54.       promptAction.showToast({ message: '请输入姓名和年龄' });
  55.       return;
  56.     }
  57.    
  58.     try {
  59.       const valuesBucket = {
  60.         name: this.nameInput,
  61.         age: parseInt(this.ageInput)
  62.       };
  63.       
  64.       const id = await this.rdbStore?.insert('User', valuesBucket);
  65.       if (id && id > 0) {
  66.         promptAction.showToast({ message: '插入成功' });
  67.         await this.queryUsers();
  68.         this.nameInput = '';
  69.         this.ageInput = '';
  70.       }
  71.     } catch (error) {
  72.       console.error(`Failed to insert data: ${error}`);
  73.       promptAction.showToast({ message: '插入失败' });
  74.     }
  75.   }
  76.   // 查询数据
  77.   async queryUsers() {
  78.     try {
  79.       const resultSet = await this.rdbStore?.querySql(
  80.         'SELECT * FROM User', []);
  81.       
  82.       if (resultSet) {
  83.         const users = [];
  84.         resultSet.goToFirstRow();
  85.         
  86.         while (!resultSet.isAtEnd()) {
  87.           users.push({
  88.             id: resultSet.getLong(resultSet.getColumnIndex('id')),
  89.             name: resultSet.getString(resultSet.getColumnIndex('name')),
  90.             age: resultSet.getInt(resultSet.getColumnIndex('age'))
  91.           });
  92.           resultSet.goToNextRow();
  93.         }
  94.         
  95.         this.userList = users;
  96.         resultSet.close();
  97.       }
  98.     } catch (error) {
  99.       console.error(`Failed to query data: ${error}`);
  100.       promptAction.showToast({ message: '查询失败' });
  101.     }
  102.   }
  103.   // 更新数据
  104.   async updateUser(id: number, name: string, age: number) {
  105.     try {
  106.       const valuesBucket = {
  107.         name: name,
  108.         age: age
  109.       };
  110.       
  111.       const conditions = new relationalStore.RdbStorePredicates('User');
  112.       conditions.equalTo('id', id.toString());
  113.       
  114.       const rowsAffected = await this.rdbStore?.update(
  115.         valuesBucket, conditions);
  116.       
  117.       if (rowsAffected && rowsAffected > 0) {
  118.         promptAction.showToast({ message: '更新成功' });
  119.         await this.queryUsers();
  120.       }
  121.     } catch (error) {
  122.       console.error(`Failed to update data: ${error}`);
  123.       promptAction.showToast({ message: '更新失败' });
  124.     }
  125.   }
  126.   // 删除数据
  127.   async deleteUser(id: number) {
  128.     try {
  129.       const conditions = new relationalStore.RdbStorePredicates('User');
  130.       conditions.equalTo('id', id.toString());
  131.       
  132.       const rowsAffected = await this.rdbStore?.delete(conditions);
  133.       
  134.       if (rowsAffected && rowsAffected > 0) {
  135.         promptAction.showToast({ message: '删除成功' });
  136.         await this.queryUsers();
  137.       }
  138.     } catch (error) {
  139.       console.error(`Failed to delete data: ${error}`);
  140.       promptAction.showToast({ message: '删除失败' });
  141.     }
  142.   }
  143.   build() {
  144.     Column() {
  145.       // 输入表单
  146.       Column() {
  147.         Input({
  148.           placeholder: '请输入姓名',
  149.           type: InputType.Text
  150.         })
  151.         .width('100%')
  152.         .margin({ top: 10, bottom: 10 })
  153.         .onChange((value: string) => {
  154.           this.nameInput = value;
  155.         })
  156.         
  157.         Input({
  158.           placeholder: '请输入年龄',
  159.           type: InputType.Number
  160.         })
  161.         .width('100%')
  162.         .margin({ top: 10, bottom: 10 })
  163.         .onChange((value: string) => {
  164.           this.ageInput = value;
  165.         })
  166.         
  167.         Button('添加用户')
  168.         .width('100%')
  169.         .onClick(() => {
  170.           this.insertUser();
  171.         })
  172.       }
  173.       .width('90%')
  174.       .margin({ top: 20, bottom: 20 })
  175.       
  176.       // 用户列表
  177.       List() {
  178.         ForEach(this.userList, (user) => {
  179.           ListItem() {
  180.             Row() {
  181.               Column() {
  182.                 Text(`姓名: ${user.name}`)
  183.                 Text(`年龄: ${user.age}`)
  184.               }
  185.               .width('70%')
  186.               
  187.               Column() {
  188.                 Button('修改')
  189.                 .onClick(() => {
  190.                   const newName = promptAction.showPromptDialog({
  191.                     message: '请输入新姓名',
  192.                     defaultValue: user.name
  193.                   });
  194.                   const newAge = promptAction.showPromptDialog({
  195.                     message: '请输入新年龄',
  196.                     defaultValue: user.age.toString()
  197.                   });
  198.                   if (newName && newAge) {
  199.                     this.updateUser(user.id, newName, parseInt(newAge));
  200.                   }
  201.                 })
  202.                
  203.                 Button('删除')
  204.                 .onClick(() => {
  205.                   this.deleteUser(user.id);
  206.                 })
  207.               }
  208.               .width('30%')
  209.             }
  210.             .width('100%')
  211.           }
  212.         })
  213.       }
  214.       .width('90%')
  215.       .margin({ top: 10, bottom: 10 })
  216.     }
  217.     .width('100%')
  218.     .height('100%')
  219.     .padding(15)
  220.   }
  221. }
复制代码
下面来解释下这个示例:

  • 首先要创建数据库配置并打开数据库,在openRdbStore方法里完成这些操作,创建了一个名为UserData.db的数据库,还定义了建表语句。
  • 插入数据时,使用insert方法,把姓名和年龄封装成valuesBucket对象传进去,插入成功后会更新用户列表。
  • 查询数据是通过querySql方法执行SQL语句,然后遍历结果集把数据存到userList里。
  • 更新数据用update方法,要先创建RdbStorePredicates对象设置更新条件,根据ID来更新对应的记录。
  • 删除数据也是先创建条件对象,然后调用delete方法,根据ID删除记录。
  • 在界面上,提供了输入框让用户输入姓名和年龄,还有添加按钮,下面展示用户列表,每条记录都有修改和删除按钮。
操作技巧总结如下


  • 打开和关闭数据库操作要在页面生命周期的合适时机进行,比如在aboutToAppear时打开,aboutToDisappear时关闭。
  • 执行数据库操作时一定要进行异常处理,避免程序崩溃。
  • 使用预编译语句可以提高性能,特别是在批量操作的时候。
  • 操作完成后要及时关闭ResultSet,释放资源。
  • 合理设计表结构,设置合适的主键和索引能提升查询效率。
  • 更新和删除操作记得设置好条件,防止误操作。
  • 对于复杂查询,可以使用原生SQL语句,但要注意SQL助入问题。
好了,以上内容供你参考,学习鸿蒙开发,抢占市场风口,国产化之路,V 哥与你搀扶前行。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册