2017-06-25 53 views
10

Czy istnieje sposób na stworzenie wielokrotnego użytku podstawowego DAO klasy podstawowej z Android Room?Wielokrotnego użytku podstawowe DAO klasy podstawowej z Androidem Room

public interface BaseDao<T> { 

    @Insert 
    void insert(T object); 

    @Update 
    void update(T object); 

    @Query("SELECT * FROM #{T} WHERE id = :id") 
    void findAll(int id); 

    @Delete 
    void delete(T object); 

} 

public interface FooDao extends BaseDao<FooObject> { ... } 

public interface BarDao extends BaseDao<BarEntity> { ... } 

Nie udało mi się wymyślić żadnego sposobu osiągnięcia tego bez konieczności deklarowania tych samych członków interfejsu i napisania zapytania dla każdej podklasy. Kiedy mamy do czynienia z dużą liczbą podobnych DAO, staje się to bardzo żmudne ...

+1

Opcja 'insert()', 'update()' oraz 'delete()' metody powinny działać jak jest jak rozumiem - Yigit napisał w kwestii, że należy to teraz wspierać. Metoda 'findAll()' musi zostać przepisana, aby podać nazwę tabeli. – CommonsWare

+0

Cool. Właśnie znalazłem problem. Wygląda na to, że typowy typ zwrotów/argumentów będzie obsługiwany z poziomu alpha3: https://issuetracker.google.com/issues/62103620 – pqvst

+0

@CommonsWare Czy naprawdę można przepisać findAll? Jeśli tak, to w jaki sposób? Myślałem, że nazwa tabeli musi być znana podczas kompilacji. –

Odpowiedz

0

Chociaż zgadzam się z twoim myśleniem, odpowiedź brzmi: nie. Z kilku powodów.

  1. Gdy fooDao_Impl.java jest generowany z klasy @Dao fooDao extends BaseDao<Foo>, będzie spotkał się z dużą ilością „nie można znaleźć klasy symbolu T” błędów. Wynika to z metody używanej przez Room do generowania implementacji dao. Jest to metoda, która nie zapewni pożądanego rezultatu i jest mało prawdopodobne, aby uległa zmianie wkrótce (moim zdaniem z powodu wymazania tekstu).

  2. Nawet jeśli problem zostanie rozwiązany, Room nie obsługuje zapytań dynamicznych @Dao, aby zapobiec iniekcji SQL. Oznacza to, że można dynamicznie wstawiać tylko wartości do zapytań, a nie do nazw kolumn, nazw tabel czy poleceń zapytań. W tym przykładzie nie można użyć wartości #{T}, ponieważ naruszałoby to tę zasadę. Teoretycznie, jeśli problem opisany w punkcie 1 zostanie rozwiązany, użytkownik może wstawić, usunąć i zaktualizować.

5

Dzisiaj, 08 sierpień 2017, w wersji 1.0.0-alpha8 Tao poniżej prac. Mogę mieć innych Dao bohaterskich na GenericDao.

@Dao 
public interface GenericDao<T> { 
    @Insert(onConflict = OnConflictStrategy.REPLACE) 
    void insert(T... entity); 

    @Update 
    void update(T entity); 

    @Delete 
    void delete(T entity); 
} 

Jednak GenericDao nie mogą być zawarte w mojej klasie Database

+0

Wygląda na to, że masz problem i nie wydaje się być odpowiedzią na pierwotne pytanie. Jeśli tak, usuń i zadaj zupełnie nowe pytanie. – SandPiper

+1

To jest dokładnie to rozwiązanie, najprawdopodobniej powodem, dla którego nie działa dla niektórych osób, jest używana wersja. – Natan

+1

Twoja odpowiedź nie mówi tego, co właśnie powiedziałeś w swoim komentarzu, a odpowiedź jest bardzo trudna do odczytania. – SandPiper