在AndoridStudio中引来GreenDAO

在AndoridStudio中引入GreenDAO

在AndoridStudio中引入GreenDAO

GreenDAO整个运行的逻辑是通过配置其提供的JavaSE代码,自动在一个文件夹下生成需要Bean、DAO、DaoMaster、DaoSession;然后在Android代码中通过自动生成的DaoSession来操作数据库,具体方法如下:

1.配置工程

在./src/main目录下创建一个与java同层级的java-gen文件夹.

打开build.gradle,引入sourceSets

sourceSets {
    main {
        java.srcDirs = ['src/main/java', 'src/main/java-gen']
    }
}

这句话的意思是把java-gen文件夹下的java文件也归入srcDir中,主要是因为GreenDAO的逻辑是通过其提供的一套Java SE代码配置后自动在java-gen文件夹下生成对应的*DAO.java、DaoMaster.java、DaoSession.java文件。在Android代码中通过调用这几个类来操作数据库。

引入dependencies

dependencies {
    compile 'de.greenrobot:greendao:1.3.7'
}

2.到GitHub上下载示例工程

下载地址:GitHub link

下载这个Demo的原因是要引入这个示例工程来实现自动创建需要的DaoMaster、DaoSession等等,GreenDao上手麻烦的原因就在于一开始以为只要gradle随便引入一个库之后就可以使用了,没想到最关键的是需要引入这个JavaSE工程来实现关键代码的自动创建。

这个Demo工程也不用怎么仔细的去看,下载解压之后Copy里面的MyDaoGenerator文件夹Code link

把这个文件夹拷贝到你的工程跟目录中,就是与app文件夹同层级的目录里。

将MyDaoGenerator include到工程中:

打开settings.gradle,修改内容

 include ':app', ':MyDaoGenerator'

打开MyDaoGenerator的build.gradle文件,配置outputDir,路径就是存放自动生成DaoMaster和其他代码的地方。这里给个示例:

def outputDir = "../app/src/main/java-gen"

注意’def‘,GitHub上的这个Demo掉了’def‘导致我一直编译错误。

3.如果一切顺利,这个时候就完整的配置好了整个GreenDAO环境

接下来需要创建DaoMaster.java等

打开MyDaoGenerator工程中的MyDaoGenerator.java

配置里面的代码,如示例:

public static void main(String args[]) throws Exception {
     Schema schema = new Schema( 1, "com.xxx.bean");
     // 1: 数据库版本号
    // com.xxx.bean:自动生成的Bean对象会放到/java-gen/com/xxx/bean中

    schema.setDefaultJavaPackageDao("com.xxx.dao");
    // DaoMaster.java、DaoSession.java、BeanDao.java会放到/java-gen/com/xxx/dao中

    // 上面这两个文件夹路径都可以自定义,也可以不设置

    initUserBean(schema); // 初始化Bean了

    new DaoGenerator().generateAll(schema, args[0]);// 自动创建
}

private static void initUserBean(Schema schema) {
    Entity userBean = schema.addEntity("UserBean");// 表名
    userBean.setTableName("user"); // 可以对表重命名
    userBean.addStringProperty("id").primaryKey().index();// 主键,索引
    userBean.addStringProperty("phone");
    userBean.addStringProperty("profile_picture");
    userBean.addStringProperty("client_id");
    userBean.addStringProperty("name");
    userBean.addStringProperty("location");
    userBean.addStringProperty("gender");
}

这里只需要关注一个问题,就是如果数据库要升级,这里是修改代码后全量重新创建。

假设要给user表增加一个”age”属性,并且增加school表的做法是:

  1. 把数据库版本号修改为2

  2. 在initUserBean方法中加入userBean.addStringProperty("age");

  3. 新建initSchoolBean方法

当明白这个文件的写法之后就要运行这个文件了,进到AndroidStudio的Gradel面板中执行run任务。

执行完成之后就会在java-gen文件夹下生成需要的代码了。

4.在Android工程中初始化数据库

初始化代码示例:

 THDevOpenHelper helper = new THDevOpenHelper(context, "my-db", null);
 SQLiteDatabase db = helper.getWritableDatabase();
 DaoMaster daoMaster = new DaoMaster(db);
 daoSession = daoMaster.newSession();  

这句话执行之后就会在app的文件夹下生成my-db.db了

如果看到这里你还没有产生疑问,那说明你没有认真看这篇文章,THDevOpenHelper是什么玩意?

这是我封装的DaoMaster.OpenHelper,之所以要做一层封装是因为默认的DaoMaster.OpenHelper在碰到数据库升级的时候会删除旧的表来创建新的表,这样就会导致旧表的数据全部丢失了,所以一定要封装DaoMaster.OpenHelper来实现数据库升级

示例如下:

public class THDevOpenHelper extends DaoMaster.OpenHelper {

    public THDevOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
        super(context, name, factory);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        switch (oldVersion) {
            case 1:
                //创建新表,注意createTable()是静态方法
                // SchoolDao.createTable(db, true);     

                // 加入新字段
                // db.execSQL("ALTER TABLE 'moments' ADD 'audio_path' TEXT;");  

                // TODO
                break;
        }
    }
}

5.得到DaoSession了,数据库能升级了,这还没有完!

为了更好的使用Dao,你应该创建一个DaoHelper。

示例如下:

public class UserBeanDaoHelper implements THDaoHelperInterface {
    private static UserBeanDaoHelper instance;
    private UserBeanDao userBeanDao;

    private UserBeanDaoHelper() {
        try {
            userBeanDao = THDatabaseLoader.getDaoSession().getUserBeanDao();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static UserBeanDaoHelper getInstance() {
        if(instance == null) {
            instance = new UserBeanDaoHelper();
        }

        return instance;
    }

    @Override
    public <T> void addData(T bean) {
        if(userBeanDao != null && bean != null) {
            userBeanDao.insertOrReplace((UserBean) bean);
        }
    }

    @Override
    public void deleteData(String id) {
        if(userBeanDao != null && !TextUtils.isEmpty(id)) {
            userBeanDao.deleteByKey(id);
        }
    }

    @Override
    public UserBean getDataById(String id) {
        if(userBeanDao != null && !TextUtils.isEmpty(id)) {
            return userBeanDao.load(id);
        }
        return null;
    }

    @Override
    public List getAllData() {
        if(userBeanDao != null) {
            return userBeanDao.loadAll();
        }
        return null;
    }

    @Override
    public boolean hasKey(String id) {
        if(userBeanDao == null || TextUtils.isEmpty(id)) {
            return false;
        }

        QueryBuilder<UserBean> qb = userBeanDao.queryBuilder();
        qb.where(UserBeanDao.Properties.Id.eq(id));
        long count = qb.buildCount().count();
        return count > 0 ? true : false;
    }

    @Override
    public long getTotalCount() {
        if(userBeanDao == null) {
            return 0;
        }

        QueryBuilder<UserBean> qb = userBeanDao.queryBuilder();
        return qb.buildCount().count();
    }

    @Override
    public void deleteAll() {
        if(userBeanDao != null) {
            userBeanDao.deleteAll();
        }
    }

    public void testQueryBy() {
        List joes = userBeanDao.queryBuilder()
                .where(UserBeanDao.Properties.Phone.eq("Joe"))
                .orderAsc(UserBeanDao.Properties.Phone)
                .list();

        QueryBuilder<UserBean> qb = userBeanDao.queryBuilder();
        qb.where(qb.or(UserBeanDao.Properties.Phone.gt(10698.85),
                qb.and(UserBeanDao.Properties.Phone.eq("id"),
                        UserBeanDao.Properties.Phone.eq("xx"))));

        qb.orderAsc(UserBeanDao.Properties.Id);// 排序依据
        qb.list();
    }
}

最后友情附上THDaoHelperInterface.java

public interface THDaoHelperInterface {
    public <T> void addData(T t);
    public void deleteData(String id);
    public <T> T getDataById(String id);
    public List getAllData();
    public boolean hasKey(String id);
    public long getTotalCount();
    public void deleteAll();
}

写在最后

本文是用Markdown写的,所以很多该附图的地方并没有附图。如果遇到看不懂的地方。

请参考Using GreenDao with Android Studio IDE