Как настроить TypeConverter для текста (большого двоичного объекта) в поле файла базы данных помещения? - PullRequest
0 голосов
/ 12 марта 2020

Во-первых, я знаю, что не рекомендуется хранить файлы (данные файлов) в базе данных, но это можно сделать. Однако эти базы данных совместно используются приложениями, и файлы должны перемещаться вместе с базой данных.

Сценарий: Когда в этом приложении создаются заметки об исследованиях, можно создавать вложения файлов. Это все от пи c до текста в офисный файл (docx, xlsx) и т. Д. c. Существует версия для настольного компьютера, которая уже существует, которая делает все это, но есть необходимость / необходимость версии Android.

Моя проблема (обновлено 13.03.20): My FilesByNoteDao не выполняется во время запроса, содержащего поле FileData (ошибка: невозможно преобразовать BLOB-объект в строку). У меня есть класс File @Entity, который имеет FileID, Filename, FileData (Text Blob). Тип данных поля FileData в базе данных: TEXT . У меня возникают трудности при преобразовании этого текстового блога в строку через FilesByNoteDao, который обрабатывает запросы этих 3 полей, в метод List @Query. Я думаю, что проблема состоит в том, что 1) не полностью понимает TypeConverter и 2) как преобразовать данные поля FileData при выполнении запроса SQL.

Что я заметил (см. Room FilesByNoteDao_impl ниже), созданное Room, пытаясь открыть FileData как строку перед преобразованием, которое моя сущность объявляет не FileData как строку, а как byte []. Я не уверен, как решить эту проблему?

Что я пробовал / сделал: Я прочитал несколько хороших примеров на StackOverflow и Developer. Android (см. Ссылки ниже примеров ). Я пытался использовать концепции, которыми поделились другие, но мне кажется, что я что-то упускаю, и кто-то может помочь.

Ниже я расскажу о том, как я думал и в данный момент настроен и вызван TypeConverter, а также Entity, Dao и База данных настроена:

TypeConverter:

import androidx.room.TypeConverter;
public class FileTypeConverter {

    @TypeConverter
    public byte[] toFileBytes(String value){
            return value.getBytes();
    }
    @TypeConverter
    public String toFileString(byte[] bytes){
        return new String(bytes);
    }
}

Entity

@Entity(tableName = "Files")
public class Files {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "FileID")
    private int fileID;

    @ColumnInfo(name = "FileName")
    private String fileName;

    @TypeConverters(FileTypeConverter.class)
    @ColumnInfo(name = "FileData", typeAffinity = ColumnInfo.TEXT)
    private String fileData;

    public Files(String fileName, String fileData){
        this.fileName = fileName;
        this.fileData = fileData;
    }
}

Dao:

@Dao
public interface FilesByNoteDao {
    @Insert
    void insert(FilesByNote filesByNote);

    @Query("SELECT f.FileID, f.FileName, f.FileData FROM Files AS f \n" +
            "LEFT JOIN Files_By_Note AS fbn ON f.FileID=fbn.FileID \n" +
            "WHERE fbn.NoteID=:noteID")
    List<Files> getFilesByNote(final int noteID);

    @Query("SELECT Notes.NoteID, SourceID, CommentID, QuestionID, QuoteID, TermID, TopicID, Deleted FROM Notes \n" +
            "LEFT JOIN Files_By_Note ON Notes.NoteID=Files_By_Note.NoteID\n" +
            "WHERE Files_By_Note.FileID=:fileID")
    List<Notes> getNotesByFile(final int fileID);
}

База данных:

@Database(entities = {AuthorBySource.class, Authors.class,  Comments.class, Files.class, FilesByNote.class,
        Notes.class, Questions.class, Quotes.class, Sources.class, Terms.class, Topics.class}, version = 1)
public abstract class ResearchDatabase extends RoomDatabase {
    private static ResearchDatabase INSTANCE;
    public abstract AuthorBySourceDao getAuthorBySourceDao();
    public abstract AuthorsDao getAuthorsDao();
    public abstract CommentsDao getCommentsDao();
    public abstract FilesDao getFilesDao();

    @TypeConverters(FileTypeConverter.class)
    public abstract FilesByNoteDao getFilesByNoteDao();

    public abstract NotesDao getNotesDao();
    public abstract QuestionsDao getQuestionsDao();
    public abstract QuotesDao getQuotesDao();
    public abstract SourcesDao getSourcesDao();
    public abstract TermsDao getTermsDao();
    public abstract TopicsDao getTopicsDao();

    public static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {

        }
    };

    // ... other code ...
}

FilesByNoteDao_impl. java

    @Override
  public List<Files> getFilesByNote(final int noteID) {
    final String _sql = "SELECT f.FileID, f.FileName, f.FileData FROM Files AS f \n"
            + "LEFT JOIN Files_By_Note AS fbn ON f.FileID=fbn.FileID \n"
            + "WHERE fbn.NoteID=?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, noteID);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
      final int _cursorIndexOfFileID = CursorUtil.getColumnIndexOrThrow(_cursor, "FileID");
      final int _cursorIndexOfFileName = CursorUtil.getColumnIndexOrThrow(_cursor, "FileName");
      final int _cursorIndexOfFileData = CursorUtil.getColumnIndexOrThrow(_cursor, "FileData");
      final List<Files> _result = new ArrayList<Files>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final Files _item;
        final String _tmpFileName;
        _tmpFileName = _cursor.getString(_cursorIndexOfFileName);
        final byte[] _tmpFileData;
        final String _tmp;
        _tmp = _cursor.getString(_cursorIndexOfFileData);       // <-- Not sure why it is doing this?
        _tmpFileData = __fileTypeConverter.toFileBytes(_tmp);
        _item = new Files(_tmpFileName,_tmpFileData);
        final int _tmpFileID;
        _tmpFileID = _cursor.getInt(_cursorIndexOfFileID);
        _item.setFileID(_tmpFileID);
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }

Ссылочные ссылки, которые я использовал:

Room TypeConverter

Room TypeConverter не работает

Android Проблема Room / TypeConverter при получении списка объектов

Android Комната - Как добавить TypeConverter

https://developer.android.com/reference/androidx/room/TypeConverters

https://developer.android.com/reference/androidx/room/TypeConverter

...