2

我正在尝试存储我的应用程序经常从 API 获得的一些变量的值。我只想在变量更改其值以向用户显示某种“更改历史”时才向数据库表添加新行。我正在使用ROOM来存储数据。

我创建了一个实体:

@Entity(tableName = "balance_history",
        indices = {@Index("received_at")})
public class BalanceResponse {
    //region getters & setters
    ...
    //endregion

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private long mId;

    @ColumnInfo(name = "money")
    private double mMoney;

    @ColumnInfo(name = "received_at")
    private DateTime mReceivedAt;
}

道:

@Dao
public abstract class DatabaseDao {
    @Query("SELECT * FROM balance_history ORDER BY received_at DESC LIMIT 1")
    public abstract LiveData<BalanceResponse> selectLatestBalanceResponse();

    public void insertNewBalanceResponse(BalanceResponse balanceResponse) {
        String sqlRequest = "INSERT INTO balance_history(money, received_at) " +
                "SELECT ?, ? " +
                "WHERE NOT EXISTS(SELECT 1 FROM (SELECT * FROM balance_history ORDER BY received_at DESC LIMIT 1) WHERE money = ?);";

        SupportSQLiteDatabase database = DatabaseStorage.getInstance().getAppDatabase().getOpenHelper().getWritableDatabase();
        database.execSQL(sqlRequest,
                new Object[]{balanceResponse.getMoney(), balanceResponse.getReceivedAt().getMillis(), balanceResponse.getMoney()});
    }
}

数据库对象:

@Database(entities = {BalanceResponse.class}, version = 1)
@TypeConverters(DateTimeConverter.class)
public abstract class AppDatabase
        extends RoomDatabase {

    public abstract DatabaseDao getDatabseDao();
}

用于存储单个数据库对象的 Singleton:

public class DatabaseStorage {
    //region singleton
    private static final DatabaseStorage ourInstance = new DatabaseStorage();

    public static DatabaseStorage getInstance() {
        return ourInstance;
    }
    //endregion

    @NonNull
    public AppDatabase getAppDatabase() {
        return mAppDatabase;
    }

    @NonNull
    private AppDatabase mAppDatabase;

    private DatabaseStorage() {
        mAppDatabase =
                Room.databaseBuilder(MyApp.getAppContext(), AppDatabase.class, "app-database")
                .build();
    }

}

我在 Activity 的 onCreate() 中实例化的视图模型:

public class BalanceView implements Observer<BalanceResponse> {

    private LiveData<BalanceResponse> mLatestBalanceResponse;

    public BalanceView(LifecycleOwner lifecycleOwner){
        mLatestBalanceResponse = DatabaseStorage.getInstance().getAppDatabase().getDatabseDao()
                .selectLatestBalanceResponse();
        mLatestBalanceResponse.observe(lifecycleOwner, this);
        //finding views here
    }

    @Override
    public void onChanged(@Nullable BalanceResponse balanceResponse) {
        //displaying changes here
    }
}

我预计每次当方法DatabaseDao.insertNewBalanceResponse()插入一行时都会触发BalanceView.onChanges()方法。

实际上BalanceView.onChanges()方法永远不会被解雇。为什么呢?我怎样才能做到这一点?

ps 但是,如果我将方法DatabaseDao.insertNewBalanceResponse()替换为原始方法:

@Insert
public abstract Long insertBalanceResponse(BalanceResponse balanceResponse);

一切正常,方法onChange()被调用。但是这种插入语句不符合我的需要。

4

1 回答 1

0

我有同样的问题,在这里我得到了解决这个问题的提示。

@Dao
interface RawDao {
     @RawQuery
     User getUserViaQuery(SupportSQLiteQuery query);
}
SimpleSQLiteQuery query = new SimpleSQLiteQuery("SELECT * FROM User WHERE id = ? LIMIT 1",
         new Object[]{userId});
User user2 = rawDao.getUserViaQuery(query);

有关更多详细信息,请查看https://developer.android.com/reference/android/arch/persistence/room/RawQuery

于 2018-07-26T06:22:03.070 回答