Room Dao generation based on annotation.
- Generate many basic database requests (less boilerplate)
- Auto threading (can be disabled as needed)
- Support
LIMIT
andORDER BY
- Support
@Ignore
,@ColumnInfo
and@Embedded
- Support one to many (using @Relation)
- Code generation is done at compile time
- Room "static query check" is preserved.
- Code generation is configurable
- Proguard removes functions that you don't use
- 100% kotlin
We will consider this Entity (standard Room Entity, nothing special here).
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
var name: String,
var age: Int,
@Ignore var job: String
)
Replace @Dao
by @AutoDao
and specify the related entity
@AutoDao(User::class)
class UserDao
getById
is automatically generated and you can write this.
getUserById(userId).subscribe()
No crash here, threading is done by default for Single
and Maybe
(using Schedulers.io()
and AndroidSchedulers.mainThread())
You can disable it if needed.
getUserById(userId, autoThread = false).subscribe()
@AutoDao
automatically detect fields: let's try to use name
getUserByName("Smith").subscribe()
Also vaargs
getUserByName("Joe", "William", "Jack").subscribe()
And LIMIT
getUserByName("Averell", limit = 10).subscribe()
Don't forget ORDER BY
// Get all users and order them by name
getAllOrderedByName().subscribe()
// Get all users named "Joe" and order them by age, oldest first
getByNameOrderedByAge("Joe", order = Order.DESC).subscribe()
Only one depth of ORDER BY
is generated, you cannot call something like getByNameOrderedByAgeOrderedById
@AutoDao
supports @Ignore
annotation.
Looking at User entity, job
carries @Ignore
annotation: nothing is generated for this field
getUserByJob().subscribe() // does not compile because of @Ignore
Of course native @Insert
, @Update
and @Delete
are avaible too
delete(badUser).subscribe()
You can control code generation with @AutoDao
parameters
Control if "order by" related functions should be generated
Default value: true
As mentionned, AutoDao uses native annotations @Insert
and @Update
.
You can control their conflict strategy by using onInsertConflictStrategy
and onUpdateConflictStrategy
Default value is OnConflictStrategy.ABORT
Room's Rx implementation support many types.
Therefore, AutoDao generate each functions 3 times
By default, the value of defaultRxReturnType
is Single
. Therefore getById
will be generated as:
- Single<List<User>> getById(id: Int)
- Maybe<List<User>> getByIdAsMaybe(id: Int)
- Flowable<List<User>> getByIdAsFlowable(id: Int)
(notice that getById
returns a Single
)
If you set defaultRxReturnType
to Flowable
, then getById
will be generated as
- Single<List<User>> getByIdAsSingle(id: Int)
- Maybe<List<User>> getByIdAsMaybe(id: Int)
- Flowable<List<User>> getByIdAs(id: Int)
(notice that getById
returns a Flowable
)
Control if AutoDao should generate each functions 3 times (for Single
, Maybe
and Flowable
)
Couple of examples:
With generateOnlyDefaultRxReturnType
to true
and defaultRxReturnType
to Single
, functions will generated only with Single
Single<List<User>> getById(id: Int)
With generateOnlyDefaultRxReturnType
to true
and defaultRxReturnType
to Flowable
, functions will generated only with Flowable
Flowable<List<User>> getById(id: Int)
With generateOnlyDefaultRxReturnType
to false
, functions will be generated 3 times, changing defaultRxReturnType
will then only affect names, ex with Flowable
:
Single<List<User>> getByIdAsSingle(id: Int)
Maybe<List<User>> getByIdAsMaybe(id: Int)
Flowable<List<User>> getById(id: Int)
Default value is of generateOnlyDefaultRxReturnType
is false
Unfortunately, this library comes with a constraint.
AutoRoomDao, generates a class annotated with @Dao
and then Room will generate a second class.
For this reason, we need AutoRoomDao to do its work before room does it own.
The only solution I found so far is to put the model (annotated with @Entity
) and the Dao (annotated with @Autoroom
) in a separate module and link it as a dependency of the app
module. Thus, we ensure that AutoRoomDao will be the first to do its code generation.
a) app
gradle files contains
implementation project(":models") // this contains `User` and `UserDao`
b) models
gradle file contains
kapt com.asaddour.autoroomdao:autoroomdao:0.7.3
compileOnly com.asaddour.autoroomdao:autoroomdao:0.7.3
compileOnly 'com.squareup:kotlinpoet:0.7.0'
If this is unclear, check the sampleapp
and dao
modules in this repository.
Annotating a class called UserDao
with @AutoDao
generates a second class called Auto_UserDao
.
You need to give Auto_UserDao
to RoomDatabase.
@Database(entities = [User::class], version = 1)
abstract fun AppDatabase(): RoomDatabase {
abstract fun users(): Auto_UserDao // Notice `Auto_UserDao` and not `UserDao`
}