9

我在我的颤振应用程序中使用 hive 作为我的 NoSQL 本地数据库。

以下是我的 Hive 类:

import 'dart:convert';

import 'package:hive/hive.dart';
import 'package:lpa_exam/src/model/listofexams.dart';
import 'package:lpa_exam/src/model/profile.dart';
part 'hiveprofile.g.dart';

@HiveType()
class PersonModel extends HiveObject{
  @HiveField(0)
  String language;

  @HiveField(1)
  String examName;

  @HiveField(2)
  int examId;

  @HiveField(3)
  Profile profile;

  @HiveField(4)
  ListExam listexam;

  @override
  String toString() {
    return jsonEncode({
      'language': language,
      'examName': this.examName,
      'examId': examId,
      'profile': profile,
      'listexam': listexam
    });
  }

  PersonModel(
      this.language, this.examName, this.examId, this.profile, this.listexam);
}

所以,我的要求是每次成功登录时我都应该更新配置文件对象。但为此,我还必须设置所有其他人。

我怎样才能只更新配置文件对象?

代码:

_personBox = Hive.openBox('personBox');
          await _personBox.then((item) {
            if (!item.isEmpty) {
              print('empty');
              item.putAt(0, PersonModel(...,..,..,..,...,..));
            }
          });

我正在使用蜂巢版本1.2.0

参考:https ://resocoder.com/2019/09/30/hive-flutter-tutorial-lightweight-fast-database/

4

5 回答 5

5

只需使用该putAt()方法,如下所示:

Hive.box('products').putAt(productIndex, _product);

您可以productIndex通过使用以下索引来获取listView.Builder

ListView.builder(
  itemBuilder: (cxt, i) {

    return Row(
      children:[
      Text(product[i].name),
        MaterialButton(
          child:Text('edit'),

          onPressed:(){

        Hive.box('products').putAt(i,product);
      }
    ),
  ]
),
}}
于 2020-08-20T13:53:46.153 回答
2

尝试 .save() 方法:

_personBox = Hive.openBox('personBox');
      await _personBox.then((item) {
        if (!item.isEmpty) {
          print('empty');
          var i = item.getAt(0, PersonModel(...,..,..,..,...,..));
          i.profile = Somevalue;
          i.save();
        }
 });
于 2020-01-13T07:46:45.687 回答
0

所以我很难解决完全相同的问题,我发现你基本上可以输入空值或引用以前的值/已经存在的值。这是一个示例,您必须输入配置文件对象,但您已经将其他属性保存在数据库中。

var language = Hive.box('personBox').getAt(0).language;
var examName = Hive.box('personBox').getAt(0).examName;
var examID = Hive.box('personBox').getAt(0).examID;
//Add the details you want to add here
var profile = SomeValue;
var listExam = Hive.box('personBox').getAt(0).listExam;

//Adding the details
Hive.box('personBox').putAt(0, PersonModel(language, examName, examID, profile, listExam));

现在的问题是,如果您的数据库中没有对象的实例,您将收到超出范围的错误。因此,为了减轻这种情况,您还需要在 main() 中添加这行额外的代码。

if (Hive.box('personBox').isEmpty == true) {
//add dummy values here for first initialization
Hive.box('personBox').add(PersonModel('', '', 0, '', ''));
}

请记住,您必须在程序中的某个位置输入其他值,但如果您只想在程序中的某个位置输入特定值,您可以使用它。这更像是一种蛮力方法,因为我找不到任何关于如何在特定字段中输入值的帮助,所以我不得不即兴发挥。

于 2021-01-23T14:31:34.323 回答
0

简短的回答:你不能

但是,您可以为 Profile 创建一个单独的框并为 PersonModel 声明一个 Id,即personId并将其用作配置文件框的索引。

import 'package:hive/hive.dart';
import 'package:lpa_exam/src/model/listofexams.dart';
import 'package:lpa_exam/src/model/profile.dart';
part 'hiveprofile.g.dart';

@HiveType()
class PersonModel extends HiveObject{
  @HiveField(0)
  String language;

  @HiveField(1)
  String examName;

  @HiveField(2)
  int examId;

  @HiveField(3)
  int personId;

  Profile profile; // notice profile is not a hive field anymore

  @HiveField(4)
  ListExam listexam;

  @override
  String toString() {
    return jsonEncode({
      'personId': personId,
      'language': language,
      'examName': this.examName,
      'examId': examId,
      'profile': profile,
      'listexam': listexam
    });
  }

  PersonModel(this.personId, 
      this.language, this.examName, this.examId, this.profile, this.listexam);
}

因为你正在使用await所以没有必要使用.then(...)

PersonModel person = PersonModel(...,..,..,..,...,..);
Profile profile = person.profile;
Box<Profile> _profileBox = await Hive.openBox<Profile>('profileBox');
_profileBox.putAt(person.personId, profile);
于 2021-05-06T01:33:46.230 回答
-1

我没有使用 Flutter 或 Hive 的经验,但来自 SQL 背景。如果你想更新 row/object/record/... 中的字段,我理解的唯一方法是读取当前记录,例如 box.getAt(index) 然后为所有字段赋值,然后使用 box.putAt(指数)。我本来希望有 box.updateAt(index, field1 value, field2 value2) 之类的东西。我想这是不存在的技术原因,它可能与性能有关。

我使用类似下面的东西:

var videoInfoData = _videoInfoBox.getAt(index);
      var updateVideoInfo = VideoInfo(
        title: videoInfoData.title,
        author: videoInfoData.author,
        time: videoInfoData.time,
        videoURL: videoInfoData.videoURL,
        dateLoaded: videoInfoData.dateLoaded,
        dateLastPlayed: DateTime.now(),
        numberTimesPlayed: videoInfoData.numberTimesPlayed + 1,
      );
      _videoInfoBox.putAt(index, updateVideoInfo);

我很想使用:

var videoInfoData = _videoInfoBox.getAt(index);
      var updateVideoInfo = VideoInfo(  
        dateLastPlayed: DateTime.now(),
        numberTimesPlayed: videoInfoData.numberTimesPlayed + 1,
      );
      _videoInfoBox.updateAt(index, fields being updated);
于 2021-12-05T05:49:26.667 回答