如何在hive对象中编写自定义类对象?

Gau*_*mar 12 flutter

在 flutter 中使用 hive 时,我Profile profile在 hive 对象中使用了自定义类对象。

因此,最初,我将自定义类对象(Profile profile)设置为null在 Hive 框中添加时。

以下是我的 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': this.language,
      'examName': this.examName,
      'examId': this.examId,
      'profile': this.profile,
      'listexam': this.listexam
    });
  }

  PersonModel(
      this.language, this.examName, this.examId, this.profile, this.listexam);
}
Run Code Online (Sandbox Code Playgroud)

可供参考的型材类别:

class Profile {
  String name='';
  String lang='';
  String emailId='';
  String mobileNumber='';
  String state='';
  String city='';
  String district='';
  String pinCode='';
  String profilePic='';
  Profile(
      this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,this.profilePic);

  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic=json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic']=this.profilePic;
    return data;
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试像这样添加添加的对象时发生错误

item.add(PersonModel(label, null, null, Profile(), ListExam())); // label='English'
Run Code Online (Sandbox Code Playgroud)

以下是发生的错误:

[VERBOSE-2:ui_dart_state.cc(157)] 未处理的异常:HiveError:无法写入,未知类型:配置文件。您是否忘记注册适配器?

现在,有人可以指出我在这里做错了什么吗?

Sel*_*ğlu 8

Hive 插件默认支持原语、列表和映射。要将其用于您自己的 Dart 对象,您需要生成一个 TypeAdapter。

您需要为您拥有的每个对象创建一个 TypeAdapter。因此,您需要对Profile类应用与PersonModel相同的内容

part 'profile.g.dart';

@HiveType()
class Profile {
  @HiveField(0)
  String name;
  @HiveField(1)
  String lang;
  @HiveField(2)
  String emailId;
  @HiveField(3)
  String mobileNumber;
  @HiveField(4)
  String state;
  @HiveField(5)
  String city;
  @HiveField(6)
  String district;
  @HiveField(7)
  String pinCode;
  @HiveField(8)
  String profilePic;

  Profile(
      this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,this.profilePic);      


  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic=json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic']=this.profilePic;
    return data;
 }

}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是最新的 hive 版本,您还需要为您的 HiveType 提供类型 ID,例如

@HiveType(typeId: 0)
Run Code Online (Sandbox Code Playgroud)

我看到您有另一个名为ListExam 的自定义类。您还需要对该类执行相同的操作


chu*_*han 4

您可以复制粘贴运行下面的完整代码,main.dart对于main.g.dart
演示,我说listexam
您需要 创建registerAdapter(ProfileAdapter())并查看下面 代码片段的完整代码
class ProfileAdapter extends TypeAdapter<Profile>

Hive
    ..init(dir.path)
    ..registerAdapter(PersonModelAdapter())
    ..registerAdapter(ProfileAdapter());


  var box = await Hive.openBox('testBox');

  var personModel = PersonModel(
      language: "en",
      examName: "abc",
      examId: 123,
      profile: Profile(name: "test", emailId: "a@b.com"));

  await box.put('test', personModel);

  print(box.get('test'));
Run Code Online (Sandbox Code Playgroud)

输出

I/flutter (10795): {"language":"en","examName":"abc","examId":123,"profile":{"name":"test","language":null,"emailId":"a@b.com","mobileNumber":null,"district":null,"state":null,"city":null,"pinCode":null,"profilePic":null}}
Run Code Online (Sandbox Code Playgroud)

主程序.dart

import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';

part 'main.g.dart';

@HiveType(typeId: 1)
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': this.language,
      'examName': this.examName,
      'examId': this.examId,
      'profile': this.profile,
      //'listexam': this.listexam
    });
  }

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

@HiveType(typeId: 2)
class Profile extends HiveObject {
  String name = '';
  String lang = '';
  String emailId = '';
  String mobileNumber = '';
  String state = '';
  String city = '';
  String district = '';
  String pinCode = '';
  String profilePic = '';

  Profile(
      {this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,
      this.profilePic});

  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic = json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic'] = this.profilePic;
    return data;
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  var dir = await getApplicationDocumentsDirectory();
  Hive
    ..init(dir.path)
    ..registerAdapter(PersonModelAdapter())
    ..registerAdapter(ProfileAdapter());

  var box = await Hive.openBox('testBox');

  var personModel = PersonModel(
      language: "en",
      examName: "abc",
      examId: 123,
      profile: Profile(name: "test", emailId: "a@b.com"));

  await box.put('test', personModel);

  print(box.get('test'));
}
Run Code Online (Sandbox Code Playgroud)

main.g.dart

part of 'main.dart';

// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************

class PersonModelAdapter extends TypeAdapter<PersonModel> {
  @override
  final typeId = 1;

  @override
  PersonModel read(BinaryReader reader) {
    var numOfFields = reader.readByte();
    var fields = <int, dynamic>{
      for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return PersonModel()
      ..language = fields[0] as String
      ..examName = fields[1] as String
      ..examId = fields[2] as int
      ..profile = fields[3] as Profile;
  }

  @override
  void write(BinaryWriter writer, PersonModel obj) {
    writer
      ..writeByte(3)
      ..writeByte(0)
      ..write(obj.language)
      ..writeByte(1)
      ..write(obj.examName)
      ..writeByte(2)
      ..write(obj.examId)
      ..writeByte(3)
      ..write(obj.profile);
  }
}

class ProfileAdapter extends TypeAdapter<Profile> {
  @override
  final typeId = 2;

  @override
  Profile read(BinaryReader reader) {
    var numOfFields = reader.readByte();
    var fields = <int, dynamic>{
      for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return Profile()
      ..name = fields[0] as String
      ..lang = fields[1] as String
      ..emailId = fields[2] as String
      ..mobileNumber = fields[3] as String
      ..district = fields[4] as String
      ..state = fields[5] as String
      ..city = fields[6] as String
      ..pinCode = fields[7] as String
      ..profilePic = fields[8] as String;
  }

  @override
  void write(BinaryWriter writer, Profile obj) {
    writer
      ..writeByte(3)
      ..writeByte(0)
      ..write(obj.name)
      ..writeByte(1)
      ..write(obj.lang)
      ..writeByte(2)
      ..write(obj.emailId)
      ..writeByte(3)
      ..write(obj.mobileNumber)
      ..writeByte(4)
      ..write(obj.district)
      ..writeByte(5)
      ..write(obj.state)
      ..writeByte(6)
      ..write(obj.city)
      ..writeByte(7)
      ..write(obj.pinCode)
      ..writeByte(8)
      ..write(obj.profilePic);
  }
}
Run Code Online (Sandbox Code Playgroud)