Room的DAO实现未正确生成。

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

Room's DAOimpl not generating correctly

问题

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

@Query("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 = :position")
Bottle getBottleWithIngredientFromPosition(int position);

而我的Bottle类如下:

public class Bottle {
    public int position;
    public String name;
    public int capacity;
    public int currentAmount;
    public String ingredientName;

    //Constructor, getters and setters
}

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

@Override
public Bottle getBottleWithIngredientFromPosition(final int position) {
    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 = ?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, position);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
        final int _cursorIndexOfPosition = 0;
        final int _cursorIndexOfName = 1;
        final int _cursorIndexOfCapacity = 2;
        final int _cursorIndexOfCurrentAmount = 3;
        final Bottle _result;
        if(_cursor.moveToFirst()) {
            final int _tmpPosition;
            _tmpPosition = _cursor.getInt(_cursorIndexOfPosition);
            final String _tmpName;
            if (_cursor.isNull(_cursorIndexOfName)) {
                _tmpName = null;
            } else {
                _tmpName = _cursor.getString(_cursorIndexOfName);
            }
            final int _tmpCapacity;
            _tmpCapacity = _cursor.getInt(_cursorIndexOfCapacity);
            final int _tmpCurrentAmount;
            _tmpCurrentAmount = _cursor.getInt(_cursorIndexOfCurrentAmount);
            _result = new Bottle(_tmpPosition,_tmpName,_tmpCapacity,_tmpCurrentAmount,null);
        } else {
            _result = null;
        }
        return _result;
    } finally {
        _cursor.close();
        _statement.release();
    }
}

我们可以看到它调用构造函数时,最后一个参数为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:

 @Query("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 = :position")
    Bottle getBottleWithIngredientFromPosition(int position);

And my bottle class is the following:

public class Bottle {
    public int position;
    public String name;
    public int capacity;
    public int currentAmount;
    public String ingredientName;

    //Constructor, getters and setters
}

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:

@Override
  public Bottle getBottleWithIngredientFromPosition(final int position) {
    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 = ?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, position);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
      final int _cursorIndexOfPosition = 0;
      final int _cursorIndexOfName = 1;
      final int _cursorIndexOfCapacity = 2;
      final int _cursorIndexOfCurrentAmount = 3;
      final Bottle _result;
      if(_cursor.moveToFirst()) {
        final int _tmpPosition;
        _tmpPosition = _cursor.getInt(_cursorIndexOfPosition);
        final String _tmpName;
        if (_cursor.isNull(_cursorIndexOfName)) {
          _tmpName = null;
        } else {
          _tmpName = _cursor.getString(_cursorIndexOfName);
        }
        final int _tmpCapacity;
        _tmpCapacity = _cursor.getInt(_cursorIndexOfCapacity);
        final int _tmpCurrentAmount;
        _tmpCurrentAmount = _cursor.getInt(_cursorIndexOfCurrentAmount);
        _result = new Bottle(_tmpPosition,_tmpName,_tmpCapacity,_tmpCurrentAmount,null);
      } else {
        _result = null;
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }

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

尝试使用以下查询:

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:

确定