GreenDao使用总结

在Android开发过程中,有时候我们需要使用SQLite数据库去本地存储一些临时文件,之前,我们的做法是通过SQLiteOpenHelper实现创建数据库,以及迭代开发中的数据库数据 内容 字段 变更时处理。

优点

1.通常我们在使用GreenDao的时候,我们只需定义数据模型,GreenDao框架将创建数据对象(实体)和DAO(数据访问对象),能够节省部分代码。
2.不向性能妥协,使用了GreenDao,大多数实体可以以每秒几千个实体的速率进行插入,更新和加载。
3.GreenDao支持加密数据库来保护敏感数据。
4.微小的依赖库,GreenDao的关键依赖库大小不超过100kb.
5.如果需要,实体是可以被激活的。而活动实体可以透明的解析关系(我们要做的只是调用getter即可),并且有更新、删除和刷新方法,以便访问持久性功能。
6.GreenDao允许您将协议缓冲区(protobuf)对象直接保存到数据库中。如果您通过protobuf通话到您的服务器,则不需要另一个映射。常规实体的所有持久性操作都可以用于protobuf对象。所以,相信这是GreenDao的独特之处。
7.自动生成代码,我们无需关注实体类以及Dao,因为GreenDao已经帮我们生成了。
8.开源 有兴趣的同学可以查看源码,深入去了解机制。

GreenDao对外提供的核心类简介

1.DaoMaster

DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的Dao类。它具有静态方法来创建表或将他们删除。其内部类OpenHelper和DevOpenHelper是在SQLite数据库中创建模式的SQLiteOpenHelper实现。

2.DaoSession

管理特定模式的所有可用Dao对象,您可以使用其中一个getter方法获取。DaoSession还为实体提供了一些通用的持久性方法,如插入,加载,更新,刷新和删除。最后,DaoSession对象也跟踪一个身份范围。

3.Dao层

数据访问对象(Dao)持续存在并查询实体。对于每个实体,GreenDao生成一个Dao,它比DaoSession有更多的持久化方法,例如:count,loadAll和insertInTx。

4.实体

持久对象,通常实体是使用标准Java属性(如POJO或JavaBean)来表示数据库的对象。

GreenDao使用

1.在工程目录下build.gradle下添加插件

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // 添加插件 更好支持GreenDao

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

然后Sync Now即可。

2.在项目目录下的build.gradle下添加插件依赖

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'

接下来继续添加依赖库

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    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'
    implementation 'org.greenrobot:greendao:3.2.2' // 添加库
}

再接下来就是初始化GreenDao配置,在app下的build.gradle目录下。

greendao {
        schemaVersion 1 //当前数据库版本
    }

然后Sync Now即可。
到这里为止,GreenDao的基本配置就大差不差了。

使用Demo

1.定义一个实体类

  @Id(autoincrement = true)//设置自增长
    private Long id;

    @Index(unique = true)//设置唯一性
    private String perNo;//人员编号

    private String name;//人员姓名

    private String sex;//人员姓名

在我们Make Project后,实体内的变化如下所示:

@Entity
public class PersonInfor {
    @Id(autoincrement = true)//设置自增长
    private Long id;

    @Index(unique = true)//设置唯一性
    private String perNo;//人员编号

    private String name;//人员姓名

    private String sex;//人员姓名

    @Generated(hash = 1311768890)
    public PersonInfor(Long id, String perNo, String name, String sex) {
        this.id = id;
        this.perNo = perNo;
        this.name = name;
        this.sex = sex;
    }

    @Generated(hash = 1362534400)
    public PersonInfor() {
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPerNo() {
        return this.perNo;
    }

    public void setPerNo(String perNo) {
        this.perNo = perNo;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return this.sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

我们可以看到编译后1.自动生成无参,有参构造。2.自动生成getter,setter方法。

2.封装数据库操作类

因为我们对数据库的操作无非就是增删改查四个操作,所以我们将他们简单封装一下。

public class DbController {
    /**
     * Helper
     */
    private DaoMaster.DevOpenHelper mHelper;//获取Helper对象
    /**
     * 数据库
     */
    private SQLiteDatabase db;
    /**
     * DaoMaster
     */
    private DaoMaster mDaoMaster;
    /**
     * DaoSession
     */
    private DaoSession mDaoSession;
    /**
     * 上下文
     */
    private Context context;
    /**
     * dao
     */
    private PersonInforDao personInforDao;

    private static DbController mDbController;

    /**
     * 获取单例
     */
    public static DbController getInstance(Context context){
        if(mDbController == null){
            synchronized (DbController.class){
                if(mDbController == null){
                    mDbController = new DbController(context);
                }
            }
        }
        return mDbController;
    }
    /**
     * 初始化
     * @param context
     */
    public DbController(Context context) {
        this.context = context;
        mHelper = new DaoMaster.DevOpenHelper(context,"person.db", null);
        mDaoMaster =new DaoMaster(getWritableDatabase());
        mDaoSession = mDaoMaster.newSession();
        personInforDao = mDaoSession.getPersonInforDao();
    }
    /**
     * 获取可读数据库
     */
    private SQLiteDatabase getReadableDatabase(){
        if(mHelper == null){
            mHelper = new DaoMaster.DevOpenHelper(context,"person.db",null);
        }
        SQLiteDatabase db =mHelper.getReadableDatabase();
        return db;
    }

    /**
     * 获取可写数据库
     * @return
     */
    private SQLiteDatabase getWritableDatabase(){
        if(mHelper == null){
            mHelper =new DaoMaster.DevOpenHelper(context,"person.db",null);
        }
        SQLiteDatabase db = mHelper.getWritableDatabase();
        return db;
    }

    /**
     * 会自动判定是插入还是替换
     * @param personInfor
     */
    public void insertOrReplace(PersonInfor personInfor){
        personInforDao.insertOrReplace(personInfor);
    }
    /**插入一条记录,表里面要没有与之相同的记录
     *
     * @param personInfor
     */
    public long insert(PersonInfor personInfor){
      return  personInforDao.insert(personInfor);
    }

    /**
     * 更新数据
     * @param personInfor
     */
    public void update(PersonInfor personInfor){
        PersonInfor mOldPersonInfor = personInforDao.queryBuilder().where(PersonInforDao.Properties.Id.eq(personInfor.getId())).build().unique();//拿到之前的记录
        if(mOldPersonInfor !=null){
            mOldPersonInfor.setName("张三");
            personInforDao.update(mOldPersonInfor);
        }
    }
    /**
     * 按条件查询数据
     */
    public List<PersonInfor> searchByWhere(String wherecluse){
        List<PersonInfor>personInfors = (List<PersonInfor>) personInforDao.queryBuilder().where(PersonInforDao.Properties.Name.eq(wherecluse)).build().unique();
        return personInfors;
    }
    /**
     * 查询所有数据
     */
    public List<PersonInfor> searchAll(){
        List<PersonInfor>personInfors=personInforDao.queryBuilder().list();
        return personInfors;
    }
    /**
     * 删除数据
     */
    public void delete(String wherecluse){
        personInforDao.queryBuilder().where(PersonInforDao.Properties.Name.eq(wherecluse)).buildDelete().executeDeleteWithoutDetachingEntities();
    }
}

看看我们的MainActivity

public class MainActivity extends AppCompatActivity {

    private Button Add,Delete,Update,Search;
    private DbController mDbController;
    private PersonInfor personInfor1,personInfor2,personInfor3,personInfor4;
    private long insertTipId;
    private TextView dataArea;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDbController = DbController.getInstance(MainActivity.this);
        initView();
        Envent();
        similateData();
    }

    private void similateData() {
        personInfor1 = new PersonInfor(null,"001","王大宝","男");
        personInfor2 = new PersonInfor(null,"002","李晓丽","女");
        personInfor3 = new PersonInfor(null,"003","王麻麻","男");
        personInfor4 = new PersonInfor(null,"004","王大锤","女");
    }

    private void Envent() {

        Add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Add
               mDbController.insertOrReplace(personInfor1);

               mDbController.insertOrReplace(personInfor2);

               mDbController.insertOrReplace(personInfor3);

               mDbController.insertOrReplace(personInfor4);

                showDataList();
            }
        });
        Delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Delete
                mDbController.delete("王麻麻");

                showDataList();
            }
        });

        Update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Update
                mDbController.update(personInfor1);

                showDataList();
            }
        });

        Search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Search
                showDataList();
            }
        });
    }

    private void showDataList() {
        StringBuilder sb = new StringBuilder();
       List<PersonInfor>personInfors = mDbController.searchAll();
       for(PersonInfor personInfor:personInfors){
          // dataArea.setText("id:"+p);
           sb.append("id:").append(personInfor.getId())
             .append("perNo:").append(personInfor.getPerNo())
             .append("name:").append(personInfor.getName())
             .append("sex:").append(personInfor.getSex())
             .append("\n");
       }
       dataArea.setText(sb.toString());
    }

    private void initView() {

        Add = findViewById(R.id.Add);

        Delete = findViewById(R.id.Delete);

        Update = findViewById(R.id.Update);

        Search = findViewById(R.id.Search);

        dataArea= findViewById(R.id.tips);

    }
}

代码说明:

细心的同学可以看到我们已经不用再使用创建数据库的sql语言了,因为GreenDao框架已经帮我们做了,通过之前的方式创建数据库过程当中还有可能出现一些莫名其妙的错误。我们只要定义出实体就可以了,从代码中可以看到我们创建了一个person.db的数据库。其实与我们平常操作就是这个Dao,这个框架会根据不同的数据实体对应生成不同的Dao,通过这个Dao我们就可以调用相应的接口去完成增删改查。

Demo简单展示

插入数据

add.PNG

更新数据

update.PNG

删除数据

delete.PNG

删除了王麻麻。

查询数据

search.PNG

GreenDao的介绍和使用就到此为止了,这个框架很方便,值得一用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容