interface BaseDAO<T> where T: BaseModel {
fun getAll(): List<T>
@Insert(onConflict = OnConflictStrategy.ABORT)
fun insert(modelData: T)
@Update(onConflict = OnConflictStrategy.ABORT)
fun update(modelData: T)
companion object {
open class DAOWrapper<P, T>(private val daoInstance: T) where T: BaseDAO<P>, P: BaseModel {
fun insertWithTimestapData(modelData: P) {
modelData.modificationDate = Date(System.currentTimeMillis())
this@DAOWrapper.daoInstance.insert(modelData)
}
}
}
}
3.使用DAOWrapper
val appDatabase = // Do something to get RoomDatabase instance...
val exampleDao = appDatabase.exampleDAO()
val exampleDaoWrapper = BaseDAO.Companion.DAOWrapper(exampleDao)
val exampleModel = ExampleModel(name = "Example Name")
exampleDaoWrapper.insertWithTimestapData(exampleModel)
参考文献
下面是RoomDatabase的示例示例和我在上面代码中使用的示例模型:
/** ExampleModel.kt */
@Entity(
tableName = "examples",
indices = [Index(value = arrayOf("name"), unique = true)]
)
class ExampleModel(): BaseModel() {
@ColumnInfo(name = "name")
@SerializedName(value = "name")
var name: String = String()
@Ignore
constructor(name: String): this() {
this@ExampleModel.name = name
}
}
/** ExampleDAO.kt */
@Dao
interface ExampleDAO: BaseDAO<ExampleModel> {
@Query("SELECT * FROM `examples`")
override fun getAll(): List<ExampleModel>
}
/** AppDatabase.kt **/
@Database(entities = [ExampleModel::class], version = 1)
abstract class AppDatabase: RoomDatabase() {
abstract fun exampleDAO(): ExampleDAO
companion object {
private var databaseInstance: AppDatabase? = null
public const val DatabaseName: String = "app_database"
fun getDatabase(context: Context): AppDatabase {
this@Companion.destroyAndCreateNewInstanceIfNeeded(context)
return this@Companion.databaseInstance!!
}
fun destroyAndCreateNewInstanceIfNeeded(context: Context) {
synchronized(AppDatabase::class) {
this@Companion.databaseInstance?.close()
this@Companion.databaseInstance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
this@Companion.DatabaseName
).build()
}
}
}
}
public abstract class BaseEntity implements Serializable {
@PrimaryKey(autoGenerate = true)
private long id;
@ColumnInfo(name = "created_at", defaultValue = "CURRENT_TIMESTAMP")
@TypeConverters(DateConverter.class)
private Date createdAt;
@ColumnInfo(name = "updated_at", defaultValue = "CURRENT_TIMESTAMP")
@TypeConverters(DateConverter.class)
private Date updatedAt;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
}
房间日期类型转换器将Java日期转换为可保存在sqlite数据库中的数字。
public class DateConverter {
@TypeConverter
public static Date toDate(Long timestamp) {
if (timestamp == null) {
return null;
}
return new Date(timestamp);
}
@TypeConverter
public static Long toTimestamp(Date date) {
if (date == null) {
return null;
}
return date.getTime();
}
}
抽象BaseDao此Dao实现了所有基本的Insert、Update和Delete方法。
@Dao
public abstract class AbstractBaseEntityDao<T extends BaseEntity> {
@Insert
public abstract long actualInsert(T t);
public long insert(T t) {
t.setCreatedAt(new Date());
t.setUpdatedAt(new Date());
return actualInsert(t);
}
@Insert
public abstract List<Long> actualInsertAll(List<T> ts);
public List<Long> insertAll(List<T> ts) {
if (ts != null) {
for (T t : ts) {
t.setCreatedAt(new Date());
t.setUpdatedAt(new Date());
}
}
return actualInsertAll(ts);
}
@Update
public abstract void actualUpdate(T t);
public void update(T t) {
t.setUpdatedAt(new Date());
actualUpdate(t);
}
@Update
public abstract void actualUpdateAll(List<T> ts);
public void updateAll(List<T> ts) {
if (ts != null) {
for (T t : ts) {
t.setUpdatedAt(new Date());
}
}
actualUpdateAll(ts);
}
@Delete
public abstract void delete(T t);
@Delete
public abstract void deleteAll(List<T> ts);
}
User和UserDao这里是一个User的具体实体和Dao的示例(典型用例)。
@Entity(tableName = "users")
public class User extends BaseEntity {
@ColumnInfo(name = "name")
private String name;
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Dao
public abstract class UserDao extends AbstractBaseEntityDao<User> {
@Query("select * from users")
public abstract List<User> getAllUsers();
}
2条答案
按热度按时间j0pj023g1#
我已经研究了很多网站,但仍然没有发现任何结果可以处理
middleware
或类似callbacks
的东西,当我们Query
,Insert
,Update
,或Delete
,...方法从DAO
s。正如@selvin所说,
RoomDatabase.Callback
接口只在第一次创建数据库时调用。所以,使用该接口是不正确的方式。所以,可能下面的方式对我来说是一个技巧,希望这对你有帮助:1.创建一个
BaseModel
此模型确保数据库中的所有模型始终可用
creation_date
和modification_date
列。2.创建
BaseDAO
在
BaseDAO
中,我还创建了一个名为DAOWrapper
的 Package 器类,该类将存储所有有用的方法,在将模型的数据交互到DAO之前,我们将使用这些方法来处理数据,如“中间件”。那么,为什么我们不在
BaseDAO
内部创建方法?-〉我们不能这样做!使用这种方式会与Android架构冲突,并且我们会从编译器中获得错误(DAO对象中声明的所有方法都需要注解Update
,Query
,...)。3.使用
DAOWrapper
参考文献
下面是RoomDatabase的示例示例和我在上面代码中使用的示例模型:
oaxa6hgo2#
下面是一个Java示例。
所有Room实体的Base实体这将Map到包含id、created_at和updated_at列的表。
房间日期类型转换器将Java日期转换为可保存在sqlite数据库中的数字。
抽象BaseDao此Dao实现了所有基本的Insert、Update和Delete方法。
User和UserDao这里是一个User的具体实体和Dao的示例(典型用例)。
如何插入用户这将使用AbstractBaseEntityDao,它设置了created_at和updated_at时间戳。
注意:不要在UI线程上执行此操作!!
如何更新用户