Próbuję zaimplementować „podstawowy interfejs DAO” dla biblioteki Room, aby uniknąć standardowego kodu:

BaseEntity.kt

interface BaseEntity {
    val entityName: String
}

Note.kt

@Entity
class Note : BaseEntity {
    override val entityName: String = "note"
    ...
}

BaseBIZ.kt

interface BaseDao<T : BaseEntity> {
    @Query("SELECT * FROM ${T.entityName}")
    fun selectAll(): List<T>
    ...

}

Noteamia.kt

@Dao
interface NoteDao : BaseDao<Note> {
...
}

Jednak wyrażenie ${T.entityName} jest nieprawidłowe. Czy jest na to sposób?

0
mickp 17 listopad 2019, 02:46
Nie jestem pewien, czy jest to możliwe z powodu wymazywania typów w JVM. Gdyby to była metoda, można by oznaczyć ją jako wbudowaną i oznaczyć T jako zreifikowaną. Jednak ponieważ jest to adnotacja, nie jestem pewien
 – 
Carson Graham
17 listopad 2019, 04:32
Adnotacje wymagają stałych czasu kompilacji, to @Query w BaseDao niestety nie zadziała.
 – 
EpicPandaForce
17 listopad 2019, 04:41

1 odpowiedź

Nie wierzę, że można zaimplementować "podstawowy interfejs DAO". Powodem jest to, że Room tworzy każdą implementację DAO w czasie kompilacji. I dlatego otrzymujesz komunikat Argument adnotacji musi być stałą czasową kompilacji.

Room musi wiedzieć, na podstawie adnotacji (na przykład), które kolumny tabeli mapować do jakich zmiennych i metody użyte do wykonania mapowania, aby można było wygenerować kod bazowy.

Na przykład, jeśli Byt i Tao byli:-

@Entity
class Note {

    @PrimaryKey
    var entityName: String = ""

}

I

@Dao
interface BaseDao {
    @Query("SELECT * FROM Note")
    fun selectAll(): List<Note>

}

Wtedy bazowa wygenerowana java byłaby :-

public final class BaseDao_Impl implements BaseDao {
  private final RoomDatabase __db;

  public BaseDao_Impl(RoomDatabase __db) {
    this.__db = __db;
  }

  @Override
  public List<Note> selectAll() {
    final String _sql = "SELECT * FROM Note";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
      final int _cursorIndexOfEntityName = CursorUtil.getColumnIndexOrThrow(_cursor, "entityName");
      final List<Note> _result = new ArrayList<Note>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final Note _item;
        _item = new Note();
        final String _tmpEntityName;
        _tmpEntityName = _cursor.getString(_cursorIndexOfEntityName);
        _item.setEntityName(_tmpEntityName);
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }
}
1
MikeT 17 listopad 2019, 07:32