当前位置: 首页 > 知识库问答 >
问题:

房间。第一个查询返回空值

丰胤运
2023-03-14

在我的Android项目中,我使用Room库来处理SQLite数据库。我使用我的数据库来保存国家电话代码。我的数据库预加载了两个国家(watch大众数据库与国家代码(道:电话代码道)功能);

@Database(entities = [CountryCode::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun createPhoneCodeDao(): PhoneCodeDao

companion object {
    @Volatile
    private var INSTANCE: AppDatabase? = null

    fun getDatabase(context: Context): AppDatabase {
        val tempInstance = INSTANCE
        if (tempInstance != null) {
            return tempInstance
        }
        synchronized(this) {
            val instance = Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                "database"
            ).addCallback(PrepopulationCallback)
                .build()
            INSTANCE = instance
            return instance
        }
    }
}

object PrepopulationCallback : RoomDatabase.Callback() {
    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        INSTANCE?.let { database ->
            GlobalScope.launch(Dispatchers.IO) {
                populateDatabaseWithCountryCodes(database.createPhoneCodeDao())
            }
        }
    }

    private fun populateDatabaseWithCountryCodes(dao: PhoneCodeDao) {
        val spainPhoneCode = CountryCode(0, "Spain", 34)
        val rusPhoneCode = CountryCode(1, "Russia", 7)
        val list = LinkedList<CountryCode>()
        list.add(spainPhoneCode)
        list.add(rusPhoneCode)
        dao.insertAllCountryCodes(list)
    }
}
}

国家代码实体

@Entity(tableName = "country_code")
data class CountryCode(
@SerializedName("order")
@ColumnInfo(name = "order_list") val order: Int,
@SerializedName("name")
@ColumnInfo(name = "country_name_eng") val name: String,
@SerializedName("phone_code")
@ColumnInfo(name = "phone_code") val phoneCode: Int
) {
@ColumnInfo(name = "id")
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

DAO接口

@Dao
interface PhoneCodeDao {

@Insert
fun insertAllCountryCodes(list: List<CountryCode>)

@Query("SELECT phone_code FROM country_code WHERE order_list = :order")
fun selectCountryCodeByOrder(order: Int): Int

}

在我的应用程序中,我按顺序选择国家代码(观察函数selectCountryCodeByOrder(order:Int):Int)。我在异步{}协同例程中异步调用此函数。但我有一个相当奇怪的错误:安装后,我在设备上首次启动我的应用程序并进行查询-查询结果为0(这意味着没有结果)。但在下一次查询和下一次启动期间,它工作得非常出色-它根据order参数返回7和34。所以我对这个错误感到非常困惑。请帮助我解决这个问题

共有2个答案

归明诚
2023-03-14

这并不奇怪,数据库是异步预填充的,并且您不会收到实际插入数据的通知。

您可以查看官方AAC样本,特别是要通知的BasicSample

  • 您需要有一个LiveData

.

private final MutableLiveData<Boolean> mIsDatabaseCreated = new MutableLiveData<>();

public static AppDatabase getInstance(final Context context, final AppExecutors executors) {
    if (sInstance == null) {
        synchronized (AppDatabase.class) {
            if (sInstance == null) {
                sInstance = buildDatabase(context.getApplicationContext(), executors);
                sInstance.updateDatabaseCreated(context.getApplicationContext());
            }
        }
    }
    return sInstance;
}

/**
 * Build the database. {@link Builder#build()} only sets up the database configuration and
 * creates a new instance of the database.
 * The SQLite database is only created when it's accessed for the first time.
 */
private static AppDatabase buildDatabase(final Context appContext,
        final AppExecutors executors) {
    return Room.databaseBuilder(appContext, AppDatabase.class, DATABASE_NAME)
            .addCallback(new Callback() {
                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);
                    executors.diskIO().execute(() -> {
                        // ...create the database here

                        // notify that the database was created and it's ready to be used
                        database.setDatabaseCreated();
                    });
                }
            })
        .build();
}

/**
 * Check whether the database already exists and expose it via {@link #getDatabaseCreated()}
 */
private void updateDatabaseCreated(final Context context) {
    if (context.getDatabasePath(DATABASE_NAME).exists()) {
        setDatabaseCreated();
    }
}

private void setDatabaseCreated(){
    mIsDatabaseCreated.postValue(true);
}

>

  • 您需要一个 MediatorLiveData 来使用 0 结果,当结果尚不可用时

    mObservableProducts.addSource(mDatabase.productDao().loadAllProducts(),
            productEntities -> {
                if (mDatabase.getDatabaseCreated().getValue() != null) {
                    mObservableProducts.postValue(productEntities);
                }
            });
    

    您可以将结果公开为LiveData

  • 米元凯
    2023-03-14

    这是因为当数据库为空时,它可能正在查询数据库。所以解决这个问题的最好方法是返回一个LiveData,而不是一个原始的int。然后,当数据库被填充时,LiveData将负责更新UI。

     @Query("SELECT phone_code FROM country_code WHERE order_list = :order")
    fun selectCountryCodeByOrder(order: Int): LiveData<SomeType>
    
     类似资料:
    • 问题内容: 我试图加快PHP脚本的速度,目前正在Mysql域中推送一些PHP逻辑。如果第一个Select不返回行或计数为零,是否可以进行其他选择查询? 请记住,第一个查询需要首先运行,并且 仅 当第一个查询返回空集 时才 应激活第二个查询。 对于上面的2个查询,我有这段代码,但似乎每个查询运行两次(一次计数,一次返回)。有一个更好的方法吗? 问题答案: 一种选择是使用有: SQL小提琴演示 这将从

    • 我正在尝试加速一个PHP脚本,目前我正在推动一些PHP逻辑在Mysql领域的东西。如果第一个select没有返回行或计数为零,是否有方法进行不同的select查询? 请记住,需要首先运行第一个查询,只有在第一个查询返回一个空集时才应激活第二个查询。 对于上面的2个查询,我有这段代码,但它似乎要运行每个查询两次(一次用于计数,一次用于返回)。有没有更好的办法做到这一点?

    • 我是新来的和我试图我的得到一个从它。我试图这样做的它与这是id但问题是我不知道如何返回目标从。 这就是<代码>刀 这是Repository类

    • 我使用的是socket.io/node.js/express。当我使用socket.join(“room”)加入socket.io房间时,它会注册该房间,但用户只加入“room”。 这个命令显示了所有的房间,它同时返回'room'和'',尽管我从未创建过'room: 任何帮助都将不胜感激,这是非常奇怪的行为:( 编辑:以下是相关的服务器代码

    • 问题内容: 我正在使用MySQL存储视频游戏数据。我有用于标题,平台,标签,徽章,评论,开发人员,出版商等的表… 当某人正在观看游戏时,最好有一个查询来返回与游戏相关的所有数据,还是最好使用多个查询?直观地,由于我们具有评论,将它们包括在同一查询中似乎毫无意义,因为它们需要分页。但是在其他情况下,我不确定是否要分解查询或使用两个查询… 我有点担心性能,因为我现在加入游戏下表:开发人员,发行者,元标

    • 问题内容: 桌子: 我的查询: 我收到“ MySQL子查询返回多个行”错误。 我知道此查询可以使用以下查询的解决方法: 然后使用php循环遍历结果并执行以下查询以获取和回显它: 但是我认为可能会有更好的解决方案? 问题答案: 简单的解决方法是在子查询中添加一个子句: 一个更好的选择(就性能而言)是使用联接: