Room的DAO实现未正确生成。

huangapple go评论90阅读模式
英文:

Room's DAOimpl not generating correctly

问题

我正在尝试使用Room库访问数据库,但是DAO实现未生成好。
在我的DAO接口中,我有:

  1. @Query("SELECT b.position,b.name,b.capacity,b.currentAmount, it.name FROM bottles AS b " +
  2. "INNER JOIN bottle_ingredient AS bi ON bi.bottlePos=b.position " +
  3. "INNER JOIN ingredient_types AS it ON it.id=bi.ingredientId" +
  4. " WHERE position = :position")
  5. Bottle getBottleWithIngredientFromPosition(int position);

而我的Bottle类如下:

  1. public class Bottle {
  2. public int position;
  3. public String name;
  4. public int capacity;
  5. public int currentAmount;
  6. public String ingredientName;
  7. //Constructor, getters and setters
  8. }

但是当我使用DAO创建一个新的Bottle对象时,它的"ingredientName"属性为空。我检查了Room生成的实现,如下所示:

  1. @Override
  2. public Bottle getBottleWithIngredientFromPosition(final int position) {
  3. final String _sql = "SELECT b.position,b.name,b.capacity,b.currentAmount, it.name FROM bottles AS b INNER JOIN bottle_ingredient AS bi ON bi.bottlePos=b.position INNER JOIN ingredient_types AS it ON it.id=bi.ingredientId WHERE position = ?";
  4. final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
  5. int _argIndex = 1;
  6. _statement.bindLong(_argIndex, position);
  7. __db.assertNotSuspendingTransaction();
  8. final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
  9. try {
  10. final int _cursorIndexOfPosition = 0;
  11. final int _cursorIndexOfName = 1;
  12. final int _cursorIndexOfCapacity = 2;
  13. final int _cursorIndexOfCurrentAmount = 3;
  14. final Bottle _result;
  15. if(_cursor.moveToFirst()) {
  16. final int _tmpPosition;
  17. _tmpPosition = _cursor.getInt(_cursorIndexOfPosition);
  18. final String _tmpName;
  19. if (_cursor.isNull(_cursorIndexOfName)) {
  20. _tmpName = null;
  21. } else {
  22. _tmpName = _cursor.getString(_cursorIndexOfName);
  23. }
  24. final int _tmpCapacity;
  25. _tmpCapacity = _cursor.getInt(_cursorIndexOfCapacity);
  26. final int _tmpCurrentAmount;
  27. _tmpCurrentAmount = _cursor.getInt(_cursorIndexOfCurrentAmount);
  28. _result = new Bottle(_tmpPosition,_tmpName,_tmpCapacity,_tmpCurrentAmount,null);
  29. } else {
  30. _result = null;
  31. }
  32. return _result;
  33. } finally {
  34. _cursor.close();
  35. _statement.release();
  36. }
  37. }

我们可以看到它调用构造函数时,最后一个参数为null,并且从数据库中获取该值的尝试。
我手动下载了SQLite数据库并运行了查询,它按预期工作。

英文:

I am trying to use Room library to access a DB, but DAO implementation is not generating well.
In my DAO interface i have:

  1. @Query("SELECT b.position,b.name,b.capacity,b.currentAmount, it.name FROM bottles AS b " +
  2. "INNER JOIN bottle_ingredient AS bi ON bi.bottlePos=b.position " +
  3. "INNER JOIN ingredient_types AS it ON it.id=bi.ingredientId" +
  4. " WHERE position = :position")
  5. Bottle getBottleWithIngredientFromPosition(int position);

And my bottle class is the following:

  1. public class Bottle {
  2. public int position;
  3. public String name;
  4. public int capacity;
  5. public int currentAmount;
  6. public String ingredientName;
  7. //Constructor, getters and setters
  8. }

But when i create a new Bottle object with the DAO it gets created with "ingredientName" as null. I checked the implementation Room generates and is the following:

  1. @Override
  2. public Bottle getBottleWithIngredientFromPosition(final int position) {
  3. final String _sql = "SELECT b.position,b.name,b.capacity,b.currentAmount, it.name FROM bottles AS b INNER JOIN bottle_ingredient AS bi ON bi.bottlePos=b.position INNER JOIN ingredient_types AS it ON it.id=bi.ingredientId WHERE position = ?";
  4. final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
  5. int _argIndex = 1;
  6. _statement.bindLong(_argIndex, position);
  7. __db.assertNotSuspendingTransaction();
  8. final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
  9. try {
  10. final int _cursorIndexOfPosition = 0;
  11. final int _cursorIndexOfName = 1;
  12. final int _cursorIndexOfCapacity = 2;
  13. final int _cursorIndexOfCurrentAmount = 3;
  14. final Bottle _result;
  15. if(_cursor.moveToFirst()) {
  16. final int _tmpPosition;
  17. _tmpPosition = _cursor.getInt(_cursorIndexOfPosition);
  18. final String _tmpName;
  19. if (_cursor.isNull(_cursorIndexOfName)) {
  20. _tmpName = null;
  21. } else {
  22. _tmpName = _cursor.getString(_cursorIndexOfName);
  23. }
  24. final int _tmpCapacity;
  25. _tmpCapacity = _cursor.getInt(_cursorIndexOfCapacity);
  26. final int _tmpCurrentAmount;
  27. _tmpCurrentAmount = _cursor.getInt(_cursorIndexOfCurrentAmount);
  28. _result = new Bottle(_tmpPosition,_tmpName,_tmpCapacity,_tmpCurrentAmount,null);
  29. } else {
  30. _result = null;
  31. }
  32. return _result;
  33. } finally {
  34. _cursor.close();
  35. _statement.release();
  36. }
  37. }

As we can see it calls the constructor with last parameter as null and never tries to get it from the DB.
I downloaded SQLite DB and run the query manually and it works as espected

答案1

得分: 1

尝试使用以下查询:

  1. SELECT b.position, b.name, b.capacity, b.currentAmount, it.name AS ingredientName FROM ....
  • 其中 .... 是查询的其余部分。即,重要的部分是将 name 列别名为 ingredientName,使用 AS

即,您提供的值可以/将与 ingredientName 成员变量关联。

这是假设您希望从 ingredient_types 表中获取 name 列的值作为 ingredientName

英文:

Try SELECT b.position,b.name,b.capacity,b.currentAmount, it.name AS ingredientName FROM ....

  • where .... is the rest of the query. i.e. the important part is aliasing the name column to be ingredientName using AS.

i.e. you are supplying the value that can/will be associated with the ingredientName member variable.

This is assuming that you want the value of the name column from the ingredient_types table to be the ingredientName.

huangapple
  • 本文由 发表于 2023年5月21日 23:22:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76300620.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定