Android最好用的数据库框架——DBFLOW全面解析
前言
为什么说DBFLOW是最好用的数据库框架?因为它综合了各个数据库的框架的优点,它比GreenDao要使用简单,同时又比ActiveAndroid性能高很多,它是一款操作简单又高效的ORM框架。
初始DBFLOW
根据官方介绍可以知道,DBFLOW是一个为Android设计的简单高效的数据库类库,它基于注解在编程过程中生成操作类,性能高效,操作安全。
DBFLOW正确使用姿势
DBFLOW配置(build.gradle版本3.0以下)
引入apt和maven,配置在工程下gradle里面
repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0-beta6' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } allprojects { repositories { jcenter() maven { url "https://jitpack.io" } }
在app的gradle下配置apply plugin: 'com.neenbedankt.android-apt',同时导入依赖包
apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' def dbflow_version = "3.0.0-beta4" android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "cn.taoweiji.dbflowexample" minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) apt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}" compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}" compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}" }
以上就是build.gradle版本3.0以下的DBFLOW的配置方式,基本上就是各种导包
--------------------------------------分割线-----------------------------------------
在Android Studio3.0以上版本、build.gradle版本3.0以上,已经把apt的注解方式修改为annotationProcessor,对应在配置也发生了变化,不需要再配置apt相关的设置
build.gradle版本3.0以上DBFLOW相关配置
工程下的gradle文件
buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.0' // 不需要配置apt // classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() maven { url "https://www.jitpack.io" } } } task clean(type: Delete) { delete rootProject.buildDir }
app下的gradle文件
apply plugin: 'com.android.application' def dbflow_version = "4.2.1" android { compileSdkVersion 27 defaultConfig { applicationId "com.kaka.dbflowdemo" minSdkVersion 18 targetSdkVersion 27 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}" implementation "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}" implementation "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}" // sql-cipher database encyrption (optional) implementation "com.github.Raizlabs.DBFlow:dbflow-sqlcipher:${dbflow_version}" }
建议使用annotationProcessor这种注解方法,不仅是配置简单,而且Android Studio对这种注解方式也进行了优化。
初始化DBFLOW
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); //初始化DBFLOW FlowManager.init(this); } }
别忘了在清单文件里面把application修改为当前Application
创建数据库
@Database(name = AppDataBase.NAME,version = AppDataBase.VERSION) public class AppDataBase { public static final String NAME="AppDataBase"; public static final int VERSION=1; }
创建一个类,需要声明一下数据库的NAME和VERSION,该@Database注释生成一个DatabaseDefinition现在引用名为“AppDatabase.db”的文件中的磁盘上的SQLite数据库。你可以在代码中引用它,DatabaseDefinition db = FlowManager.getDatabase(AppDatabase.class);
创建表
两种方式
第一种(不推荐)
@Table(database = AppDataBase.class) public class User { @PrimaryKey UUID id; @Column String name; @Column int age; }
这种是最简单的方式,创建User类,通过注解来声明对应的数据库字段,@PrimaryKey是主键,@Column是字段的意思
第二种(推荐)
@Table(database = AppDataBase.class) public class User2Model extends BaseModel { @PrimaryKey(autoincrement = true) private int id; @Column private String name; @Column private int age; @Column private long timeStamp; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public long getTimeStamp() { return timeStamp; } public void setTimeStamp(long timeStamp) { this.timeStamp = timeStamp; } }
使用这种方法创建表我们推荐,继承了BaseModel以后会更好更方便地让我们操作数据,代码更加简洁。
注:不要重写构造方法,不要重写构造方法,不要重写构造方法;重要的事情说三遍。
CRUD基本操作
第一种创建表的方式的操作
User user=new User(); user.id= UUID.randomUUID(); user.name="kaka"; user.age=18; ModelAdapter<User> adapter=FlowManager.getModelAdapter(User.class); //插入User adapter.insert(user); //修改名字 user.name = "Test"; adapter.update(user); User userQuery=SQLite.select().from(User.class).querySingle(); Log.e(TAG,"id="+userQuery.id+",name="+userQuery.name+",age="+userQuery.age);
第二种创建表的方式
User2Model userModel=new User2Model(); userModel.setName("UserModel"); userModel.setAge(new Random().nextInt(100)); userModel.save(); userModel.update(); userModel.delete();
从代码也可以看出第二种方式的代码更加简洁,打开BaseModel源码看一眼里面重写了getModelAdapter方法
public ModelAdapter getModelAdapter() { if (modelAdapter == null) { modelAdapter = FlowManager.getModelAdapter(getClass()); } return modelAdapter; }
跟第一种实现的方式ModelAdapter<User> adapter=FlowManager.getModelAdapter(User.class);其实是一样的,只不过更简单一些。
查询:
DBFLOW在查询方法提高了很强大的支持,无论你是要排列、分组还是各种条件查询都可以满足
List<User2Model> user2Models=SQLite.select().from(User2Model.class).where(User2Model_Table.age.greaterThan(18),User2Model_Table.name.eq("UserModel")) .orderBy(OrderBy.fromNameAlias(NameAlias.of("id"))) .groupBy(NameAlias.of("id")) .queryList(); if (user2Models.size()!=0){ for (User2Model user2Model:user2Models){ Log.e(TAG,"id="+user2Model.getId()+",name="+user2Model.getName()+",age="+user2Model.getAge()); } }else{ Toast.makeText(this,"数据为0",Toast.LENGTH_SHORT).show(); }
看到这样小伙伴们可能要问了User2Model_Table这个是个什么鬼,之前在对DBFLOW介绍的时候也说到了,DBFLOW是根据注解在编译过程生成对应的操作类,在你建好表(User2Model)以后,Make Project一下(或者ReBuild只要让代码重新编译一下)就会生成对应User2Model_Table操作类对象,这个XXX_Table操作对象在条件搜索过程都会被用到。
事务操作、批量操作
事务操作是我们数据库不得不去了结,DBFLOW当然也支持了事务的相关操作。
FlowManager.getDatabase(AppDataBase.class).executeTransaction(new ITransaction() { @Override public void execute(DatabaseWrapper databaseWrapper) { for (int i=0;i<100;i++){ User2Model userModel=new User2Model(); userModel.setName("UserModel"); userModel.setAge(new Random().nextInt(100)); userModel.save(databaseWrapper); } } });
这种是同步事务的方法,虽然DBFLOW执行的速度非常快,效率也很好,但是我们不推荐,因为当我们批量操作数据越来越大的时候,同步事务就会变成一个耗时的操作,而耗时操作我们要放在子线程里执行,这样就需要异步执行事务的方法
//异步事务 FlowManager.getDatabase(AppDataBase.class).beginTransactionAsync(new ITransaction() { @Override public void execute(DatabaseWrapper databaseWrapper) { for (int i=0;i<100;i++){ User2Model userModel=new User2Model(); userModel.setName("UserModel"); userModel.setAge(new Random().nextInt(100)); userModel.save(databaseWrapper); } } }).success(new Transaction.Success() { @Override public void onSuccess(@NonNull Transaction transaction) { Log.e(TAG,"onSuccess()"); } }).error(new Transaction.Error() { @Override public void onError(@NonNull Transaction transaction, @NonNull Throwable error) { Log.e(TAG,"onError()"); } }).build().execute();
一波非常简洁的链式操作,并且提供好了事务操作成功和失败的回调
数据库升级(增加表、修改表字段等)
如果要增加表,除了要创建表以外,还要修改数据库版本号,如果没有修改数据库版本号,那么再调表对象的时候就会报出一个经典错误,no such table,但凡报这个错误都是你数据版本号没有修改。
如果要修改表的字段或者增加字段,相对来说稍微麻烦一点。DBFLOW专门提供了AlterTableMigration<T>这个类来修改表相关的资料。以User2Model这个表为例,假如说我们要增加一个字段timeStamp是long类型的,不仅改数据库版本号,同时在类对象中增加 @Column
private long timeStamp; 字段以外,还需要增加咱们刚才提到的AlterTableMigration的子类来修改
@Migration(version = AppDataBase.VERSION,database = AppDataBase.class) public class Migration1 extends AlterTableMigration<User2Model> { public Migration1(Class<User2Model> table) { super(table); } @Override public void onPreMigrate() { super.onPreMigrate(); addColumn(SQLiteType.INTEGER,User2Model_Table.timeStamp.getNameAlias().name()); } }
继承AlterTableMigration重写onPreMigrate,在里面写你需要
修改表的操作,这里我们需要增加一个字段addColumn(SQLiteType.INTEGER,User2Model_Table.timeStamp.getNameAlias().name()); 这样就ok了
总结
DBFLOW是一个很强大的ORM框架,不仅有文中提到这些基本操作,它还支持Kotlin语言、RxJava以及各种高级用法,不过这些一般在我们客户端使用的情况不多,这里不作为重点介绍,感兴趣的小伙伴可以看一下官网的介绍https://agrosner.gitbooks.io/dbflow/content/StoringData.html
最后的最后放上我的github地址:https://github.com/kaka10xiaobang/DBFLOW_DEMO

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
xamarin android网络请求总结
xamarin android中网络请求的框架非常多,在项目中使用的是第三方的一个网络请求框架restsharp,应该是github上.net网络请求最多star的框架,没有之一。这里就简单汇总了其他的一些网络请求的例子,主要还是分为android和.net两种平台。.net 中可以使用HttpWebRequest、HttpClient、RestSharp第三框的一些框架,android的有HttpURLConnectin、HttpClient、OkHttp、Retrofit、Volley 下面就用.net中的httpwebrequest、httpclient、restsharp和android中的httpURLConnection、okhttp实现一个get方式获取图片、post方式提交表单,适合新手入门看看总结一下。效果图如下: 1.HttpWebRquest、HttpWebResponse 命名空间: System.Net;程序集: System(位于 System.dll) 1 public class HttpWebRequestUtil 2 { 3 //发送get请求获取b...
- 下一篇
Q1全球智能机销量增长3.9% 三星苹果华为居三甲
5月20日,据国外科技媒体Android Authority报道,市场研究公司Gartner日前发布的2016年第一季度全球智能机市场报告显示,今年Q1智能手机总体销量为3.5亿部,同比增长了3.9%。 厂商方面,尽管三星的市场份额自从去年同期以来一直在缓慢下跌,但三星仍然保住了第一的位置,其市场份额为23.2%。由于iPhone6s和iPhone 6s Plus的表现较差,苹果的市场占有率从17.9%跌至14.8%。剩下的前五名则被中国公司包揽,华为和OPPO可能是真正的赢家,其市场占有率分别增长了2.9%和2.6%,排在第三和第四位,小米微跌0.1%,排在第五位。 操作系统方面,Android的市场份额增长了5.0%,由于iPhone市场份额下降,iOS的市场占有率下跌至14.8%.也许在iPhone SE的带动下,iOS的市场份额在下一个季度会有所上升。 由于过去一年微软手机销售毫无起色,Windows Phone的市场份额跌至0.7%。鉴于推出Windows Phone 10产品的厂商数量有限,微软恐怕是很难翻身了。 至于黑莓,由于开始转投Android,黑莓操作系统的市场份额...
相关文章
文章评论
共有0条评论来说两句吧...