GreenDao应用解析

来源:互联网 发布:淘宝好的学生围巾店 编辑:程序博客网 时间:2024/04/29 04:26

一、概论

GreenDao是一种对象关系映射(ORM)型数据库,在Android开发中使用较为广泛,比其他关系映射数据库性能更加良好。

这里写图片描述

GreenDao的Github源码地址:https://github.com/greenrobot/greenDAO

GreenDao的官方地址:http://greenrobot.org/greendao/

Tips:国外网站存在被墙的问题,相信这不会影响大家对实现原理的探究。

二、在Android中配置使用GreenDao

配置GreenDao需要两个步骤:

  • 通过Java工程生成实体类和相应的管理类;

  • 将第一步生成的实体类和管理类加到Android项目中,就可以使用了。

注意:这两个步骤,不管使用Eclipse还是Android Studio,都需要加入依赖的jar包。

步骤一用到的jar包,有下边两个:这里写图片描述

步骤二用到的jar包,是GreenDao.jar这里写图片描述

下载全部jar包

下面详细介绍两个步骤:

生成类

Main方法中的代码:

public static void main(String[] args) throws IOException, Exception {        Schema schema = new Schema(1, "de.greenrobot.daoexample");  //生成的实体类的目录        addSeason(schema);//添加实体类        addMatchClass(schema); //添加实体类        new DaoGenerator().generateAll(schema, "D://DaoExamples");//生成的实体类目录要保存的路径,也可以是本地途径,例如“./daoExamples”,就会把生成的内容保存到daoExamples下,目录结构为de.greenrobot.daoexample。    }

addSeason(schema)类中的代码:

private static void addSeason(Schema schema) {         season = schema.addEntity("Season");         season.addLongProperty("seasonId").notNull().primaryKey();         season.addStringProperty("seasonName");         season.addStringProperty("description");    }

addMatchClass(schema)类中的代码:

private static void addMatchClass(Schema schema) {        matchClass = schema.addEntity("MatchClass");        matchClass.addLongProperty("classId").notNull().primaryKey();        matchClass.addStringProperty("className");        matchClass.addStringProperty("description");        Property propertySeasonId = matchClass.addLongProperty("seasonId").getProperty();        matchClass.addToOne(season, propertySeasonId);//将MatchClass的seasonId属性和Season关联    }

在addMatchClass(schema)类中我么用到了关联数据库的基本操作,即:建“外键”。

此处使用的是一对一的关联,还有一对多、多对多的关联,不过多介绍,可参考:
http://blog.csdn.net/wangkeke1860/article/details/51934058

使用类

将生成的类加入到Android项目中,加入greendao.jar包后,就可以使用。

DaoMaster.java:持有数据库对象(SQLiteDatabase)并管理一些DAO类(而不是对象),以静态方式创建和drop数据库表。它的内部类OpenHelper和DevOpenHelper是SQLiteOpenHelper的实现类,用于创建SQLite数据库的模式。

DaoSession.java:管理Dao对象,执行增删改查这些操作。

Season.java:实体类。

SeasonDao.java:数据访问对象,用于实体的持久化和查询。

三、数据库升级

默认的升级方法会删除原来所有的表,然后重建。为了避免数据丢失,我们需要对每个表进行手动操作,但是这样也太麻烦,所以这里给出一个对数据库升级的工具类(来自:http://stackoverflow.com/questions/13373170/greendao-schema-update-and-data-migration)

import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.text.TextUtils;import android.util.Log;import com.crashlytics.android.Crashlytics;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import de.greenrobot.dao.AbstractDao;import de.greenrobot.dao.internal.DaoConfig;import greendao.DaoMaster;/** * Created by pokawa on 18/05/15. */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) {                        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()));        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;    }}

升级是,在update中添加语句:

 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        MyMigrationHelper.getInstance().migrate(db,StudentDao.class,SchoolDao.class);//只有已经存在的表才添加到里边,新增的表不用添加        }

参考博客:http://blog.csdn.net/wangkeke1860/article/details/51838830

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 删除淘宝评价之后卖家不返现怎么办 美团客户给差评怎么办 淘宝卖家评价差怎么办 淘宝卖家发货未揽收怎么办 周不过5我超过了怎么办 淘宝申请退款后卖家不确认怎么办 淘宝直通车b类扣12分怎么办 淘宝店铺被买家投诉怎么办 淘宝店铺遭买家投诉怎么办 淘宝店铺被买家恶意投诉怎么办 苹果手机无法识别指纹怎么办 淘宝店铺虚假交易违规怎么办 斗鱼直播太卡怎么办 神笔添加视频尺码不符合怎么办 闲鱼卖家单号填错了怎么办 户户通没有信号强度怎么办 全民k歌qq登不上怎么办 手机直播没电了怎么办 淘宝退货卖家拒收怎么办 充的会员卡店家关门了怎么办 淘宝手机号码被注册了怎么办 淘宝不支持七天无理由退货怎么办 微信视频横屏怎么办 房子里潮气太重怎么办 淘宝不小心注销了怎么办 淘宝号不小心注销了怎么办 xp网络驱动没了怎么办 淘宝卖家客服态度差怎么办 怀孕吃辣椒喉咙好痛怎么办 淘宝店铺建议不要提交认证怎么办 淘宝买东西商家不退款怎么办 淘宝买东西商家不发货怎么办 在微信上买东西被骗了怎么办 新浪微博自动关注人怎么办 搜淘宝找不到关键词和店铺怎么办 小超市开在一起竞争太大怎么办 淘宝店铺被投诉盗图怎么办 充电宝ic坏了怎么办 淘宝店宝贝权重下降怎么办 淘宝卖家评分低怎么办 淘宝买东西客服不理人怎么办