房间数据库如何实现需要来自 2 个实体的列的项目

Room Data-base how to implement item that needs columns from 2 entities

我已经使用带有 MVVM 的 Room 创建了数据库,但我遇到了一个问题,希望您能帮我解决这个问题。

我有一个包含 3 个实体 PlayerGroupStandings 的数据库,其中 Standings 是 PlayerGroup 之间的关系。 问题是我想显示排名,但 Standings 只包含 GroupPlayer 的 ID,我希望它还显示 [=] 中的玩家姓名11=],我正在使用 LiveDataadaptersViewModels,所以当我 return 要观察 LiveData<List<Standings>> 的列表时,它不会包含玩家的名字。

有人知道我怎样才能传递这个名字吗?

我能想到的唯一解决方案是创建新的class,它有一个 Standing 和 name(String) 作为实例,然后 return 观察它。

但感觉不自然,所以我想我可以在这里找到更好、更优雅的解决方案。

     groupStandingsViewModel = ViewModelProviders.of(this, new GroupStandingsViewModelFactory(this.getApplication(), 0)).get(GroupStandingsViewModel.class);
    groupStandingsViewModel.getAllStandings().observe(this, new Observer<List<Standings>>() {
        @Override
        public void onChanged(List<Standings> standings) {
            adapter.setStanding(standings);
        }
    });

我希望能够获得观察的 onChanged 函数中给出的排名和名称。

The only solution that I could think of is to create new class that has a Standing and the name(String) as the instances and then return it to observe.

But it doesn't feel natural so I thought I could find here a better, more elegant solution.

这听起来可能不自然,但您需要一些新代码,还有什么? (P.S。这是修辞)。

我建议一个新的 class 是这样的方式:-

public class PlayerGroupStanding {

    @Embedded
    Standings standing;
    String playerName;
    long playerId;
    String groupName;
    long groupId;

    public PlayerGroupStanding() {
    }

    public Standings getStanding() {
        return standing;
    }

    public void setStanding(Standings standing) {
        this.standing = standing;
    }

    public long getPlayerId() {
        return playerId;
    }

    public void setPlayerId(long playerId) {
        this.playerId = playerId;
    }

    public String getPlayerName() {
        return playerName;
    }

    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }

    public long getGroupId() {
        return groupId;
    }

    public void setGroupId(long groupId) {
        this.groupId = groupId;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupname(String groupname) {
        this.groupName = groupname;
    }
}

这可以按照以下方式与 Dao 查询结合使用:-

@Query("SELECT * FROM standings JOIN player ON mapToPlayer = playerId JOIN `group` ON mapToGroup = groupId")
List<PlayerGroupStanding> getAllStandingsWithPlayerAndGroupDetails();
  • 请注意,上面对名称做了很多假设,尽管给出的名称应该是不言自明的。
  • 注意变量的名称,例如playerName 应与查询中的 return 列名称相匹配。

额外

重新评论

what object does the SELECT returns in a query. I understand that if I use a SELECT * then the object will be of the class that is in the FROM. but when I returns columns, what will be the object that I need to mention in the LiveData>? Where can if find information about it? Thank you very much in advance:D

SELECT 实际上 return 是一个游标,它是注释,然后根据 class 映射列的方法的定义编写提取列的代码的成员名称到 return 对象,如果存在其他列,它们将被忽略。 FROM 子句未确定结果对象 return 在 @Query 根据类型 return 从该方法编辑后 returned 方法。

实际代码可以在项目生成的代码中构建(Ctrl + F9)后找到,例如

所以对于上面的例子,那么在 Dao 代码中生成的相应方法(即 Dao 后缀为 _impl)是:-

@Override
  public List<PlayerGroupStandings> getAllPlayerGroupStandings() {
    final String _sql = "SELECT * FROM standings JOIN player ON mapToPlayer = playerId JOIN `group` ON mapToGroup = groupId";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, true, null);
    try {
      final int _cursorIndexOfMapToPlayer = CursorUtil.getColumnIndexOrThrow(_cursor, "mapToPlayer");
      final int _cursorIndexOfMapToGroup = CursorUtil.getColumnIndexOrThrow(_cursor, "mapToGroup");
      final LongSparseArray<ArrayList<Player>> _collectionPlayers = new LongSparseArray<ArrayList<Player>>();
      final LongSparseArray<ArrayList<Group>> _collectionGroup = new LongSparseArray<ArrayList<Group>>();
      while (_cursor.moveToNext()) {
        if (!_cursor.isNull(_cursorIndexOfMapToPlayer)) {
          final long _tmpKey = _cursor.getLong(_cursorIndexOfMapToPlayer);
          ArrayList<Player> _tmpPlayersCollection = _collectionPlayers.get(_tmpKey);
          if (_tmpPlayersCollection == null) {
            _tmpPlayersCollection = new ArrayList<Player>();
            _collectionPlayers.put(_tmpKey, _tmpPlayersCollection);
          }
        }
        if (!_cursor.isNull(_cursorIndexOfMapToGroup)) {
          final long _tmpKey_1 = _cursor.getLong(_cursorIndexOfMapToGroup);
          ArrayList<Group> _tmpGroupCollection = _collectionGroup.get(_tmpKey_1);
          if (_tmpGroupCollection == null) {
            _tmpGroupCollection = new ArrayList<Group>();
            _collectionGroup.put(_tmpKey_1, _tmpGroupCollection);
          }
        }
      }
      _cursor.moveToPosition(-1);
      __fetchRelationshipplayerAsarmAndroidroommigrationsPlayer(_collectionPlayers);
      __fetchRelationshipgroupAsarmAndroidroommigrationsGroup(_collectionGroup);
      final List<PlayerGroupStandings> _result = new ArrayList<PlayerGroupStandings>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final PlayerGroupStandings _item;
        final Standings _tmpStandings;
        if (! (_cursor.isNull(_cursorIndexOfMapToPlayer) && _cursor.isNull(_cursorIndexOfMapToGroup))) {
          _tmpStandings = new Standings();
          final Long _tmpMapToPlayer;
          _tmpMapToPlayer = _cursor.getLong(_cursorIndexOfMapToPlayer);
          _tmpStandings.setMapToPlayer(_tmpMapToPlayer);
          final Long _tmpMapToGroup;
          _tmpMapToGroup = _cursor.getLong(_cursorIndexOfMapToGroup);
          _tmpStandings.setMapToGroup(_tmpMapToGroup);
        }  else  {
          _tmpStandings = null;
        }
        ArrayList<Player> _tmpPlayersCollection_1 = null;
        if (!_cursor.isNull(_cursorIndexOfMapToPlayer)) {
          final long _tmpKey_2 = _cursor.getLong(_cursorIndexOfMapToPlayer);
          _tmpPlayersCollection_1 = _collectionPlayers.get(_tmpKey_2);
        }
        if (_tmpPlayersCollection_1 == null) {
          _tmpPlayersCollection_1 = new ArrayList<Player>();
        }
        ArrayList<Group> _tmpGroupCollection_1 = null;
        if (!_cursor.isNull(_cursorIndexOfMapToGroup)) {
          final long _tmpKey_3 = _cursor.getLong(_cursorIndexOfMapToGroup);
          _tmpGroupCollection_1 = _collectionGroup.get(_tmpKey_3);
        }
        if (_tmpGroupCollection_1 == null) {
          _tmpGroupCollection_1 = new ArrayList<Group>();
        }
        _item = new PlayerGroupStandings();
        _item.standings = _tmpStandings;
        _item.players = _tmpPlayersCollection_1;
        _item.group = _tmpGroupCollection_1;
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }