DBFlow新版使用
一、DBFlow4.2.4介绍
DBFlow是一个基于AnnotationProcessing(注解处理器)的ORM框架。此框架设计为了速度、性能和可用性。消除了大量死板的数据库代码,取而代之的是强大而又简介的API接口。
二、特性:
1、无缝支持多个数据库;
2、使用annotation processing提高速度;
3、ModelContainer类库可以直接解析像JSON这样的数据;
4、增加灵活性的丰富接口。
三、该实例涉及功能:
1.数据库增删改查(操作封装)
2.同/异步+事物操作
3.数据库升级(新增表+新增字段+默认值设置等)+自定义数据库存储路径
四、配置:
在项目目录的build.gradle中加入:
allprojects { repositories { ... maven { url "https://jitpack.io" } } }
在工程目录的build.gradle中加入:
apply plugin: 'com.android.application' def dbflow_version = "4.2.4" android { ... } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:27.1.1' testImplementation 'junit:junit:4.12' annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:$dbflow_version" // gradle 3.0.0 可以使用 implementation,否则用 compile implementation "com.github.Raizlabs.DBFlow:dbflow-core:$dbflow_version" implementation "com.github.Raizlabs.DBFlow:dbflow:$dbflow_version" // }
五、使用
1.创建DataBase
@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION) public class AppDatabase { //版本号 public static final int VERSION = 1; //数据库名称 public static final String NAME = "App2018DB"; }
2.创建Model
必须继承BaseModel,BaseModel包含了基本的数据库操作(save、delete、update、insert、exists)
//必须是共有的修饰符,如果使用私有属性则返回(老的版本记得写get/set方法就可以了): // Error:Execution failed for task ':xxx:compileDebugJavaWithJavac'.> //Compilation failed; see the compiler error output for details. @Table(database =AppDatabase.class) public class BigSeaInfo0 extends BaseModel{ @PrimaryKey(autoincrement = true) @Column public int userId; @Column public String name; @Column(defaultValue = "18")//默认值无效 public int age=20;//有效 @Column//(name = "desc") public String remarks; @Column public long money=3000; } //备注:DBFlow会根据你的类名自动生成一个表明,以此为例: //这个类对应的表名为:UserData_Table //常用注解操作符: // @Table、 // @PrimaryKey、//主键 // @Column、//列 // @Unique、:唯一的 // @ForeignKey:外键,一般数据裤不常用 // 等
3.DbFlow初始化
//初始化方式有三种: public class App extends Application { @Override public void onCreate() { super.onCreate(); //DBFlow初始配置:3中方式 //FlowManager.init(this);// 初始化方式1 //FlowManager.init(new FlowConfig.Builder(this).build());//初始化方式2 //自定义路径-初始化方式3--> api>=23需授权(文件读写),再添加此操作,具体见StartActivity // FileDatabaseContext mSdDatabaseContext = // new FileDatabaseContext(getApplicationContext()); // FlowManager.init(mSdDatabaseContext); FlowLog.setMinimumLoggingLevel(FlowLog.Level.V);//添加日志 }
4.一般使用操作:
//-------------------------添加操作----------------------- //DBFlow 对数据的增删改查已经做了封装,使用起来比较简单 private void insertBaseModle() { BigSeaInfo0 product = new BigSeaInfo0(); product.name = "P000" + index; product.age = 18 + index; product.remarks = "备注-" + index; product.money = 300 * index; // product.insert(); boolean success = product.save(); index++; // 执行到这里之后 id 已经被赋值 App.showToast(this, "添加结果:" + success); } //-------------------------修改操作----------------------- /* * 更新和删除可以为先查询后操作,只要查到对应的数据,在 bean 上做修改, * 然后调用 update() 方法,数据库就能修改完成。还有另一中更接近 sql 语法的方式。 */ private void updateBaseModle0() { // 第一种 先查后改 BigSeaInfo0 product = SQLite.select() .from(BigSeaInfo0.class)//查询第一个 .where(BigSeaInfo0_Table.name.is("P0000")) .querySingle();// 区别与 queryList() if (product != null) { Log.d("zhh_Bd", "Update: " + product.name + " update to P0000"); product.name = "P000X"; boolean success = product.update(); App.showToast(this, "修改结果:" + success); } else { App.showToast(this, "name=P0000的条件数据不存在:"); } } // update:第二种 高级用法,删改查都是同理 private void updateBaseModle1() { SQLite.update(BigSeaInfo0.class) .set(BigSeaInfo0_Table.name.eq("PXXXX")) .where(BigSeaInfo0_Table.name.is("P0001")) .execute(); } //-------------------------删除操作----------------------- //删除1 private void deleteBaseModle() { // 第一种 先查后删 BigSeaInfo0 product = SQLite.select() .from(BigSeaInfo0.class) .where(BigSeaInfo0_Table.name.is("P00010")) .querySingle();//查询单个 if (product != null) { product.delete(); Log.d("zhh_db", "Delete: " + product.name); } //删除一张表 // Delete.table(BigSeaInfo0.class); // 删除多张表 // Delete.tables(MyTable1.class, MyTable2.class); } //删除2 private void deleteBaseModle1() { // 第二种 SQLite.delete(BigSeaInfo0.class) .where(BigSeaInfo0_Table.name.is("PXXXX")) .execute(); } //-------------------------查询操作----------------------- //查询 private void selectBaseModle() { // List<BigSeaInfo0> list = SQLite.select().from(BigSeaInfo0.class).queryList(); List<BigSeaInfo0> list = SQLite.select().from(BigSeaInfo0.class). where(BigSeaInfo0_Table.name.like("P%")).queryList(); printData(list); } //异步执行查询:尽管是异步的,但是线程安全的 private void selectBaseModleSync() { SQLite.select().from(BigSeaInfo0.class)//.where(BigSeaInfo0_Table.name.is("")) .async().queryListResultCallback(new QueryTransaction. QueryResultListCallback<BigSeaInfo0>() { @Override public void onListQueryResult(QueryTransaction transaction, @NonNull List<BigSeaInfo0> tResult) { printData(tResult);//更新UI } }); } //指定字段升降序查询 private void selectBaseModleOrderBy() { //true为'ASC'正序, false为'DESC'反序 List<BigSeaInfo0> list = SQLite.select() .from(BigSeaInfo0.class) .where() .orderBy(BigSeaInfo0_Table.userId, true) .queryList(); printData(list); } //分组查询--以年龄+名字分组查询:先排序后分组 private void selectBaseModleGroupBy() { List<BigSeaInfo0> list = SQLite.select() .from(BigSeaInfo0.class) .groupBy(BigSeaInfo0_Table.age, BigSeaInfo0_Table.name) .queryList(); printData(list); } //分页查询--每页查询3条--》limit后面跟的是3条数据,offset:是从第(page*3)条开始读取 private void selectPageBaseModle(int page) { List<BigSeaInfo0> list = SQLite.select() .from(BigSeaInfo0.class) .limit(3)//条数-》3 .offset(page * 3)//当前页数 .queryList(); printData(list); }
5.事物回滚+异步操作
//-------------------------添加操作----------------------- private void insertBaseModle0() { BigSeaInfo0 product = new BigSeaInfo0(); product.name = "P000" + index; product.age = 18 + index; product.remarks = "备注-" + index; product.money = 300 * index; //boolean success = product.save(); boolean success = product.async().save();//异步 //添加成功,但是返回为false,因为是异步,还未执行完成异步就返回值了,所以需要配置事物操作(个人理解) index++; // 执行到这里之后 id 已经被赋值 App.showToast(this, "添加结果:" + success); } //异步执行查询:尽管是异步的,但是线程安全的 private void insertBaseModle1() { //自己去实现事务批量保存 Transaction transaction = FlowManager.getDatabase(AppDatabase.class). beginTransactionAsync(new ITransaction() { @Override public void execute(DatabaseWrapper databaseWrapper) { // todo 处理list保存:批量添加 int i = 0; Iterator<BigSeaInfo0> iterator = resultList().iterator(); while (iterator.hasNext()) { BigSeaInfo0 info = iterator.next(); boolean success = info.save(); i = success ? ++i : i; } Log.i("zhh_db_sync", "成功添加了数据条数:" + i); } }).build(); transaction.execute(); //transaction.executeSync();//异步执行 } private void insertBaseModle2() { FlowManager.getDatabase(AppDatabase.class) .beginTransactionAsync(new ProcessModelTransaction.Builder<>( new ProcessModelTransaction.ProcessModel<BigSeaInfo0>() { @Override public void processModel(BigSeaInfo0 bigSeaInfo0, DatabaseWrapper wrapper) { // do work here -- i.e. user.delete() or user.update() //增删改操作等,这里添加集合对象 boolean success = bigSeaInfo0.save(); Log.i("zhh_db_sync", "添加结果" + success); } }).addAll(resultList()).build()) .error(new Transaction.Error() { @Override public void onError(Transaction transaction, Throwable error) { App.showToast(DbFlowTransactionActivity.this, "error结果:" + error.getMessage()); Log.i("zhh_db_sync", "error结果" + error.getMessage()); } }) .success(new Transaction.Success() { @Override public void onSuccess(Transaction transaction) { App.showToast(DbFlowTransactionActivity.this, "success结果:" + transaction.name()); Log.i("zhh_db_sync", "添加success"); } }).build() // .execute();//同步 .executeSync();//异步 } //-------------------------修改||删除操作----------------------- private void updateBaseModle0() { //不存在的条件数据做更改,也走成功的方法 SQLite.update(BigSeaInfo0.class) .set(BigSeaInfo0_Table.name.eq("PXXXX")) .where(BigSeaInfo0_Table.name.is("P0001")) .async() .error(new Transaction.Error() { @Override public void onError(@NonNull Transaction transaction, @NonNull Throwable error) { Log.i("zhh_db_sync", "异步修改error---" + error.getMessage()); } }).success(new Transaction.Success() { @Override public void onSuccess(@NonNull Transaction transaction) { Log.i("zhh_db_sync", "异步修改success"); } }).execute(); } //删除同上,SQLite.update--》改为SQLite.delete //-------------------------查询操作----------------------- //提供了三种方式 //方式1:QueryResultSingleCallback:单个查询 SQLite.select().from(BigSeaInfo0.class).where(BigSeaInfo0_Table.name.is("P0000")) .async()//异步查询 .querySingleResultCallback(new QueryTransaction. QueryResultSingleCallback<BigSeaInfo0>() { @Override public void onSingleQueryResult(QueryTransaction transaction, @Nullable BigSeaInfo0 bigSeaInfo0) { if(null!=bigSeaInfo0){ Log.i("zhh_db_sync", "对象查询-----异步2--id---" + bigSeaInfo0.userId + ",name->" + bigSeaInfo0.name + ",age---" + bigSeaInfo0.age + ",note--" + bigSeaInfo0.remarks + ",money-->" + bigSeaInfo0.money); }else{ App.showToast(DbFlowTransactionActivity.this,"数据为空"); } } }) .error(new Transaction.Error() { @Override public void onError(@NonNull Transaction transaction, @NonNull Throwable error) { Log.i("zhh_db_sync", "Sync-----error--" + error.getMessage()); } }).success(new Transaction.Success() { @Override public void onSuccess(@NonNull Transaction transaction) { Log.i("zhh_db_sync", "Sync-----success--" + transaction.name()); //更新Ui操作 } }).execute(); //方式2:QueryResultListCallback:集合查询 SQLite.select().from(BigSeaInfo0.class)//.where(BigSeaInfo0_Table.name.is("")) .async()//异步查询 .queryListResultCallback(new QueryTransaction. QueryResultListCallback<BigSeaInfo0>() { @Override public void onListQueryResult(QueryTransaction transaction, @NonNull List<BigSeaInfo0> tResult) { printData(tResult);//更新UI } }).error(new Transaction.Error() { @Override public void onError(@NonNull Transaction transaction, @NonNull Throwable error) { Log.i("zhh_db_sync", "SyncList--error---" + error.getMessage()); } }).success(new Transaction.Success() { @Override public void onSuccess(@NonNull Transaction transaction) { Log.i("zhh_db_sync", "SyncList---success--" ); } }).execute(); //方式3:QueryResultCallback:方式1+2的统一 SQLite.select().from(BigSeaInfo0.class).async().queryResultCallback( new QueryTransaction.QueryResultCallback<BigSeaInfo0>() { @Override public void onQueryResult(@NonNull QueryTransaction<BigSeaInfo0> transaction, @NonNull CursorResult<BigSeaInfo0> tResult) { BigSeaInfo0 bigSeaInfo0 = tResult.toModel(); //这里可以是返回集合:tResult.toList() Log.i("zhh_db_sync", "对象查询-----异步1-->id---" + bigSeaInfo0.userId + ",name->" + bigSeaInfo0.name + ",age---" + bigSeaInfo0.age + ",note--" + bigSeaInfo0.remarks + ",money-->" + bigSeaInfo0.money); tResult.close();//关闭资源 } }).execute();
六、数据库升级
当你升级数据库@Database版本,只需要添加一个Migration来配置升级操作,DBFlow 已经有它的几个现成的实现提供给我们进行使用:
1.AlterTableMigration 用于重命名表,增加列
2.IndexMigration/IndexPropertyMigration 用于索引创建和删除
3.UpdateTableMigration 升级数据库的时候更新数据
数据库升级–添加列(设置默认值)&新增表—-版本改为2,之前是1(个人建议version=10—》参照build.gradle中的versionName:1.0)如下:
//----------------升级-新增表:改版本好即可 //----------------升级-新增列:新增下面代码 @Migration(version = VERSION, database = AppDatabase.class)//=2的升级 public static class Migration1 extends AlterTableMigration<BigSeaInfo0> { // Migration可设置优先级,高优先级的将先被执行。 //Migration有3个方法: //onPreMigrate() 首先被调用,在这儿设置和构造 //migrate() 具体的迁移在这儿执行 //onPostMigrate() 执行一些清理工作,或者执行完成的通知 public Migration1(Class<BigSeaInfo0> table) { super(table); } @Override public void onPreMigrate() { //所有Java标准的数据类型(boolean、byte、short、int、long、float、double等)及相应的包装类, // 以及String,当然我们还默认提供了对java.util.Date、java.sql.Date与Calendar的支持。 // 使用如下:这里值添加remarks2 //addColumn(SQLiteType.get(long.class.getName()), "money");//基本数据类型 //addColumn(SQLiteType.get(int.class.getName()), "money");//基本数据类型 //addColumn(SQLiteType.get(double.class.getName()), "money");//基本数据类型:浮点数 //addColumn(SQLiteType.get(String.class.getName()), "money");//基本数据类型:浮点数 addColumn(SQLiteType.TEXT, "remarks2"); } }
具体使用,请下载源码: