Java 如何在android中使用Room持久化ORM工具实现创建的_at和更新的_at列

Java 如何在android中使用Room持久化ORM工具实现创建的_at和更新的_at列,java,android,orm,android-room,sql-timestamp,Java,Android,Orm,Android Room,Sql Timestamp,我如何使用Android中的Room持久化ORM工具实现created_at和update_at列,在创建或更新表中的行时自动更新时间戳?我研究了许多站点,但仍然没有发现任何结果可以处理中间件或类似回调的查询、插入、更新或删除,。。。方法来自DAOs 正如@selvin所说,RoomDatabase.Callback接口仅在第一次创建数据库时调用。所以,使用该接口是不正确的。 所以,也许下面的方法对我来说是个窍门,希望这能帮助你: 1.我们需要创建一个基本模型 此模型确保数据库中的所有模型始终可

我如何使用Android中的Room持久化ORM工具实现created_at和update_at列,在创建或更新表中的行时自动更新时间戳?

我研究了许多站点,但仍然没有发现任何结果可以处理中间件或类似回调的查询、插入、更新或删除,。。。方法来自DAOs

正如@selvin所说,RoomDatabase.Callback接口仅在第一次创建数据库时调用。所以,使用该接口是不正确的。 所以,也许下面的方法对我来说是个窍门,希望这能帮助你:

1.我们需要创建一个基本模型 此模型确保数据库中的所有模型始终可用列“创建日期”和“修改日期”

2.创建一个BaseDAO 在BaseDAO内部,我还创建了一个名为DAOWrapper的包装类,这个类将存储所有有用的方法,我们将使用这些方法来处理数据,比如在将模型的数据交互到DAO之前使用中间件

那么,为什么我们不在BaseDAO内部创建方法呢? ->我们不能那样做!使用这种方式将与android架构冲突,而且我们将从编译器得到错误。DAO对象中声明的所有方法都需要注释更新、查询等

工具书类 下面是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()
            }
        }
    }

}

下面是一个Java示例

所有房间图元的基础图元 这将映射到一个表,该表包含一个id、在列中创建的和在列中更新的

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实现所有基本的插入、更新和删除方法

@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);
}
如何更新用户


有了可以在RoomDatabase.Callback.OnCreate内部添加的触发器,有人能展示一个可以使用这两个字段的模型实体的示例吗?如果用Java或logic flow编写,效果会更好。它被贴上了标签Java@AsifMohammadMollah我添加了一个java示例:大多数的样板代码都会考虑一个常规的数据库过程。
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;
    }
}
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();
    }
}
@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);
}
@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();
}
YourDatabase database = YourDatabase.getInstance(getApplicationContext());
UserDao userDao = database.userDao();
long userId = userDao.insert(userToAdd);
userToAdd.setId(userId);
YourDatabase database = YourDatabase.getInstance(getApplicationContext());
UserDao userDao = database.userDao();
userDao.update(userToEdit);