GreenDao2.x的基本使用和集成

项目结构:

新建Android工程GreenDaoTest
这里写图片描述

新建Java lib工程mylib
这里写图片描述
这里写图片描述
next, 取名mylib(自己随便取)
这里写图片描述
finish, 在Android工程中创建目录Java-gen, 与Java平级, 看第一张图

配置

第一步:在app的build.gradle中添加配置如下:
这里写图片描述

第二步:在mylib的build.gradle中添加配置如下:
这里写图片描述

编码

第一步: 在mylib中的类MyClass.java中这样写:

public class MyClass {

    public static void main(String[] args) throws Exception {
        int version=1;
        String defaultPackage="com.ygl.bean";
//        String defaultPackage="com.ygl.greendaotest";
        //创建模式对象,指定版本号和自动生成的bean对象的包名
        Schema schema=new Schema(version,defaultPackage);
        //指定自动生成的dao对象的包名,不指定则都DAO类生成在"test.greenDAO.bean"包中
        schema.setDefaultJavaPackageDao("com.ygl.dao");

        // 模式(Schema)同时也拥有两个默认的 flags,分别用来标示 entity 是否是 activie 以及是否使用 keep sections。
        // schema2.enableActiveEntitiesByDefault();
        // schema2.enableKeepSectionsByDefault();

        addEntity(schema);

        String outDir="C:/Users/ygl_panpan/Downloads/GreenDaoTest/app/src/main/java-gen";
        //调用DaoGenerator().generateAll方法自动生成代码到之前创建的java-gen目录下
        new DaoGenerator().generateAll(schema,outDir);
    }

    private static Entity addEntity(Schema schema) {
        //添加一个实体,则会自动生成实体Entity类
        Entity entity = schema.addEntity("student");
        //指定表名,如不指定,表名则为 Entity(即实体类名)
        entity.setTableName("students");
        //给实体类中添加属性(即给test表中添加字段)
        entity.addIdProperty().autoincrement();//添加Id,自增长
        entity.addStringProperty("name").notNull();//添加String类型的name,不能为空
        entity.addIntProperty("age");//添加Int类型的age
        entity.addDoubleProperty("score");//添加Double的score

        return entity;
    }

运行MyClass
这里写图片描述

在Android工程的Java-gen目录中会有如下红框中的代码生成
这里写图片描述

使用

官方推荐将获取 DaoMaster 对象的方法放到 Application 层,这样将避免多次创建生成 Session 对象, 新建MyApplication :

public class MyApplication extends Application {
    private static MyApplication instance = new MyApplication();

    private static DaoSession daoSession;
    private static SQLiteDatabase db;
    private static DaoMaster.DevOpenHelper helper;
    private static DaoMaster daoMaster;

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

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

    private void setupDatabase() {
        //创建数据库
        // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
        // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
        helper = new DaoMaster.DevOpenHelper(this, "test", null);
        //得到数据库连接对象
        db = helper.getWritableDatabase();
        //得到数据库管理者
        daoMaster =new DaoMaster(db);
        //得到daoSession,可以执行增删改查操作
        daoSession = daoMaster.newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }

}

Activity中这样使用:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "plq";

    private com.ygl.dao.studentDao studentDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        studentDao =MyApplication.getInstance().getDaoSession().getStudentDao();
    }

    public void insert(View v) {
        List<student> list = new ArrayList<>();

        list.add(new student(1l, "张一", 21, 91.0));
        list.add(new student(2l, "张二", 22, 92.0));

        studentDao.insertOrReplaceInTx(list);
        Log.i(TAG, "insert scuccess");
    }

    public void query(View v) {
        List<student> students = studentDao.loadAll();
        Log.i(TAG, students.size()+"");
        for (student stu : students){
            Log.i(TAG, stu.getName());
        }
        Log.i(TAG, "query scuccess");
    }

    public void update(View v) {
        studentDao.update(new student(1l, "张一yi", 21, 91.0));
        Log.i(TAG, "update scuccess");
    }

    public void delete(View v) {
        studentDao.deleteByKey(2l);
        Log.i(TAG, "delete scuccess");
    }

}

数据库升级:

当我们在MyClass中修改了entity(增减变量), 那么我们应该修改version的值+1, 然后mark project, 之后我们在自动生成的DaoMaster类中添加一行代码, 如下:
这里写图片描述

需要注意的是每次mark project后, DaoMaster中的代码都会还原, 所以每次mark project后都需要去添加这行代码

MigrationHelper类:

/**
 * author:国外大牛 on 2016/12/14 15:25
 * email:
 *
 * description:
 *      GreenDAO数据库版本升级之旧数据的保存
 * 使用: 在DaoMaster类中, 有个继承OpenHelper的内部类DevOpenHelper, 在DevOpenHelper的onUpgrade方法中调用以下一行代码既可(记得注释原先onUpgrade方法中默认代码):
 *      MigrationHelper.getInstance().migrate(db, xxxDao.class, yyyDao.class, ......);
 */
public class MigrationHelper {

    private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
    private static MigrationHelper instance;

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

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

    private void generateTempTables(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        for(int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

            String divider = "";
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            ArrayList<String> properties = new ArrayList<>();

            StringBuilder createTableStringBuilder = new StringBuilder();

            createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");

            for(int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if(getColumns(db, tableName).contains(columnName)) {
                    properties.add(columnName);

                    String type = null;

                    try {
                        type = getTypeByClass(daoConfig.properties[j].type);
                    } catch (Exception exception) {
                        exception.printStackTrace();
//                        Crashlytics.logException(exception);
                    }

                    createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

                    if(daoConfig.properties[j].primaryKey) {
                        createTableStringBuilder.append(" PRIMARY KEY");
                    }

                    divider = ",";
                }
            }
            createTableStringBuilder.append(");");

            db.execSQL(createTableStringBuilder.toString());

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tableName).append(";");

            db.execSQL(insertTableStringBuilder.toString());
        }
    }

    private void restoreData(SQLiteDatabase 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");
            ArrayList<String> properties = new ArrayList();

            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if(getColumns(db, tempTableName).contains(columnName)) {
                    properties.add(columnName);
                }
            }

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();

            dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);

            db.execSQL(insertTableStringBuilder.toString());
            db.execSQL(dropTableStringBuilder.toString());
        }
    }

    private String getTypeByClass(Class<?> type) throws Exception {
        if(type.equals(String.class)) {
            return "TEXT";
        }
        if(type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
            return "INTEGER";
        }
        if(type.equals(Boolean.class)) {
            return "BOOLEAN";
        }

        Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
        exception.printStackTrace();
//        Crashlytics.logException(exception);
        throw exception;
    }

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

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值