表格和数据库属性

创建数据库

用DBFlow创建数据库是超级简单的。只要简单地定义一个占位符 @Database 类:

  1. @Database(name = AppDatabase.NAME, version = AppDatabase.VERSION)
  2. public class AppDatabase {
  3. public static final String NAME = "AppDatabase";
  4. public static final int VERSION = 1;
  5. }

P.S. 你可以定义为许多@Database 只要你喜欢,但是名称要唯一的。

预包装数据库

如果想为你得app包含预先准备好的数据库,直接把 “.db” 文件复制到src/main/assets/{databaseName}.db目录中。在创建数据库时,我们复制该文件给应用使用。由于这是APK内预先包装,在复制完后,我们无法将其删除,导致APK变大(取决于数据库文件大小)。

配置属性

全局冲突处理:在这里通过指定insertConflict()updateConflict(),任何 @Table没有明确定上面2个属性的任意一个,他将会使用最适合的一个关联@Database

以前,你需要定义一个generatedClassSeparator() 才能运行。

如果要更改默认_ ,只需添加一些字符串:

  1. @Database(generatedClassSeparator = "$$")

开放数据库的完整性检查:每当打开数据,consistencyChecksEnabled() 将运行一个PRAGMA quick_check(1),如果失败,它将尝试复制预先打包的数据库。

轻松备份数据库backupEnabled() 调用,可以备份数据库

  1. FlowManager.getDatabaseForTable(table).backupDB()

请注意:当数据库备份失败时,这将创建一个临时的第三方数据库。

打开外键Constrants:通过设置foreignKeysSupported()=true ,让数据库强制执行外键。默认情况下此处于关闭状态。们仍然可以定义@ForeignKey,但他们的关系不执行。

OpenHelper的定义实现:他们必须为FlowSQLiteOpenHelper配置构造参数:

  1. public FlowSQLiteOpenHelper(BaseDatabaseDefinition flowManager, DatabaseHelperListener listener)

public,并在 @Database 注解中指出了 sqlHelperClass() 自定义类。

模型与创造

所有标准表必须使用@Table 注解和实现Model接口。为方便起见,BaseModel提供了一个默认的实现。

Model的支持

  1. Fields: 支持任何默认Java类型.
  2. 类型转换器: 您可以定义非标准类的列,如Date, Calendar等,这些可以在列逐列的基础上进行配置。
  3. 复合 @PrimaryKey
  4. 复合 @ForeignKey. 嵌套 Model, ModelContainer, ForeignKeyContainer or standard @Column.
  5. 结合 @PrimaryKey@ForeignKey, 以及那些可以有复杂的主键。
  6. 内部类

Models的规则和技巧
1.Model必须有一个可访问的默认构造函数。这可以是public或package private.。

  1. 子类是完全支持。DBFlow将收集并结合每个子类“的注释并将它们组合为当前类。
  2. 字段可以是public,package private(我们生成package helpers访问),或private(要有getter和setter)。Private fields需要有一个getter get{Name}和setter set{Name}。这些也可以被配置。
  3. 我们可以继承非Model的类,这样类可以通过扩展inheritedColumns() (或inheritedPrimaryKeys())。这些都必须通过带有对应的getter和setter的 package-private, public, or private
  4. 结合 @PrimaryKey@ForeignKey, 以及那些可以有复杂的主键。
  5. 要启用缓存,设置 cachingEnabled = true,这将加快在大多数情况下检索。

简单例子

这是一个带有一个主键(一个Model最少有一个)和其他列的 Model

  1. @Table(database = AppDatabase.class)
  2. public class TestModel extends BaseModel {
  3. // All tables must have a least one primary key
  4. @PrimaryKey
  5. String name;
  6. // By default the column name is the field name
  7. @Column
  8. int randomNumber;
  9. }

高级表功能

为特定的列自定义类型转换器

在3.0,现在您可以为特定@Column指定一个TypeConverter,为转换器指定对应的Column

  1. @Column(typeConverter = SomeTypeConverter.class)
  2. SomeObject someObject;

它将取代通常的转换/访问方法(除如果该字段是私有的,它保留了基于私有访问方法)。

所有字段作为列

因为其他库也这样做,你可以设置 @Table(allFields = true) 打开使用所有的public/package private,non-final,,以及non-static 字段作为 @Column。你仍然需要提供至少一个 @PrimaryKey 字段。

如果您需要忽略一个字段,使用 @ColumnIgnore 注释。

私人列

如果你想使用私有字段,只需指定一个getter和setter,格式:name -> getName() + setName(columnFieldType)

  1. @Table(database = TestDatabase.class)
  2. public class PrivateModelTest extends BaseModel {
  3. @PrimaryKey
  4. private String name;
  5. public String getName() {
  6. return name;
  7. }
  8. public void setName(String name) {
  9. this.name = name;
  10. }
  11. }

boolean fields can use “is”

  1. @Table(database = TestDatabase.class, useIsForPrivateBooleans = true)
  2. public class PrivateModelTest extends BaseModel {
  3. @PrimaryKey
  4. private String name;
  5. @Column
  6. private boolean selected;
  7. public boolean isSelected() {
  8. return selected;
  9. }
  10. public void setSelected(boolean selected) {
  11. this.selected = selected;
  12. }
  13. //... etc
  14. }

默认值

当字段的值丢失或遗漏,希望提供在数据库中默认值。SQLite使用DEFAULT来实现。

然而,在DBFlow也不是那么容易,因为我们依靠预编译实现这个INSERT声明。因此,作为一种妥协,这些值插入这样:

  1. @Table(database = TestDatabase.class)
  2. public class DefaultModel extends TestModel1 {
  3. @Column(defaultValue = "55")
  4. Integer count;
  5. }

In the _Adapter:

  1. @Override
  2. public final void bindToInsertValues(ContentValues values, DefaultModel model) {
  3. if (model.count != null) {
  4. values.put("`count`", model.count);
  5. } else {
  6. values.put("`count`", 55);
  7. }
  8. //...
  9. }

我们在运行时插入它的值。这有一定的局限性:

  1. 常量, 纯字符串值
  2. No Model, ModelContainer, or primitive can use this.
  3. 必须是同一类型的
  4. String 类型需要通过进行转义: "\"something\""