简体   繁体   中英

Room - Query all memory handling

I'm considering using the android Room library as a ORM in my app, but i would like to know more details/comments because of some constraints i have and i was not able to find on the internet (ie.Google;)) When i do the following query:

@Query("SELECT * FROM users")
List<User> getAll();

and if i have thousands off users, wouldn't it be an issue? because from the generated code below it seems to load everything into an ArrayList. Event the LiveData> or Flowable> do the same.

@Override
public List<User> getAll() {
  final String _sql = "SELECT * FROM Users";
  final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
  final Cursor _cursor = __db.query(_statement);
  try {
   final int _cursorId = _cursor.getColumnIndexOrThrow("id");
   final int _cursorName = _cursor.getColumnIndexOrThrow("name");
   final List<User> _result = new ArrayList<User>(_cursor.getCount());
   while(_cursor.moveToNext()) {
     final User _item;
     final String _tmpMId;
     _tmpMId = _cursor.getString(_cursorId);
     final String _tmpMName;
     _tmpMName = _cursor.getString(_cursorName);
     _item = new User(_tmpMId,_tmpMName);
     _result.add(_item);
   }
   return _result;
  } finally {
   _cursor.close();
   _statement.release();
  }
}

@Override
  public Flowable<List<User>> getAllRX() {
    final String _sql = "SELECT * FROM Users";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    return RxRoom.createFlowable(__db, new String[]{"Users"}, new Callable<List<CachedAttendee>>() {
      public List<User> call() throws Exception {
        final Cursor _cursor = __db.query(_statement);
        try {
          final int _cursorId = _cursor.getColumnIndexOrThrow("id");
          final int _cursorName = _cursor.getColumnIndexOrThrow("name");
          final List<User> _result = new ArrayList<User>(_cursor.getCount());
          while(_cursor.moveToNext()) {
            final User _item;
            final String _tmpMId;
            _tmpMId = _cursor.getString(_cursorId);
            final String _tmpMName;
            _tmpMName = _cursor.getBlob(_cursorName);
            _item = new User(_tmpMId,_tmpMName);
            _result.add(_item);
          }
          return _result;
        } finally {
          _cursor.close();
        }
      }

      @Override
      protected void finalize() {
        _statement.release();
      }
    });
  }

Am i looking at it wrongly or Google dismissed this point? I can always use Cursors, but that defeats the point of having an ORM handling that serialisation for me.

Cheers,

and if i have thousands off users, wouldn't it be an issue? because from the generated code below it seems to load everything into an ArrayList.

You asked it to do that. If you do not want a List of all users, do not ask for it. Create a @Query that uses some sort of constraints (eg, WHERE , LIMIT / OFFSET ).

This is not significantly different from other ORM solutions. That being said, if you find some other ORM that you like better, use it. Room is an option, not a requirement.

You can consider pagination to improve this problem.

Query is :

@Query("SELECT * FROM user LIMIT :limit OFFSET :offset")
    User[] loadAllUsersByPage(int limit,int offset);

Here, it will give a list of user based on limit and offset.

if loadAllUsersByPage(2,0) it will return first 2 rows from table.

if loadAllUsersByPage(2,1) it will return 3rd and 4th rows from table.

but if loadAllUsersByPage(-1,10) then it will serve first 10 rows from table.

Thanks :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM