Хранение списка в большом двоичном объекте с помощью sqflite

Я ищу пример хранения общего объекта Dart (обычно List<MyObject>) в столбце Blob с sqflite (и извлекаю его обратно, пожалуйста), предполагая, что он будет хранить его как двоичные данные.

MyObject - это объект, используемый моим приложением, его содержимое здесь не важно, поскольку я ищу общий / универсальный метод.

Может ли кто-нибудь быть достаточно любезным, чтобы предоставить фрагмент?

Документация по этой теме для Dart встречается редко. Ближайшее, что я смог найти, - это маршалинг объекта как Uint8List что-то вот так или что-то в этом роде, но я не мог понять / применить их.

Я обнаружил эту аналогичную проблему, где разработчик заканчивает преобразование своих списков в строку ... Мы действительно не можем сделать лучше (то есть более эффективно)?

Большое спасибо за вашу помощь.

Патрик


person Patrick    schedule 28.12.2019    source источник
comment
Думаю, лучшим вариантом будет преобразование в JSON и снова в список JSON. Будет легко конвертировать из одного в другой и наоборот.   -  person OMi Shah    schedule 28.12.2019
comment
Спасибо за быстрый ответ. Однако мне интересно, будет ли это эффективным решением по сравнению с хранением в виде двоичных данных. Не могли бы вы что-нибудь по этому поводу сказать?   -  person Patrick    schedule 28.12.2019
comment
вы нашли лучшее решение?   -  person DNS    schedule 11.03.2021


Ответы (1)


Вам нужно преобразовать MyObject в сериализованный поток байтов с помощью BytesBuilder (), а затем вставить в большой двоичный объект sqflite как Uint8List. Для списка есть несколько стратегий:

  • Если размер MyObject одинаков для всех элементов в списке, просто сохраните их один за другим.
  • Если размер является переменным, сохраните сначала количество байтов для каждого из них, а затем сам объект, повторяя для всех элементов в списке.
  • Или сохраните каждый объект MyObject с разделителем. Разделитель должен быть уникальным: ни один разделитель не должен быть частью каких-либо экземпляров MyObject.

Обычно второй вариант более надежен и гибок. Пример:

MyList = getTheListOfMyObject();
final bytes = BytesBuilder();
for(int i = 0; i < myList.length; i++) {    
    bytes.addByte(sizeOfMyObject[i]);
    // Here starts the serialization of MyObject
    // only you know how it is structured, but
    // every member could be expressed as series of bytes
    // and remember to think on how to deserialize them
    // in order to recover MyObject from the sqflite BLOB
    bytes.addByte(firstByteOfMyObject[i]);
    bytes.addByte(secondByteOfMyObject[i]);
    bytes.addByte(thirdByteOfMyObject[i]);
    // and so on.
}
// Then retrieve the full stream as a Uint8List:
final blob = bytes.toBytes();
Map<String, dynamic> map = {
  'id': 1,
  'my_list': blob,
};
res = await _db.insert("my_table", map);

Таблица для примера: CREATE TABLE my_table (id INTEGER, my_list BLOB)

Лучше всего реализовать сериализацию / десериализацию MyObject внутри класса MyObject. Подпрограммы базы данных должны получить Uint8List от получателя перед его сохранением и должны передать байты сеттеру, чтобы класс восстановил структуру объекта. Таким образом, вы правильно инкапсулируете детали реализации объекта.

person J. Pelaez    schedule 24.03.2021