【问题标题】:Room query with ID returns null带有 ID 的房间查询返回 null
【发布时间】:2019-10-01 09:36:38
【问题描述】:

我正在为我的数据库使用房间持久性库。我的一个查询返回 null,我不明白为什么:

实体:

@Entity
public class Item{

    @PrimaryKey (autoGenerate = true)
    @ColumnInfo (name = "I_ID")
    private final int iId;

    @ColumnInfo (name = "I_Name")
    private final String iName;

    public int getIId() {
        return iId;
    }

    public String getIName() {
        return iName;
    }

    public Item(int iId, String iName) {
        this.iId = iId;
        this.iName = iName;
    }
}

道:

@Dao
public interface ItemDao {
    @Query("SELECT * FROM Item WHERE I_ID = :iId")
    Item getItemById(int iId);
}

此查询显示警告:Return value of the method is never used。 它总是返回 null,即使我确定数据库中存在具有给定 ID 的项目。有人可以帮帮我吗?

【问题讨论】:

  • 我发现你的代码有问题
  • 在我的回答中尝试进入下面的列表
  • 显示您在哪里使用 getItemById() 方法以及如何使用??

标签: android android-room


【解决方案1】:

我发现尝试这样使用:

@Dao
public interface ItemDao {
@Query("SELECT * FROM item WHERE I_ID = :iId")
List<Item> getItemById(int iId);
}

【讨论】:

    【解决方案2】:

    给定的代码似乎没有任何问题。而是您没有检查由于 id 不是 Item 的 id 而没有返回任何结果的可能结果。

    使用上面的 Item 类,以及稍微修改的 ItemDao(允许插入):-

    @Dao
    public interface ItemDao {
        @Query("SELECT * FROM Item WHERE I_ID = :iId")
        Item getItemById(int iId);
    
        @Insert
        long insert(Item item); //<<<<<<<<<< ADDED 
    }
    

    @Database 为 :-

    @androidx.room.Database(version = 1,entities = {Item.class})
    public abstract class Database extends RoomDatabase {
    
        public abstract ItemDao itemDao();
    }
    

    以及活动中的以下代码:-

    public class MainActivity extends AppCompatActivity {
    
        Database mDB;
        ItemDao mItemDao;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mDB = Room.databaseBuilder(this,Database.class,"mydb")
                    .allowMainThreadQueries()
                    .build();
            mItemDao = mDB.itemDao();
    
            mItemDao.insert(new Item(1,"Item1"));
            mItemDao.insert(new Item(2,"Item2"));
            logItemInfo(mItemDao.getItemById(1));
            logItemInfo(mItemDao.getItemById(2));
        }
    
        private void logItemInfo(Item i) {
            Log.d("ITEMINFO","Item is " + i.getIName() + " ID is " + i.getIId());
        }
    }
    

    日志中的结果输出是:-

    2019-10-02 07:36:41.180 D/ITEMINFO: Item is Item1 ID is 1
    2019-10-02 07:36:41.181 D/ITEMINFO: Item is Item2 ID is 2
    

    看来您的问题是您可能将一个 id 传递给实际上不是正在使用的 id 的选择。

    例如使用:-

        mItemDao.deleteAllItems(); //<<<<<<<<<<< Added to Item Dao as @Query("DELETE FROM Item") to make this rerunnable
    
        mItemDao.insert(new Item(1,"Item1")); //<<<<<<<<<< AS WAS
        mItemDao.insert(new Item(2,"Item2")); //<<<<<<<<<< AS WAS
        logItemInfo(mItemDao.getItemById(1)); //<<<<<<<<<< AS WAS
        logItemInfo(mItemDao.getItemById(2)); //<<<<<<<<<< AS WAS
        logItemInfo(mItemDao.getItemById(100)); //<<<<<<<<<< ATTEMPT TO GET AN INVALID ID
    

    导致空指针异常(尝试访问 logItemInfo 方法中的项目时),因为 没有 ID 为 100 的项目,这可能是问题的原因你已经描述了(即你正在请求一个不存在的行)。

    logItemInfo 方法修改为:-

    private void logItemInfo(Item i) {
        if (i == null) {
            Log.d("ITEMINFO","NOT AN ITEM");
            return;
        }
        Log.d("ITEMINFO","Item is " + i.getIName() + " ID is " + i.getIId());
    }
    

    结果输出(而不是异常)是:-

    2019-10-02 07:57:21.189 11388-11388/aso.asofkinroom D/ITEMINFO: Item is Item1 ID is 1
    2019-10-02 07:57:21.190 11388-11388/aso.asofkinroom D/ITEMINFO: Item is Item2 ID is 2
    2019-10-02 07:57:21.190 11388-11388/aso.asofkinroom D/ITEMINFO: NOT AN ITEM
    

    【讨论】:

      猜你喜欢
      • 2021-09-01
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-21
      相关资源
      最近更新 更多