【Android 进阶】ORM 框架之 greenDAO学习笔记

本文介绍了Android ORM框架greenDAO,阐述了ORM的概念及其优点,对比了主流ORM框架,并详细解析了greenDAO的使用步骤,包括添加依赖、创建数据库模块、配置数据库帮助类以及在实际应用中的操作。同时推荐了用于数据库查看的工具Stetho,帮助开发者更好地理解和运用greenDAO。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

当初学习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

后话

欢迎关注我的微信公众号,不定时推送干货
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值