GreenDao使用踩过的坑

Posted 物来顺心,事去宁心!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GreenDao使用踩过的坑相关的知识,希望对你有一定的参考价值。

本来想用litePal,看了郭大婶的说明,真的是好用!

后来发现网上说比较流行的还是 GREENDAO,且效率不错!

不用管那么多了,直接用吧.

----------------------------------------------------------------------------------

看了一天的 GREENDAO,还是没有敢动手,那就动起来!

----------------------------------------------------------------------------------

1.先导入包,直接按官网来

-------------------------

// In your root build.gradle file:  项目的 build.gradle
buildscript {
    repositories {
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath \'com.android.tools.build:gradle:2.3.0\'
        classpath \'org.greenrobot:greendao-gradle-plugin:3.2.2\' // add plugin
    }
}
 
// In your app projects build.gradle file: 应用程序的 build.gradle
apply plugin: \'com.android.application\'
apply plugin: \'org.greenrobot.greendao\' // apply plugin
 
dependencies {
    compile \'org.greenrobot:greendao:3.2.2\' // add library
}

导入结束,高高兴兴的准备在application 中加入 daoMaster daoSession

private DaoMaster.DevOpenHelper mHelper;
 private SQLiteDatabase db;
 private DaoMaster mDaoMaster;
 private DaoSession mDaoSession;

这里还有个小插曲:不要笑我笨!

我根本找不到   application 类在哪???

后来,一个大兄弟告诉我,那需要你自己写个 应用类,,继承application ,大概长这样:

import android.app.Application;

/**
 * Created by Think on 2017/12/21.
 */

public class BaseApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
    }
}

建立完app后还要在 AndroidManifest.xml 中加入  name=\'BaseApp\'

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ssqhan.mydbtest">

    <application
        android:name="BaseApp"
        .............................
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

好吧,快写上内容:(官网是这样要求的)

// do this once, for example in your Application class           这不,,要求写到应用程序中
helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
db = helper.getWritableDatabase();
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
// do this in your activities/fragments to get hold of a DAO
noteDao = daoSession.getNoteDao();
//那我们就这样写了
//----------------------------------------------
import
android.app.Application; /** * Created by Think on 2017/12/21. */ public class BaseApp extends Application { private DaoMaster.DevOpenHelper mHelper; private SQLiteDatabase db; private DaoMaster mDaoMaster; private DaoSession mDaoSession; // do this once, for example in your Application class mHelper= new DaoMaster.DevOpenHelper(this, "notes-db", null); db = helper.getWritableDatabase(); mDaoMaster= new DaoMaster(db); mDaoSession=mDaoMaster.newSession(); // do this in your activities/fragments to get hold of a DAO noteDao = daoSession.getNoteDao(); @Override public void onCreate() { super.onCreate(); } }

可是会发现, DAOMaster  是红色的 且出现:  cannot resolve symbol \'daoMaster\'

why???????????

----------------------------------------------------------------------------------------------------

2.正确姿势就该这样:

  (1)先建一个实体这样:(直接COPY 官网上的)

@Entity
public class User {
    @Id
    private Long id;
 
    private String name;
 
    @Transient
    private int tempUsageCount; // not persisted
 
   // getters and setters for id and user ...
}

什么,又是一片红:    一通  \'alt+enter\'  解决问题

(2) 这样就自动生成三个文件

     我当时现现了另一个神级的错误:  三个文件最上面出现 package;   并且标红

   解决方法:直接删除  package

     (后来发现,删除是不对的,没有能正确的生成包名是因为  User  实体的位置放置不对,所以生成的  DaoMaster,DaoSession,UserDao 的包名都不正确)

      又发现:userDao里的 User又标红   \'alt+enter\' 直接 import  User就可以了!

      现在才刚刚开始!

-------------------------------------------------------------------------------------------------------

3.写入全局应用程序中

   终于不再看到 标红的 字样了..真的有点崩溃了!

   再来看看:

public class BaseApp extends Application {

    private DaoMaster.DevOpenHelper mHelper;
    private SQLiteDatabase db;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
       
 
    @Override
    public void onCreate() {
        super.onCreate();

        mHelper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
        db = mHelper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSession = mDaoMaster.newSession();
        // do this in your activities/fragments to get hold of a DAO   既然要在 activities 里,那这里就不用了
        //noteDao = mDaoSession.getNoteDao();
        
    }
}

好了.没有标红,我的个小心脏啊..真的有点受不了了!

好吧,还是让代码看来起更优雅一点(借用大侠的代码,地址:http://www.jianshu.com/p/4986100eff90):

public class BaseApp extends Application {

    private DaoMaster.DevOpenHelper mHelper;
    private SQLiteDatabase db;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    public static  BaseApp instances;
 
    @Override
    public void onCreate() {
        super.onCreate();
        instances = this;
        setDatabase();        
    }

    public static BaseApp getInstances(){
         return instances;
    }

/**
 * 设置greenDao
 */
    private void setDatabase() {
        // 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
        // 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
        // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
        // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
        mHelper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
        db = mHelper.getWritableDatabase();
        // 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。 
        mDaoMaster = new DaoMaster(db); 
        mDaoSession = mDaoMaster.newSession();
     }
    public DaoSession getDaoSession() {
         return mDaoSession;
    }
    public SQLiteDatabase getDb() {
         return db;
    }
}

 

上面说了,那句话要在 activity 里,那就打开主activity.

-------------------------------------------------------------------------------------

4. 主activity中加入实体操作

    该怎么写呢?  以下这样,出错了,看标红:

    

   那又该如何做????   脑袋中直冒金星!!!

   *****************************************************************************

  经过多方测试,发现我的User 实体放的位置不对!应该放到 JAVA下面的 COM.example.***下面,再 build project这样就不会有问题了。

  正确的姿势应该这样:

package com.example.ssqhan.mydbtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    MenuDao mMenuDao;
   TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        creatTable();
        tv=findViewById(R.id.tv);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                QueryBuilder<Menu> queryMenu = mUserDao.queryBuilder();
                queryMenu.where(MenuDao.Properties.Id.eq(1));
                List<Menu> list = queryMenu.list();
                tv.setText((list.get(0)).getName());
            }
        });
    }
    public void creatTable(){
       mMenuDao = BaseApp.getInstances().getDaoSession().getMenuDao();
       Menu menu = new Menu((long)1,"MenuItem");
       mMenuDao.insert(menu);
    }
}

上面的代码,,点击运行,答案出来了。。。tv的text 变成了  MenuItem(我把User实体换成了Menu)  别的都一样!

 

以上是关于GreenDao使用踩过的坑的主要内容,如果未能解决你的问题,请参考以下文章

编程中踩过的坑

转:Flutter开发中踩过的坑

JS代码中踩过的坑

与webview打交道踩过的坑

golang中创建logger时候踩过的坑

Fragment全解析系列:那些年踩过的坑