美文网首页
greenDao使用

greenDao使用

作者: Erzyb | 来源:发表于2017-07-03 15:06 被阅读0次

    网络资源整理自用,非原创。

    1. 配置
    //project配置
    buildscript {
        repositories {
            jcenter()
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.3.2'
            classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0'
        }
    }
    
    //module配置
    apply plugin: 'com.android.application'
    apply plugin: 'org.greenrobot.greendao'
    android {
        greendao {
            schemaVersion 1    //数据库版本
            targetGenDir '*******'    //生成DaoMaster类文件夹
            daoPackage   '**********'  //生成DaoMaster类包名
        }
    dependencies {
        compile 'org.greenrobot:greendao:3.1.0'
    }
    
    1. 表创建
    @Entity(nameInDb = "Book")
    public class Book {
        @Id(autoincrement = true)
        @Property(nameInDb = "no")
        //@Unique
        private String no;
        @Property(nameInDb = "title")
        //@Transient
        private String title;
        @Property(nameInDb = "author")
        //@NotNull
        private String author;}```
    @Entity 用于标识这是一个需要Greendao帮我们生成代码的bean
    @Id 标明主键,括号里可以指定是否自增
    @Property 用于设置属性在[数据库](http://lib.csdn.net/base/mysql)中的列名(默认不写就是保持一致)
    @NotNull 非空
    @Transient 标识这个字段是自定义的不会创建到数据库表里
    @Unique 添加唯一约束
      make projeck后会自动添加seter,geter以及构造函数。并且会新加三个类:
      -  BookDao
      -  DaoMaster
      -  DaoSession
    2. 封装
    

    //网上找的封装
    public class DBManager {
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    private static DBManager mInstance; //单例

    private DBManager(){
        if (mInstance == null) {
            DaoMaster.DevOpenHelper devOpenHelper = new MergeDevOpenHelper(new GreenDaoContext(), "******.db");
            mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
            mDaoSession = mDaoMaster.newSession();
        }
    }
    
    public static DBManager getInstance() {
        if (mInstance == null) {
            synchronized (DBManager.class) {//保证异步处理安全操作
                if (mInstance == null) {
                    mInstance = new DBManager();
                }
            }
        }
        return mInstance;
    }
    
    public DaoMaster getMaster() {
        return mDaoMaster;
    }
    public DaoSession getSession() {
        return mDaoSession;
    }
    public DaoSession getNewSession() {
        mDaoSession = mDaoMaster.newSession();
        return mDaoSession;
    }
    

    }

    1. 使用
    

    //在application的onCreate中调用getInstance
    DBManager.getInstance();
    //可以再封装,调用api实现增删改查
    DBManager.getInstance().getSession().getBookDao().queryBuilder().list();//查询book表中所有数据

    5. 升级和迁移
      普通升级直接修改数据库版本号就可以了,但是默认实现会删除所有数据,重新创建数据库表格。所以需要自己实现升级。
    

    public class MergeDevOpenHelper extends DaoMaster.OpenHelper{
    public MergeDevOpenHelper(Context context, String name) {
    super(context, name);
    }

    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        MigrationHelper.getInstance().migrate(db, BookDao.class);
    }
    

    }

    
    

    //类是从github中copy出来的,非原创。。。。。
    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(Database db, Class... daoClasses) {
        generateTempTables(db, daoClasses);
        DaoMaster.dropAllTables(db, true);
        DaoMaster.createAllTables(db, false);
        restoreData(db, daoClasses);
    }
    
    private void generateTempTables(Database db, Class... 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 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) {
                    }
    
                    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(Database db, Class... 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 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()));
        throw exception;
    }
    
    private static List getColumns(Database db, String tableName) {
        List 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;
    }
    

    }

    上边处理了数据库升级,数据迁移的问题。
    在我自己的项目中还有一个问题是需要处理外部数据库,所以还需指定一个数据库路径。
    

    public class GreenDaoContext extends ContextWrapper {
    private String currentUserId = "greendao";//一般用来针对一个用户一个数据库,以免数据混乱问题
    private Context mContext;

    public GreenDaoContext() {
        super(BaseApp.gContext);
        this.mContext = BaseApp.gContext;
        //        this.currentUserId = "greendao";//初始化
    }
    
    /**
     * 获得数据库路径,如果不存在,则创建对象
     *
     * @param dbName
     */
    @Override
    public File getDatabasePath(String dbName) {
        String dbDir = "";//指定数据库路径
        if (TextUtils.isEmpty(dbDir)){
            Log.e("SD卡管理:", "SD卡不存在,请加载SD卡");
            return null;
        }
        File baseFile = new File(dbDir);
        // 目录不存在则自动创建目录
        if (!baseFile.exists()){
            baseFile.mkdirs();
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append(baseFile.getPath());
        buffer.append(File.separator);
    

    // buffer.append(currentUserId);
    dbDir = buffer.toString();// 数据库所在目录
    // buffer.append(File.separator);
    // buffer.append(dbName+"_"+currentUserId);//也可以采用此种方式,将用户id与表名联系到一块命名
    buffer.append(dbName);
    String dbPath = buffer.toString();// 数据库路径
    LogUtil.e(LogUtil.getLogTag()+dbPath);
    // 判断目录是否存在,不存在则创建该目录
    File dirFile = new File(dbDir);
    if (!dirFile.exists()){
    dirFile.mkdirs();
    }
    // 数据库文件是否创建成功
    boolean isFileCreateSuccess = false;
    // 判断文件是否存在,不存在则创建该文件
    File dbFile = new File(dbPath);
    if (!dbFile.exists()) {
    try {
    LogUtil.e(LogUtil.getLogTag()+"创建db");
    isFileCreateSuccess = dbFile.createNewFile();// 创建文件
    } catch (IOException e) {
    e.printStackTrace();
    }
    } else
    isFileCreateSuccess = true;
    // 返回数据库文件对象
    if (isFileCreateSuccess)
    return dbFile;
    else
    return super.getDatabasePath(dbName);
    }

    /**
     * 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。
     *
     * @param name
     * @param mode
     * @param factory
     */
    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode,SQLiteDatabase.CursorFactory factory) {
        SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory);
        return result;
    }
    
    /**
     * Android 4.0会调用此方法获取数据库。
     *
     * @param name
     * @param mode
     * @param factory
     * @param errorHandler
     * @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String, int,
     * android.database.sqlite.SQLiteDatabase.CursorFactory,
     * android.database.DatabaseErrorHandler)
     */
    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory,DatabaseErrorHandler errorHandler) {
        SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory);
    
        return result;
    }
    

    }

    相关文章

      网友评论

          本文标题:greenDao使用

          本文链接:https://www.haomeiwen.com/subject/ieyacxtx.html