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...
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.
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.
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.
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
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With