【问题标题】:ROOM persistence library update and delete won´t change anythingROOM 持久性库更新和删除不会改变任何东西
【发布时间】:2019-10-05 22:03:27
【问题描述】:

我正在编写小型应用程序,我为此使用了空间。 SQLite 包装器。 就我的代码工作而言,有些功能它们不起作用。此外,文档似乎非常不完整,或者在某些方面是错误的。比如dao注解@Update和@Delete。 我慢慢地对使用这个框架感到困惑,我想回到使用 SQLite API 来代替它。你觉得房间怎么样?

现在是我想问的主要问题。我将向您展示我的代码,也许您会看到,为什么不能正常工作。

首先,我的实体和道。它应该代表一个音频文件。

@Entity(tableName = "audiofile")
public class AudioFile
{
    @PrimaryKey(autoGenerate = true)
    private long id;

    @ColumnInfo(name = "title")
    private String title;

    @ColumnInfo(name = "artist")
    private String artist;

    @ColumnInfo(name = "path")
    private String path;

    @ColumnInfo(name = "duration")
    private long duration;

@Dao
public interface AudioFileDao
{
    @Query("SELECT * FROM audiofile WHERE title LIKE :title")
    AudioFile getAudioFile(String title);

    @Query("SELECT * FROM audiofile")
    List<AudioFile> getAll();

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void initAudioFiles(AudioFile... audioFiles);

    @Update
    void updateAudioFile(AudioFile... audioFiles);

//        @Query("DELETE FROM audiofile WHERE id = :audioFileId")
    @Delete
    void deleteAudioFile(AudioFile audioFile);

    @Insert
    void insertAll(AudioFile... audioFiles);

    @Insert
    long insertAudioFile(AudioFile audioFile);
}

那是常规的数据库管理器。

@Database(entities = {AudioFile.class}, version = 1)
public abstract class DbManager extends RoomDatabase
{

    private static DbManager INSTANCE;

    public abstract AudioFile.AudioFileDao audioFileDao();

    public static DbManager getDbManager(Context ctx){
        if (INSTANCE == null){
            INSTANCE = Room.databaseBuilder(ctx.getApplicationContext(), DbManager.class, "playlist").build();
        }
        return INSTANCE;
    }

    public static void destroyInstance(){
        INSTANCE = null;
    }
}

Aaaand 这是我的测试,它产生了我所有的担忧:

@RunWith(JUnit4.class)
public class DbManagerAndroidTest
{
    private AudioFile.AudioFileDao audioFileDao;
    private DbManager db;

    @Before
    public void createDb()
    {
        Context ctx = InstrumentationRegistry.getInstrumentation().getContext();

        db = Room.inMemoryDatabaseBuilder(ctx, DbManager.class).build();
        audioFileDao = db.audioFileDao();
    }

    /**
     * Test CRUD
     */
    @Test
    public void writeAndRead()
    {
        AudioFile audioFile = new AudioFile.Builder("title")
            .withArtist("artist")
            .withDuration(5)
            .withPath("/this/is/path")
            .build();

        audioFileDao.insertAudioFile(audioFile);
        assertTrue(db.audioFileDao().getAll().size() > 0);
        assertEquals("title", db.audioFileDao().getAll().get(0).getTitle());

        audioFile.setArtist("yo-mama");
        //It won´t update
        audioFileDao.updateAudioFile(audioFile);

        assertEquals("yo-mama", audioFileDao.getAudioFile("title").getArtist());
        //It won´t delete
        audioFileDao.deleteAudioFile(audioFile);
        assertEquals(0, audioFileDao.getAll().size());
    }

    @After
    public void tearDown(){
        db.clearAllTables();
        db.close();
    }
}

提前感谢您的帮助。这件事让我很生气。

【问题讨论】:

    标签: java sqlite android-sqlite android-room


    【解决方案1】:

    现在是我想问的主要问题。我将向您展示我的代码,也许您会看到,为什么不能正常工作。

    我相信您的问题是,当您插入 AudioFile 时,id 未设置,因此在 AudioFile 对象 audioFile 中为 0。但是,当插入时,id 将自动生成,并且不会为 0,而是可能是某个时间插入的 AudioFile 对象的数量 + 1。

    如果不设置 id 然后使用相同的 AudioFile 对象来更新/删除,将尝试使用 0 的 id 更新删除。 不会有这样的行。

    修复,假设 AudioFile 存在 setId 方法,但不处理失败的插入可以使用:-

    audioFile.setId(audioFileDao.insertAudioFile(audioFile));
    

    可以处理未导致异常的失败插入的修复可能是:-

    long insertedId = audioFileDao.insertAudioFile(audioFile);
    if (insertedId > 0) {
        audioFile.setId(insertedId);
    } else {
        //......... handle not inserted
    }
    

    示例/演示

    以下代码在运行时显示上述内容(您的 Entity 和 Dao 已按原样复制):-

        ...... database built
        mAudioFileDao = mAppDB.audioFileDao();
    
        AudioFile a = new AudioFile();
        a.setTitle("MySong");
        a.setDuration(5);
        a.setArtist("Fred");
        a.setPath("/thepath");
    
        logAudioFile(a,"Before Insert into DB");
        long currentId = mAudioFileDao.insertAudioFile(a); //<<<<<<<<<< INSERT INTO DB
        logAudioFile(a,"Immediately after Insert. ID returned from insert is " + currentId);
        a.setId(currentId); //<<<<<<<<<< SET the the id of the AudioFile object a
        logAudioFile(a,"After setting the ID to " + currentId);
        mAudioFileDao.updateAudioFile(a);
        List<AudioFile> audioFileList = mAudioFileDao.getAll();
        for (AudioFile af: audioFileList) {
            logAudioFile(af,"Extracted from DB");
        }
        mAudioFileDao.deleteAudioFile(a);
        Log.d("AUDIOFILEINFO","Attempt to delete Audio File undertaken");
        audioFileList = mAudioFileDao.getAll();
        for (AudioFile af: audioFileList) {
            logAudioFile(af,"After deletion");
        }
    

    logAudioFile 方法是:-

    private void logAudioFile(AudioFile a, String extra) {
        Log.d(
                "AUDIOFILEINFO",
                "Title is " + a.getTitle() +
                        " ID is " + a.getId() +
                        "\n\tExtra Info is " + extra
        );
    }
    

    结果(上面的日志):-

    2019-10-06 11:03:39.757 D/AUDIOFILEINFO: Title is MySong ID is 0
            Extra Info is Before Insert into DB
    2019-10-06 11:03:39.808 D/AUDIOFILEINFO: Title is MySong ID is 0
            Extra Info is Immediately after Insert. ID returned from insert is 1
    2019-10-06 11:03:39.808 D/AUDIOFILEINFO: Title is MySong ID is 1
            Extra Info is After setting the ID to 1
    2019-10-06 11:03:39.829 D/AUDIOFILEINFO: Title is MySong ID is 1
            Extra Info is Extracted from DB
    2019-10-06 11:03:39.831 D/AUDIOFILEINFO: Attempt to delete Audio File undertaken
    

    你觉得房间怎么样?

    这是在征求意见,所以是题外话。

    【讨论】:

    • @Raven 然后请勾选已回答的问题。附言添加了一个演示。
    猜你喜欢
    • 2018-08-20
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 2022-09-26
    相关资源
    最近更新 更多