前言
当初学习Hibernate的时候就非常惊叹这种ORM思想,后来才知道原来Android中也有这种基于ORM思想的开源框架greenDAO。
greenDAO简介:
简单的讲,greenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案。(greenDAO is a light & fast ORM solution that maps objects to SQLite databases.) Dao全称是Data Access Object – 数据访问对象.它是一个中间件,对象正是通过它才能和数据库中的表建立联系.
什么是ORM
ORM全称是Object Relationship Mapping – >对象关系映射,将一个对象映射为数据库中的一个表.
对象关系映射,简单的说就是对象模型和关系模型的一种映射。为什么要有这一个映射?因为现在的开发语言基本是oop的,但是传统的数据库却是关系型的,为了可以靠贴近面向对象开发,我们想要像操作对象一样操作数据库。
ORM 的优点:
- 让业务代码访问对象,而不是数据库表
- 隐藏面向对象的逻辑SQL查询详情
- 无需处理数据库实现
原生操作数据库的api的缺点
- 手动拼接sql
- 大量而重复操作数据库代码
- 不能自动把数据中的数据映射为对象
- 没有实现级联查询
主流的ORM框架:
- OrmLiet
- SugarORM
- LitePal
- GreenDAO
对比一个开源框架是否更优秀,一般从下面几个点来对比
- 性能:性能好一般指的是效率问题
- 文档:完整的文档可以避免很多弯路,方便学习
- 流行性:流行证明用户群体多,也方便交流合作
- 使用是否简单:学习成本问题
- 拓展性:拓展性当然需要
greenDao优点:
- 一个精简的库
- 性能最大化
- 内存开销最小化
- 易于使用的 APIs
- 对 Android 进行高度优化
学习方法
对于一项新技术,我本人非常推崇看官方的英文介绍,这样原汁原味。
- 官网:官网
- 官方github:greenDao
接下来总结下使用步骤。
如何使用GreenDAO
第一步:
使用AS新建项目
app module 里面添加gradle依赖:
compile 'de.greenrobot:greendao:2.1.0'
不要忘记同步一下
第二步:
在项目中新建一个module,类型选择Java Library如下图,命名为greendaogenerate
在该module的gradle里面添加依赖:
compile 'de.greenrobot:greendao-generator:2.1.0'
不要忘记同步一下
第三步:
在greendaogenerate这个module里面D的MyClass类里根据greenDAO的api配置数据库帮助类以及建表。示例如下:
public class MyClass {
public static void main(String arg[]){
//第一个参数是db的版本号,第二个是生成的包名(该包下若干数据库操作帮助类)
Schema schema = new Schema(1,"www.greendao.com");
Entity son = schema.addEntity("Son");//创建一个son表
//给son表添加属性
son.addStringProperty("name");
son.addIntProperty("age");
son.addIdProperty();
Property fatherId = son.addLongProperty("fatherId").getProperty();//设置外键
Entity father = schema.addEntity("Father");//创建一个father表
//给father表添加属性
father.addIdProperty();
father.addStringProperty("name");
father.addIntProperty("age");
son.addToOne(fater,fatherId);//建立关联
try {
//设置生成的包(www.greendao.com)所存放的的路径
new DaoGenerator().generateAll(schema,"app/src/main/java");
}catch (Exception e){
e.printStackTrace();
}
}
}
运行该MyClass类,结果如下:
这时候就可以在项目中使用这些由greenDAO框架生成的数据库帮助类进行测试了。
第四步
在MainActivity里面具体使用,api的使用示例以及介绍见下面代码
public class MainActivity extends AppCompatActivity {
//greenDAO提供的帮助类
private DaoMaster master;
private DaoSession session;
private SQLiteDatabase db;
private SonDao sonDao;
private FatherDao fatherDao;
private void openDb(){
//创建一个名为person.db的数据库
db = new DaoMaster.DevOpenHelper(MainActivity.this,"person.db",null).getWritableDatabase();
master = new DaoMaster(db);
session = master.newSession();
//获得son表操作数据库类的对象
sonDao = session.getSonDao();
//获得father表操作数据库类的对象
fatherDao = session.getFatherDao();
}
//插入数据
private void addPerson(){
//下面代码具体得根据数据库表的关系,这里只是示例(son有多个father)
Son son = new Son();
son.setName("nate");
son.setAge(29);
sonDao.insert(son);
Father father = new Father();
father.setName("Tom");
father.setSon(son);
fatherDao.insert(father);
Father father2 = new Father();
father2.setName("Jane");
father2.setSon(son);
fatherDao.insert(father2);
}
//常用api:
//list() 直接取出数据返回一个list并缓存数据
//listLazy() 不直接取出数据返回一个list有缓存,需手动close
//listLazyUncached() 延迟加载返回一个list不缓存数据,需手动close
//listIterator() 遍历数据,返回一个迭代器
public void queryAll(){
//listLazy()懒加载,多个表级联查询使用最佳
List<Son> list = sonDao.queryBuilder().list();//查询son表中的所有数据,返回集合
for (Son son: list){
Log.d("nate","queryAll() called with: "+son);
}
}
//条件查询: Eq 查询
public void queryEq(){
Son nate = sonDao.queryBuilder().where(SonDao.Properties.Name.eq("nate")).unique();
Log.d("nate","queryEq called with:"+ nate);
}
//条件查询: like 查询
public void queryLike(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Name.like("nate%")).list();
Log.d("nate","queryEq called with:"+ data);
}
//条件查询: between 查询
public void queryBetween(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Age.between(16,20)).list();
Log.d("nate","queryBetween called with:"+ data);
}
//条件查询: > 大于 查询
public void queryGt(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Age.gt(16)).list();
Log.d("nate","queryGt called with:"+ data);
}
//条件查询: < 小于 查询
public void queryLt(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Age.lt(16)).list();
Log.d("nate","queryLt called with:"+ data);
}
//条件查询: NotEq 查询
public void queryNotEq(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Age.notEq(16)).list();
Log.d("nate","queryNotEq called with:"+ data);
}
//条件查询: GE 大于等于 查询
public void queryGE(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Age.ge(16)).list();
Log.d("nate","queryGE called with:"+ data);
}
//条件查询: 排序 查询
public void queryOrder(){
List data = sonDao.queryBuilder().where(SonDao.Properties.Name.like("nate%"))
.orderDesc(SonDao.Properties.Age).list();
Log.d("nate","queryOrder called with:"+ data);
}
//拼装sql语句查询,在api无法满足查询需求的情况下使用
public void querySQL(){
List data = sonDao.queryBuilder()
.where(new WhereCondition.StringCondition(
"FATHER_ID IN" +"{SELECT _ID FROM FATHER WHERE AGE <50}"
)).list();
Log.d("nate","querySQL called with:"+ data);
}
//多线程查询:有兴趣可以看源码
public void queryThread(){
final Query query = sonDao.queryBuilder().build();
new Thread(){
@Override
public void run() {
List data = query.forCurrentThread().list();
Log.d("nate","queryThread called with:"+ data);
}
};
}
//一对多查询:具体得看数据表关系
public void queryOneToMany(){
List<Son> sons = sonDao.queryBuilder().list();//查询son表中的所有数据,返回集合
for (Son son:sons){
List<Father> fathers = son.getFathers();
for (Father father:fathers){
Log.d("nate","queryOneToMany() called with: "+son.getName()+" father:"+father.getName());
}
}
}
//一对一查询:具体得看数据表关系
public void queryOneToOne(){
List<Son> sons = sonDao.queryBuilder().list();//查询son表中的所有数据,返回集合
for (Son son:sons){
// Log.d("nate","queryOneToOne() called with: "+son.getFather().getName());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//打开一个数据库
openDb();
//向数据库添加person
addPerson();
//设置打印sql语句,方便查看
QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;
//选择具体需要的查询方式测试:如queryOrder
queryOrder();
}
}
对数据库的操作后必然想查看数据库的数据是否有变化,但是android查看数据库不是很方便,幸好有如下这个好工具。
推荐工具:stetho
facebook推出的一款可以在Chrome查看app数据库的工具
在项目中添加依赖:
compile 'com.facebook.stetho:stetho:1.3.1'
初始化:
public class MyApplication extends Application {
public void onCreate() {
super.onCreate();
Stetho.initializeWithDefaults(this);
}
}
运行App, 打开Chrome输入chrome://inspect/#devices
chrome会检测到我们的app,点击inspect进入查看页面即可
源码
Github:GreenDaoDemo
总结
如果学过JavaEE开发,用过Hibernate框架的就会非常容易理解greenDAO框架,两者都是基于ORM的思想:ORM-对象关系映射,将一个对象映射为数据库中的一个表。
此外,学习一个框架,我认为不只是要学会怎么使用,最重要的是深入学习这种设计思想以及欣赏底层封装的代码的艺术。
感谢
慕课网:nate的 Android框架-GreenDao
后话
欢迎关注我的微信公众号,不定时推送干货