Во-первых, я знаю, что не рекомендуется хранить файлы (данные файлов) в базе данных, но это можно сделать. Однако эти базы данных совместно используются приложениями, и файлы должны перемещаться вместе с базой данных.
Сценарий: Когда в этом приложении создаются заметки об исследованиях, можно создавать вложения файлов. Это все от пи 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