一、初始化DBFlow
新建类 MyApplication 继承 Application,并在其中初始化DBFlow:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
FlowManager.init(this);// 初始化DBFlow
}
}
并在AndroidManifest.xml中注册:
<application
android:name=".MyApplication"
......
</application>
二、创建数据库
创建一个类MyDatabase,并加上 @Database 注解
@Database(version = MyDatabase.VERSION)
public class MyDatabase {
public static final int VERSION = 1;
}
三、建表
假设要建一张Person表,直接创建类Person 继承BaseModel,并加上 @Table 注解,定义里面的字段,并给字段加上 @Column 注解,主键可以加上 @PrimaryKey 注解
@Table(database = MyDatabase.class)
public class Person extends BaseModel {
@PrimaryKey(autoincrement = true)
public long id;
@Column
public String name;
@Column
public int age;
}
Make Project
点击 AndroidStudio 的 Build -> Make Project 之后,就可以在 app\build\generated\source\apt\debug 目录下找到生成的类 Person_Table,在里面可以看到一些 SQL 语句:
public final class Person_Table extends ModelAdapter<Person> {
/**
* Primary Key AutoIncrement */
public static final Property<Long> id = new Property<Long>(Person.class, "id");
public static final Property<String> name = new Property<String>(Person.class, "name");
public static final Property<Integer> age = new Property<Integer>(Person.class, "age");
public static final IProperty[] ALL_COLUMN_PROPERTIES = new IProperty[]{id,name,age};
public Person_Table(DatabaseDefinition databaseDefinition) {
super(databaseDefinition);
}
@Override
public final Class<Person> getModelClass() {
return Person.class;
}
@Override
public final String getTableName() {
return "`Person`";
}
@Override
public final Person newInstance() {
return new Person();
}
@Override
public final Property getProperty(String columnName) {
columnName = QueryBuilder.quoteIfNeeded(columnName);
switch ((columnName)) {
case "`id`": {
return id;
}
case "`name`": {
return name;
}
case "`age`": {
return age;
}
default: {
throw new IllegalArgumentException("Invalid column name passed. Ensure you are calling the correct table's column");
}
}
}
@Override
public final void updateAutoIncrement(Person model, Number id) {
model.id = id.longValue();
}
@Override
public final Number getAutoIncrementingId(Person model) {
return model.id;
}
@Override
public final String getAutoIncrementingColumnName() {
return "id";
}
@Override
public final ModelSaver<Person> createSingleModelSaver() {
return new AutoIncrementModelSaver<>();
}
@Override
public final IProperty[] getAllColumnProperties() {
return ALL_COLUMN_PROPERTIES;
}
@Override
public final void bindToInsertValues(ContentValues values, Person model) {
values.put("`name`", model.name);
values.put("`age`", model.age);
}
@Override
public final void bindToContentValues(ContentValues values, Person model) {
values.put("`id`", model.id);
bindToInsertValues(values, model);
}
@Override
public final void bindToInsertStatement(DatabaseStatement statement, Person model, int start) {
statement.bindStringOrNull(1 + start, model.name);
statement.bindLong(2 + start, model.age);
}
@Override
public final void bindToStatement(DatabaseStatement statement, Person model) {
int start = 0;
statement.bindLong(1 + start, model.id);
bindToInsertStatement(statement, model, 1);
}
@Override
public final void bindToUpdateStatement(DatabaseStatement statement, Person model) {
statement.bindLong(1, model.id);
statement.bindStringOrNull(2, model.name);
statement.bindLong(3, model.age);
statement.bindLong(4, model.id);
}
@Override
public final void bindToDeleteStatement(DatabaseStatement statement, Person model) {
statement.bindLong(1, model.id);
}
@Override
public final String getInsertStatementQuery() {
return "INSERT INTO `Person`(`name`,`age`) VALUES (?,?)";
}
@Override
public final String getCompiledStatementQuery() {
return "INSERT INTO `Person`(`id`,`name`,`age`) VALUES (?,?,?)";
}
@Override
public final String getUpdateStatementQuery() {
return "UPDATE `Person` SET `id`=?,`name`=?,`age`=? WHERE `id`=?";
}
@Override
public final String getDeleteStatementQuery() {
return "DELETE FROM `Person` WHERE `id`=?";
}
@Override
public final String getCreationQuery() {
return "CREATE TABLE IF NOT EXISTS `Person`(`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `age` INTEGER)";
}
@Override
public final void loadFromCursor(FlowCursor cursor, Person model) {
model.id = cursor.getLongOrDefault("id");
model.name = cursor.getStringOrDefault("name");
model.age = cursor.getIntOrDefault("age");
}
@Override
public final boolean exists(Person model, DatabaseWrapper wrapper) {
return model.id > 0
&& SQLite.selectCountOf()
.from(Person.class)
.where(getPrimaryConditionClause(model))
.hasData(wrapper);
}
@Override
public final OperatorGroup getPrimaryConditionClause(Person model) {
OperatorGroup clause = OperatorGroup.clause();
clause.and(id.eq(model.id));
return clause;
}
}
四、增删改查
DBFlow 对数据的增删改查已经做了封装,使用起来比较简单,也不很容易理解。
1、insert
对于向数据库插入数据的操作,对于已经继承了 BaseModel 的 bean,我们可以直接 new 一个出来,给相应的属性赋值之后,直接调用 save() 方法,数据就保存完毕了,代码如下。这里我们并没有给 Product 的主键 id 赋值,但是在保存完之后这个 id 就被赋值了。
Person person = new Person();
person.name = "Mike";
person.age = 23;
person.save();
2、query
List<Person> persons= SQLite.select()
.from(Person.class)
.where(Person_Table.name.isNotNull(), Person_Table.age.greaterThanOrEq(18))// 这里的条件也可以多个
.orderBy(Person_Table.id, true)// 按照 id 升序
.limit(3)// 限制 3 条
.queryList();// 返回的 list 不为 null,但是可能为 empty
3、update
// 第一种 先查后改
Person person3 = SQLite.select()
.from(Person.class)
.where(Person_Table.id.eq(1L))
.querySingle();// 区别与 queryList()
if (person3 != null) {
person3.name = "P0000";
person3.update();
}
// 第二种 直接sql
SQLite.update(Person.class)
.set(Person_Table.name.eq("Mike"))
.where(Person_Table.id.eq(1L))
.execute();
4、delete
//单个查找
Person person2 = SQLite.select()
.from(Person.class)
.where(Person_Table.id.eq(1L))
.querySingle();
if(person2 != null){
Log.d(TAG,person2.toString());
}
//范围查找
List<Person> persons= SQLite.select()
.from(Person.class)
.where(Person_Table.name.isNotNull(), Person_Table.age.greaterThanOrEq(18))// 这里的条件也可以多个
.orderBy(Person_Table.id, true)// 按照 id 升序
.limit(3)// 限制 3 条
.queryList();// 返回的 list 不为 null,但是可能为 empty
Log.d(TAG,persons.toString());
五、数据库版本升级
1、因为新建表而升级
当要在数据库中新建一个表的时候,就会涉及到数据库的版本升级,得将之前创建数据库时候设置的版本号VERSION+1,然后再去建立新的表,否则会报错。
public static final int VERSION = 2;
2、因修改表结构而升级
DBFlow 的表结构修改是通过 Migration 实现的,通过对它的实现,来进行对表的操作。
- AlterTableMigration 用于重命名表,增加列
- IndexMigration/IndexPropertyMigration 用于索引创建和删除
- UpdateTableMigration 升级数据库的时候更新数据
下面用AlterTableMigration举例:
首先,新建一个StudentMigration类,继承AlterTableMigration
然后,添加 @Migration 注解,标明新版本号和所在数据库名
最后,重写 onPreMigrate() 方法,在该方法中添加新的字段
下面在Student表中添加一个新的列mom_id
@Migration(version = 3,database = MyDatabase.class)
public class StudentMigration extends AlterTableMigration<Student> {
public StudentMigration(Class<Student> table) {
super(table);
}
@Override
public void onPreMigrate() {
addColumn(SQLiteType.INTEGER,"mom_id");
}
}
最后,重新运行程序,就可以添加新的字段。