Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusable generic base class DAOs with Android Room

Is there any way to create reusable generic base class DAOs with Android 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> { ... } 

I haven't been able to figure out any way of achieving this without having to declare the same interface members and write the query for each sub class. When dealing with a large number of similar DAOs this becomes very tedious...

like image 289
pqvst Avatar asked Jun 25 '17 12:06

pqvst


People also ask

Can a room database have multiple Dao?

There is no such rule that you have to make separate @Dao for every table. You can make one Dao class that holds all of your database queries. But just with the convention, you make separate Dao for every entity.

What is Dao in room database in Android?

When you use the Room persistence library to store your app's data, you interact with the stored data by defining data access objects, or DAOs. Each DAO includes methods that offer abstract access to your app's database. At compile time, Room automatically generates implementations of the DAOs that you define.

What is Dao in room?

android.arch.persistence.room.Dao. Marks the class as a Data Access Object. Data Access Objects are the main classes where you define your database interactions. They can include a variety of query methods. The class marked with @Dao should either be an interface or an abstract class.


2 Answers

Today, August 08, 2017, with version 1.0.0-alpha8 the Dao below works. I can have other Dao heroing the GenericDao.

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

However, GenericDao can not be included in my Database class

like image 109
Natan Avatar answered Sep 19 '22 22:09

Natan


Generic findAll function:

base repository and dao:

abstract class BaseRepository<T>(private val entityClass: Class<T>) {      abstract val dao: BaseDao<T>      fun findAll(): List<T> {         return dao.findAll(SimpleSQLiteQuery("SELECT * FROM ${DatabaseService.getTableName(entityClass)}"))     } }  interface BaseDao<T> {      @RawQuery     fun findAll(query: SupportSQLiteQuery): List<T> } 

database service:

object DatabaseService {      fun getEntityClass(tableName: String): Class<*>? {         return when (tableName) {             "SomeTableThatDoesntMatchClassName" -> MyClass::class.java             else -> Class.forName(tableName)         }     }      fun getTableName(entityClass: Class<*>): String? {         return when (entityClass) {             MyClass::class.java -> "SomeTableThatDoesntMatchClassName"             else -> entityClass.simpleName         }     } } 

example repo and dao:

class UserRepository : BaseRepository<User>(User::class.java) {      override val dao: UserDao         get() = database.userDao  }  @Dao interface UserDao : BaseDao<User> 
like image 29
jc12 Avatar answered Sep 22 '22 22:09

jc12