android數據庫框架DBFlow

 

創建你的數據庫

在DBFlow中,創建數據庫是非常簡單的,只需要定義一個@Database類:

@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION)
public class AppDatabase {

  public static final String NAME = "AppDatabase";

  public static final int VERSION = 1;
}

P.S.你可以定義多個@Database,但請保證他們沒有重名。

預包裝的數據庫

如果你需要在創建時載入一個預包裝好的數據庫,只需要將數據庫文件.db放在src/main/assets/{databaseName}.db,這樣在DBFlow創建數據庫的時候就會自動將這個數據庫拷貝進來使用。但請注意,由於預包裝的數據庫文件已經被打包進了APK文件,所以我們無法在拷貝後將其刪除,這會增加APK的大小(等於預包裝數據庫文件的大小)。

配置屬性

全局衝突處理:通過定義insertConflict()updateConflict(),任何沒有被明確定義的@Table都將使用與之對應的@Database中的表。
(Global Conflict Handling: By specifying insertConflict() and updateConflict() here, any @Table that does not explicitly define either itself will use the corresponding one from the associated @Database.)

Kotlin:3.0開始,我們提供了對Kotlin的良好支持。

以前我們需要定義一個generatedClassSeparator()爲之工作:

@Database(generatedClassSeparator = "_")

數據庫完整性檢查:如果設置了consistencyChecksEnabled()方法,我們將會在數據庫打開時運行PRAGMA quick_check(1)進行檢查。如果檢查失敗,我們將嘗試拷貝預定義的數據庫文件覆蓋當前數據庫。

簡單的數據庫備份: backupEnabled()開啓數據庫備份後,我們便可以簡單的備份數據庫了:

FlowManager.getDatabaseForTable(table).backupDB()

NOTE:請注意,這會首先生成一個臨時的數據庫,以防止備份失敗。

開啓外鍵常量(Constrants):使用foreignKeysSupported()=true開啓強制外鍵(the database enforce foreign keys)。如果設爲false,我們仍然能夠定義@ForeignKey,但它們的關係將不是強制的。

自定義OpenHelper類:通過繼承FlowSQLiteOpenHelper我們可以定義自己的Helper類。注意,在自定義Helper類中需要實現FlowSQLiteOpenHelper的構造函數:

public FlowSQLiteOpenHelper(BaseDatabaseDefinition flowManager, DatabaseHelperListener listener)

自定義的Helper類需要在@Database註解中通過sqlHelperClass()參數聲明使用。

Model & Creation

所有的標準Table類都必須帶上@Table註解並實現Model接口。爲了方便,我們提供了Model接口的標準實現BaseModel

Table數據類中支持的數據類型

  1. 所有Java標準的數據類型(booleanbyteshortintlongfloatdouble等)及相應的包裝類,以及String,當然我們還默認提供了對java.util.Datejava.sql.DateCalendar的支持。
  2. 其他不被支持的類型可以通過自定義TypeConverter來提供支持。範型類型的對象不被支持,容器類型如List、Map等同樣也是不推薦的。如果你一定要使用容器,你也只能在無法獲得範型參數情況下使用。
  3. 支持複合主鍵。
  4. 通過@ForeignKey可以嵌套其他的Model,即一對一的關係。
  5. 任何被作爲@ForeignKey使用的Model都必須是ModelContainer
  6. 支持多個@ForeignKey
  7. 通過在列屬性中顯式聲明@Column(typeConverter = SomeTypeConverter.class)來提供自定義的TypeConverter

表Model的規則

  1. 所有的Model必須有一個公共無參構造。在查詢時我們將會使用到這個構造函數。
  2. 對於一個繼承自另一個Model的子類,library將會收集全部被@Column註解標記的屬性(包括父類中的)。
  3. 默認情況下爲了方便,我們使用屬性變量名作爲數據表的列名,當然你也可以通過@Column中的參數來自定義列名。
  4. 爲了使_Adapter類可以訪問,屬性必須是public或者包私有的。
    NOTE:Package private fields need not be in the same package as DBFlow will generate the necessary access methods to get to them.
  5. 屬性如果被定義爲private,就必須提供對應的getter和setter方法,命名規則爲:對屬性{name},必須有get{Name}()set{Name}(columnType)方法。
  6. 所有的Model類都必須是可訪問的。內部類在3.0.0-beta1+後被支持。

Model示例

這裏是一個Model類的示例,其中包含一個主鍵(Table中必須有至少一個主鍵)和一個其他屬性。

@Table(database = AppDatabase.class)
public class TestModel extends BaseModel {

    // All tables must have a least one primary key
    @PrimaryKey
    String name;

    // By default the column name is the field name
    @Column
    int randomNumber;

}

高級Table特性

爲特定列指定自定義類型轉換器

從3.0版本開始,你可以爲特定列指定自定義的類型轉換器TypeConverter

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

這個自定義轉換器將會覆蓋默認的轉換器和訪問方法(除了私有屬性,對於私有屬性,自定義轉換器將會攔截訪問器方法)。

設置所有屬性都作爲列

我們可以通過設置@Table(allFields = true)將所有類中的屬性都設置爲列。當打開這個設置後,DBFlow會將所有public/package private、non-final、non-static屬性都作爲@Column。當然,這時你仍然需要顯式地設置至少一個@PrimaryKey主鍵。

私有屬性列

正如上面所說,你需要將作爲@Column的屬性都設爲public或package private,而如果一定要使用私有屬性則需要提供相應的getter與setter方法:

@Table(database = TestDatabase.class)
public class PrivateModelTest extends BaseModel {

    @PrimaryKey
    private String name;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

訪問器方法的命名方式按照java標準的命名方式,所以boolean類型可以使用“is”:

@Table(database = TestDatabase.class, useIsForPrivateBooleans = true)
public class PrivateModelTest extends BaseModel {

    @PrimaryKey
    private String name;

    @Column
    private boolean selected;

    public boolean isSelected() {
      return selected;
    }

    public void setSelected(boolean selected) {
      this.selected = selected;
    }

    //... etc
}

UNIQUE 約束

在SQLite中我們可以定義UNIQUE約束,即對於列或者列集合其在這個表中一定是唯一的。

UNIQUE('name', 'number') ON CONFLICT FAIL, UNIQUE('name', 'address') ON CONFLICT ROLLBACK

與SQL語句相似,DBFlow中我們是這樣定義UNIQUE約束的:

@Table(database = AppDatabase.class,
  uniqueColumnGroups = {@UniqueGroup(groupNumber = 1, uniqueConflict = ConflictAction.FAIL),
                        @UniqueGroup(groupNumber = 2, uniqueConflict = ConflictAction.ROLLBACK))
public class UniqueModel extends BaseModel {

  @PrimaryKey
  @Unique(unique = false, uniqueGroups = {1,2})
  String name;

  @Column
  @Unique(unique = false, uniqueGroups = 1)
  String number;

  @Column
  @Unique(unique = false, uniqueGroups = 2)
  String address;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章