greendao的使用

 
 

http://www.jianshu.com/p/b268264bf305

http://www.jianshu.com/p/b268264bf305

http://www.jianshu.com/p/b268264bf305

greenDao  

http://www.cnblogs.com/libertycode/p/6256000.html

http://www.jianshu.com/p/b268264bf305

http://blog.csdn.net/u010151514/article/details/72865861

以前开发用到数据库时,基本上都是用android原生的sql语句,写那些语句时稍有不慎,就给你抛出一个exception。现在网上有很多的数据库ORM框架,今天写篇文章来记录一下比较好用的框架:greendao的使用。关于greendao的介绍,网上已经有很多了,可以自行查阅。


准备工作
  • 1、新建一个android工程,在main目录下新建一个文件夹java-gen,如下图:
QQ20160305-0@2x.png
  • 2、在同一个project下,再新建一个java module,并新创建一个类,如下图:
QQ20160305-1@2x.png
  • 3、在android module中的build.gradle文件中加上以下代码:

    0){                fos.write(buffer,0,length);            }            fos.close();            inputStream.close();        } catch (Exception e) {            e.printStackTrace();        }    }    @Override    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {        Log.d("GreenDao","openOrCreateDatabase");        SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory);        return result;    }    @Override    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {        Log.d("GreenDao","openOrCreateDatabase");        SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory);        return result;    }}" data-snippet-id="ext.02002a61fd295b53c17554d8876c3582" data-snippet-saved="false" data-codota-status="done" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important;">        Log.d("GreenDao","buildDatabase");
    InputStream inputStream=mContext.getResources().openRawResource(R.raw.accurmedicine);
    FileOutputStream fos= null;
    try {
    fos = new FileOutputStream(filePath);
    byte[] buffer=new byte[1024];
    int length;
    while ((length=inputStream.read(buffer))>0){
    fos.write(buffer,0,length);
    }
    fos.close();
    inputStream.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
    Log.d("GreenDao","openOrCreateDatabase");
    SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory);
    return result;
    }

    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
    Log.d("GreenDao","openOrCreateDatabase");
    SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory);
    return result;
    }
    }
    复制代码

这里提一下:ContextWrapper是一个Context包装类,需要包含一个真正的Context,详细介绍看:

http://www.jianshu.com/p/94e0f9ab3f1d

  3)在创建DevOpenHelper的时候使用GreenDaoContextWrapper

String DBName="xxx";
DaoMaster.DevOpenHelper helper=new DaoMaster.DevOpenHelper(new GreenDaoContextWrapper(context),DBName,null);

这样就大功告成了!

 

二、数据库版本升级

这个办法是从网上看到的,还不错,就搬过来了。

复制代码
public class MigrationHelper {

    private static MigrationHelper instance;

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

    /**
     * 创建临时表->删除旧表->创建新表->导入数据
     * @param database
     * @param daoClasses
     */
    public void migrate(SQLiteDatabase database, Class<? extends AbstractDao<?,?>>...daoClasses){
        generateTempTables(database,daoClasses);
        DaoMaster.dropAllTables(database,true);
        DaoMaster.createAllTables(database,false);
        restoreData(database,daoClasses);
    }

    /**
     * 临时表生产
     * @param database
     * @param daoClasses
     */
    private void generateTempTables(SQLiteDatabase database,Class<? extends AbstractDao<?,?>>...daoClasses){
        for (int i=0;i<daoClasses.length;i++){
            DaoConfig config=new DaoConfig(database,daoClasses[i]);
            String divider="";
            String tableName=config.tablename;
            String tmpTableName=config.tablename.concat("_TEMP");
            ArrayList<String > properties=new ArrayList<>();
            StringBuilder createTableStringBuilder=new StringBuilder();
            createTableStringBuilder.append("CREATE TABLE ").append(tmpTableName).append(" (");
            List<String> columns = getColumns(database, tableName);
            for (int j=0;j<config.properties.length;j++){
                String columnName=config.properties[j].columnName;
                if (columns.contains(columnName)){
                    properties.add(columnName);
                    String type=null;
                    try {
                        type=getTypeByClass(config.properties[j].type);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);
                    if (config.properties[j].primaryKey){
                        createTableStringBuilder.append("  PRIMARY KEY");
                    }
                    divider=",";
                }
            }
            createTableStringBuilder.append(");");
            Log.d("xxxxx","sql="+createTableStringBuilder.toString());
            database.execSQL(createTableStringBuilder.toString());
            StringBuilder insertTableString=new StringBuilder();
            insertTableString.append("insert into ").append(tmpTableName).append(" (");
            insertTableString.append(TextUtils.join(",",properties));
            insertTableString.append(") select ");
            insertTableString.append(TextUtils.join(",",properties));
            insertTableString.append(" from ").append(tableName).append(";");
            Log.d("xxxxx","sql="+insertTableString.toString());
            database.execSQL(insertTableString.toString());
        }
    }

    /**
     * 数据字段与Java数据类型匹配
     * @param type
     * @return
     * @throws Exception
     */
    private String getTypeByClass(Class<?> type) throws Exception {
        if (type.equals(String.class)){
            return "TEXT";
        }
        if (type.equals(Long.class)||type.equals(Integer.class)){
            return "INTEGER";
        }
        if (type.equals(Boolean.class)){
            return "BOOLEAN";
        }
        String strException="数据表数据类型匹配错误";
        Exception exception=new Exception(strException.concat("- Class").concat(type.toString()));
        throw exception;
    }

    /**
     * 获取当前数据表字段列表
     * @param database
     * @param tableName
     * @return
     */
    private static List<String > getColumns(SQLiteDatabase database,String tableName){
        List<String > columns=new ArrayList<>();
        Cursor cursor=null;
        /**
         * 通过查询数据表
         */
        cursor=database.rawQuery("select * from "+tableName+" limit 1",null);
        try {
            if (cursor!=null){
                String[] columnNames = cursor.getColumnNames();
                for (String name:columnNames){
                    columns.add(name.toUpperCase());
                }
//                columns=new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor!=null){
                cursor.close();
            }
        }
        return columns;
    }

    /**
     * 数据恢复->删除临时表
     * @param database
     * @param daoClasses
     */
    private void restoreData(SQLiteDatabase database,Class<? extends AbstractDao<?,?>>...daoClasses){
        for (int i=0;i<daoClasses.length;i++){
            DaoConfig config=new DaoConfig(database,daoClasses[i]);
            String tableName=config.tablename;
            String tmpTableName=config.tablename.concat("_TEMP");
            ArrayList<String > properties=new ArrayList<>();
            for (int j=0;j<config.properties.length;j++){
                String columnName = config.properties[j].columnName;

                if(getColumns(database, tmpTableName).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(tmpTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();

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

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

}
复制代码

 

然后在需要数据库版本设计的时候修改DaoMaster中的SCHEMA_VERSION 

 

public static final int SCHEMA_VERSION = 1;

这个变量就是用于在创建OpenHelper时指定数据库版本号。

紧接着修改DevOpenHelper的onUpgrade代码:

复制代码
 @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
//            dropAllTables(db, true);
//            onCreate(db);
            MigrationHelper.getInstance()
                    .migrate(db,
                    paramsDao.class,
                    );
        }
复制代码

最后大功告成!

 顺带需要补充一下,查看SQLite数据库版本可以执行以下这句语句:

 

PRAGMA user_version

 

设置SQLite数据库版本的语句:

PRAGMA user_version =<你的版本号>

以上的这两句话其实可以在SQLiteDatabase以及SQLiteOpenHelper的源码中看到:

在android-24的SQLiteOpenHelper源码中可以看到:

复制代码
/**
     * Gets the database version.
     *
     * @return the database version
     */
    public int getVersion() {
        return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
    }

    /**
     * Sets the database version.
     *
     * @param version the new database version
     */
    public void setVersion(int version) {
        execSQL("PRAGMA user_version = " + version);
    }
复制代码

而SQLiteOpenHelper设置和获取数据库版本就是通过调用这两句话来实现的,具体源码可以查看SQLiteOpenHelper的getDatabaseLocked函数,这里不再赘述。



 
 
 
 
 
 
 
 
 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值