我正在尝试让SQLite使用CURRENT_TIMESTAMP创建自动时间戳。
我自由使用了Google的code:
// roomVersion = '2.2.2'
@Entity
public class Playlist {
@PrimaryKey(autoGenerate = true)
long playlistId;
String name;
@Nullable
String description;
@ColumnInfo(defaultValue = "normal")
String category;
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
String createdTime;
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
String lastModifiedTime;
}
@Dao
interface PlaylistDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(playlist: Playlist): Long
}
这将转换为SQLite语句:
CREATE TABLE `Playlist` (
`playlistId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`name` TEXT,
`description` TEXT,
`category` TEXT DEFAULT 'normal',
`createdTime` TEXT DEFAULT CURRENT_TIMESTAMP,
`lastModifiedTime` TEXT DEFAULT CURRENT_TIMESTAMP
)
我确实做了一个插入:
mDb.playListDao().insert(Playlist().apply { name = "Test 1" })
但是时间戳总是空的。
使用用于SQLite的数据库浏览器,我添加了另一个条目,在这里我获得了时间戳。
如何在不插入Null时间戳的情况下插入?
(信息:createdTime也总是与lastModifiedTime相同。我认为这必须使用SQLite中的触发器来完成,但这是一个不同的问题,这里不再讨论)。
答案 0 :(得分:2)
您不需要使用其他类,可以使用@Query
代替便利@Insert
。
按照:-
查询方法支持4种类型的语句:SELECT,INSERT,UPDATE和DELETE。 Query
例如
@Query("INSERT INTO test_table001 (name) VALUES(:name) ")
void insert(String name);
您也不限于CURRENT_TIMESTAMP作为获取当前时间戳的唯一方法,您可以使用嵌入的datetime函数(如下所示),该函数可以更有效地存储值,并且更加灵活,例如您可以使用“ +7天”等修饰符来调整当前时间。
如果您考虑以下问题:-
@Entity(tableName = "test_table001")
public class TestTable001 {
@PrimaryKey
Long id;
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
String dt1;
@ColumnInfo(defaultValue = "(datetime('now'))")
String dt2;
@ColumnInfo(defaultValue = "(strftime('%s','now'))")
String dt3;
String name;
}
autogenerate = true
,但您仍可以为SQLite分配ID (请注意,必须使用Long / Integer类型,而不是long或int) 道为:-
@Dao
public interface TestTable001Dao {
@Insert()
long insert(TestTable001 testTable001);
@Query("INSERT INTO test_table001 (name) VALUES(:name) ")
long insert(String name);
@Query("SELECT * FROM test_table001")
List<TestTable001> getAllTestTable001();
}
以及以下内容进行测试/演示:-
public class MainActivity extends AppCompatActivity {
AppDatabase mRoomDB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRoomDB = Room.databaseBuilder(this,AppDatabase.class,"testdb")
.allowMainThreadQueries()
.build();
TestTable001 tt01 = new TestTable001();
tt01.setName("tt01");
mRoomDB.useTestTable001().insert(tt01);
mRoomDB.useTestTable001().insert("tt02");
logAllTestTable001();
}
private void logAllTestTable001() {
for (TestTable001 tt: mRoomDB.useTestTable001().getAllTestTable001()) {
Log.d(
"TTINFO",
"ID = " + tt.getId() +
" Name = " + tt.getName() +
" Date1 = " + tt.getDt1() +
" Date2 = " + tt.getDt2() +
" Date3 = " + tt.getDt3());
}
}
}
结果是:-
2019-12-14 03:18:32.569 D/TTINFO: ID = 1 Name = tt01 Date1 = null Date2 = null Date3 = null
2019-12-14 03:18:32.569 D/TTINFO: ID = 2 Name = tt02 Date1 = 2019-12-13 16:18:32 Date2 = 2019-12-13 16:18:32 Date3 = 1576253912
答案 1 :(得分:1)
找到了。没有阅读手册。
您必须创建一个第二类,而没有要插入的自动设置字段。
public class NameAndDescription {
String name;
String description
}
我认为,这不是一个好主意。 如果数据库中有一个自动增量字段,则在传递0时它将获得一个自动更新的值。 同样,传递null或“”时,应使用时间戳的默认值。
答案 2 :(得分:1)
我发现最好的解决方案是创建一个实现插入和更新方法的抽象Dao。我没有使用默认值(也许我做错了)。在这里查看我的答案:How to implement created_at and updated_at column using Room Persistence ORM tools in android