• Android中的GreenDao框架修改数据库的存储路径


       目前android中比较热门的数据库框架有greenDAO、OrmLite、AndrORM,其中我比较喜欢用GreenDao,其运行效率最高,内存消耗最少,性能最佳。具体怎么使用GreenDao,网上随便搜搜都会有很多资料介绍。不过最近,在我的项目我需要改变数据库的存储位置,而android默认是在/data/data/Package Name/database创建数据库文件,

    我首先想到的GreenDao有没有提供这样的接口去修改存储路径,不过我好像没有发现这样的接口。

    于是我查看在GreenDao中生成的DaoMaster类:

    public static abstract class OpenHelper extends SQLiteOpenHelper {
            public OpenHelper(Context context, String name, CursorFactory factory) {
                super(context, name, factory, SCHEMA_VERSION);
            }
    
            @Override
            public void onCreate(SQLiteDatabase db) {
                Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
                createAllTables(db, false);
            }
     }
    
     public static class DevOpenHelper extends OpenHelper {
            public DevOpenHelper(Context context, String name, CursorFactory factory) {
                super(context, name, factory);
            }
    
            @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);
            }
     }

    }

    从上面这段可以看出GreenDap框架实际也是对原生数据库作了一层封装,数据库的创建、升级等仍然是继承SQLiteOpenHelper 来操作,于是我只能去看原生数据库中的SQLiteOpenHelper 类,该类中的getDatabaseLocked方法,也是在创建数据库的时候一定会调用的方法,其中有这样一段:

    if (DEBUG_STRICT_READONLY && !writable) {
    
           final String path = mContext.getDatabasePath(mName).getPath();
           db = SQLiteDatabase.openDatabase(path, mFactory,
           SQLiteDatabase.OPEN_READONLY, mErrorHandler);
     } else {
           db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
           Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
           mFactory, mErrorHandler);
     }

    没错,貌似我们已经看到了什么,数据库的默认存储路径采用的是mContext.getDatabasePath(mName),数据库名称需要指定,而路径即为使用到的Context也就是上下文的数据库路径,getDatabasePath(String name)就是上面提到过得默认路径,所以我们需要去自定义一个上下文继承自ContextWrapper,然后复写getDatabasePath(String name)方法,下面是我自定义的一个DatabaseContext ,修改了数据库路径为SD卡上的databases目录下:

    public class DatabaseContext extends ContextWrapper {
         public DatabaseContext(Context base) {
               super(base);
         }
        /**
         * 获得数据库路径,如果不存在,则自动创建
         */
        @Override
        public File getDatabasePath(String name) {
            //判断是否存在sd卡
            boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState());
            if(!sdExist){//如果不存在,
                Log.e("SD卡管理:", "SD卡不存在,请加载SD卡");
                return null;
            }
            else{//如果存在
                //获取sd卡路径
                String dbDir=android.os.Environment.getExternalStorageDirectory().toString();
                dbDir += "/databases";//数据库所在目录
                String dbPath = dbDir+"/"+name;//数据库路径
                //判断目录是否存在,不存在则创建该目录
                File dirFile = new File(dbDir);
                if(!dirFile.exists())
                    dirFile.mkdirs();
                //数据库文件是否创建成功
                boolean isFileCreateSuccess = false;
                //判断文件是否存在,不存在则创建该文件
                File dbFile = new File(dbPath);
                if(!dbFile.exists()){
                    try {
                        isFileCreateSuccess = dbFile.createNewFile();//创建文件
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                else
                    isFileCreateSuccess = true;
                //返回数据库文件对象
                if(isFileCreateSuccess)
                    return dbFile;
                else
                    return null;
                }
           }
    
          @Override
          public SQLiteDatabase openOrCreateDatabase(String name, int mode,
                                                   SQLiteDatabase.CursorFactory factory) {
               SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
               return result;
           }
       
          @Override
          public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory,
                                                   DatabaseErrorHandler errorHandler) {
                SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
               return result;
             }
    }

    最后,别忘了改变数据库创建时传入的Context,如下:

            DatabaseContext databaseContext = new DatabaseContext(this);
            helper = new DaoMaster.DevOpenHelper(databaseContext, "scyl.db", null);
            db = helper.getWritableDatabase();
            daoMaster = new DaoMaster(db);
            daoSession = daoMaster.newSession();

    一般的数据库的初始化建议放在Application中。到此数据库存储路径已经改变成指定的路径下。

  • 相关阅读:
    对象类JavaSist之ClassPool
    文件修改如何简单修改Android的so文件
    进程匿名APUE学习进程间通信(1)
    添加空间ShareSDK 微博空间分享
    文件学习IOS学习:常用第三方库(GDataXMLNode:xml解析库)
    文件androidAndroid 源码文件结构
    sql数据库java连接sqlserver2005数据库
    文件数据IOS学习:ios中的数据持久化初级(文件、xml、json、sqlite、CoreData)
    拼接字符SQL语句拼接 最后一个字符多出 处理方式
    目录服务器Linux Ubuntu上架设FTP
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/9105380.html
Copyright © 2020-2023  润新知