greendao 测试可以

Posted 君子求诸己

tags:

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

参考地址:

https://www.jianshu.com/p/853401a7d02b

https://www.cnblogs.com/zhangqie/p/7250459.html

第一步 先在 目的Project 的 buil.gradle 里

在dependencies 里添加
classpath \'org.greenrobot:greendao-gradle-plugin:3.2.1\'

第二步 在自己想要用的
GreenDao Module 里的 dependencies 里添加

compile \'org.greenrobot:greendao:3.+\'

 

android 里 添加

greendao {
    schemaVersion 1//指定数据库版本号,更新操作会用到;
    daoPackage \'com.test.greendao.gen\'//自动生成的dao的包名,包名默认是entity所在的包;
    targetGenDir \'src/main/java\'//生成数据库文件的目录
}

 

 

 

schemaVersion: 数据库schema版本,也可以理解为数据库版本号
daoPackage:设置DaoMaster、DaoSession、Dao包名
targetGenDir:设置DaoMaster、DaoSession、Dao目录
targetGenDirTest:设置生成单元测试目录
generateTests:设置自动生成单元测试用例

头部 添加

apply plugin: \'org.greenrobot.greendao\'


第三步 创建新的实体类

/** * Created by AFa on 2016/8/23. *

/

@Entity

public class User {  

 @Id(autoincrement = true)   

private Long id;   

private String name;   

private String age;   

private String sex;   

private String salary;

}

public class GreenApplication extends Application {

 private DaoMaster.DevOpenHelper mHelper;
 //private Helper mHelper;

 private SQLiteDatabase db;

 private DaoMaster mDaoMaster;

 private DaoSession mDaoSession;

 public static GreenApplication instances;

 @Override    public void onCreate() {

     super.onCreate();

     instances = this;

     setDatabase();

 }

 public static GreenApplication getInstances(){

     return instances;

 }

 

/**

 * 设置greenDao

 */

private void setDatabase() {

    // 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。

    // 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。

    // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。

    // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
   //mHelper = new Helper(new GreenDaoUtils(this));

  

    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;

  }

}

 

 

MainActivity中

UserDao userDao= GreenApplication.getInstances().getDaoSession().getUserDao();

 

结果插入数据时,报如下错误:

android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: PERSON._id (code 1555)

说是主键必须是唯一的,主键不是自增的吗?怎么会不唯一呢?原来原因是主键自增类型必须是Long(注意是大写的L),而不是小子的long类型。修改后再运行,ok了。

版本升更新

比如需要在实体类加一个字段 或者 改变字段属性等 就需要版本更新来保存以前的数据了;

1:需要一个MigrationHelper.java一位大神写的 直接拿来用即可

package fateat.xinkong.com.greendaotest.util.dao;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.StandardDatabase;
import org.greenrobot.greendao.internal.DaoConfig;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Createdby PedroOkawa and modified by MBH on 16/08/16.
 */
public final class MigrationHelper {

    private static MigrationHelper instance;

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

    public static void migrate(SQLiteDatabase sqliteDatabase, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        StandardDatabase db = new StandardDatabase(sqliteDatabase);
        generateNewTablesIfNotExists(db, daoClasses);
        generateTempTables(db, daoClasses);
        dropAllTables(db, true, daoClasses);
        createAllTables(db, false, daoClasses);
        restoreData(db, daoClasses);
    }

    public static void migrate(StandardDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        generateNewTablesIfNotExists(db, daoClasses);
        generateTempTables(db, daoClasses);
        dropAllTables(db, true, daoClasses);
        createAllTables(db, false, daoClasses);
        restoreData(db, daoClasses);
    }

    private static void generateNewTablesIfNotExists(StandardDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        reflectMethod(db, "createTable", true, daoClasses);
    }

    private static void generateTempTables(StandardDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        for (int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            StringBuilder insertTableStringBuilder = new StringBuilder();
            insertTableStringBuilder.append("CREATE TEMP TABLE ").append(tempTableName);
            insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";");
            db.execSQL(insertTableStringBuilder.toString());
        }
    }

    private static void dropAllTables(StandardDatabase db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
        reflectMethod(db, "dropTable", ifExists, daoClasses);
    }

    private static void createAllTables(StandardDatabase db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
        reflectMethod(db, "createTable", ifNotExists, daoClasses);
    }

    /**
     * dao class already define the sql exec method, so just invoke it
     */
   
private static void reflectMethod(StandardDatabase db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
        if (daoClasses.length < 1) {
            return;
        }
        try {
            for (Class cls : daoClasses) {
                Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class);
                method.invoke(null, db, isExists);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private static void restoreData(StandardDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        for (int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            // get all columns from tempTable, take careful to use the columns list
            List<String> columns = getColumns(db, tempTableName);
            ArrayList<String> properties = new ArrayList<>(columns.size());
            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;
                if (columns.contains(columnName)) {
                    properties.add(columnName);
                }
            }
            if (properties.size() > 0) {
                final String columnSQL = TextUtils.join(",", properties);

                StringBuilder insertTableStringBuilder = new StringBuilder();
                insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
                insertTableStringBuilder.append(columnSQL);
                insertTableStringBuilder.append(") SELECT ");
                insertTableStringBuilder.append(columnSQL);
                insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");
                db.execSQL(insertTableStringBuilder.toString());
            }
            StringBuilder dropTableStringBuilder = new StringBuilder();
            dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
            db.execSQL(dropTableStringBuilder.toString());
        }
    }

    private static List<String> getColumns(StandardDatabase db, String tableName) {
        List<String> columns = null;
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null);
            if (null != cursor && cursor.getColumnCount() > 0) {
                columns = Arrays.asList(cursor.getColumnNames());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
            if (null == columns)
                columns = new ArrayList<>();
        }
        return columns;
    }

}

2:接下来就是我们 GreenApplication 类里的 Helper类了

 

public class Helper extends DaoMaster.OpenHelper{

 

    private static DaoMaster daoMaster;

    private static DaoSession daoSession;

 

    public static final String DBNAME = "greendao.db";

 

    public Helper(Context context){

        super(context,DBNAME,null);

    }

 

 

    @Override

    public void onUpgrade(Database db, int oldVersion, int newVersion) {

        super.onUpgrade(db, oldVersion, newVersion);

        Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);

        if (oldVersion < newVersion) {

            Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);

            MigrationHelper.getInstance().migrate(db, UserDao.class);

            //更改过的实体类(新增的不用加)   更新UserDao文件 可以添加多个  XXDao.class 文件

//             MigrationHelper.getInstance().migrate(db, UserDao.class,XXDao.class);

        }

    }

 

    /**

     * 取得DaoMaster

     *

     * @param context

     * @return

     */

    public static DaoMaster getDaoMaster(Context context) {

        if (daoMaster == null) {

            DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(context,

                    DBNAME, null);

            daoMaster = new DaoMaster(helper.getWritableDatabase());

        }

        return daoMaster;

    }

 

    /**

     * 取得DaoSession

     *

     * @param context

     * @return

     */

    public static DaoSession getDaoSession(Context context) {

        if (daoSession == null) {

            if (daoMaster == null) {

                daoMaster = getDaoMaster(context);

            }

            daoSession = daoMaster.newSession();

        }

        return daoSession;

    }

}

 

完成相关操作之后;还要改数据库版本

greendao {

    schemaVersion 2//改版本号为2

    daoPackage \'com.zhangqie.greendao.gen\';

    targetGenDir \'src/main/java\'

}

编译运行,可以去实体类和UserDao查看  增加的字段相关信息自动生成完成;



 

以上是关于greendao 测试可以的主要内容,如果未能解决你的问题,请参考以下文章

GreenDao使用

GreenDao使用

GreenDao使用

如何在android应用中使用greendao orm框架

安卓GreenDao(基础)

GreenDao源码分析