ObjectBox——objectBox数据库路径及自定义路径

目录

前言

一.ObjectBox数据库默认存储路径

二.ObjectBox自定义存储路径

三.ObjectBox数据库管理类封装


前言

之前已经讲了ObjectBox的基本配置,网上已经讲了很多ObjectBox的相关知识,但是ObjectBox的数据库存储路径问题,却极少提到,这节就让我们来探究下ObjectBox的数据存储路径吧。

今天涉及的知识有:

  1. ObjectBox数据库默认存储路径
  2. ObjectBox自定义存储路径
  3. ObjectBox数据库管理类封装

一.ObjectBox数据库默认存储路径

在使用Objectbox进行数据处理之前,我们先要初始化ObjectBox数据库,这时会涉及到BoxStore的初始化,让我们来看看初始化ObjectBox数据库代码吧:

private static BoxStore boxStore;

boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();

这段代码会在你项目的application中初始化。其中,让我们来看看

androidContext(context.getApplicationContext())

方法,追踪源码,会看到以下代码:

    public BoxStoreBuilder androidContext(Object context) {
        if (context == null) {
            throw new NullPointerException("Context may not be null");
        }
        this.context = getApplicationContext(context);

        File baseDir = getAndroidBaseDir(context);
        if (!baseDir.exists()) {
            baseDir.mkdir();
            if (!baseDir.exists()) { // check baseDir.exists() because of potential concurrent processes
                throw new RuntimeException("Could not init Android base dir at " + baseDir.getAbsolutePath());
            }
        }
        if (!baseDir.isDirectory()) {
            throw new RuntimeException("Android base dir is not a dir: " + baseDir.getAbsolutePath());
        }
        baseDirectory = baseDir;
        android = true;
        return this;
    }

继续看其中涉及到的 getAndroidBaseDir(context) 方法:

    static File getAndroidBaseDir(Object context) {
        return new File(getAndroidFilesDir(context), "objectbox");
    }

这里我们看到创建了一个File,getAndroidFilesDir(context)是一个路径,然后后面跟了一个"objectbox"值,"objectbox"是该路径下的一个文件夹名称,接着往下看

    @Nonnull
    private static File getAndroidFilesDir(Object context) {
        File filesDir;
        try {
            Method getFilesDir = context.getClass().getMethod("getFilesDir");
            filesDir = (File) getFilesDir.invoke(context);
            if (filesDir == null) {
                // Race condition in Android before 4.4: https://issuetracker.google.com/issues/36918154 ?
                System.err.println("getFilesDir() returned null - retrying once...");
                filesDir = (File) getFilesDir.invoke(context);
            }
        } catch (Exception e) {
            throw new RuntimeException(
                    "Could not init with given Android context (must be sub class of android.content.Context)", e);
        }
        if (filesDir == null) {
            throw new IllegalStateException("Android files dir is null");
        }
        if (!filesDir.exists()) {
            throw new IllegalStateException("Android files dir does not exist");
        }
        return filesDir;
    }

ok, getAndroidFilesDir(Object context) 方法其实是创建了一个文件夹路径。
接着我们看

boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();

中 的 “ .build()” 方法,追踪源码,显示如下:

    /**
     * Builds a {@link BoxStore} using any given configuration.
     */
    public BoxStore build() {
        if (directory == null) {
            name = dbName(name);
            directory = getDbDir(baseDirectory, name);
        }
        checkProvisionInitialDbFile();
        return new BoxStore(this);
    }

继续看 dbName(name) 方法:

    private static String dbName(@Nullable String dbNameOrNull) {
        return dbNameOrNull != null ? dbNameOrNull : DEFAULT_NAME;
    }

这里出现了当 dbName(name)方法中的 name为null时,会设置一个默认name=DEFAULT_NAME,接着看追踪DEFAULT_NAME:

public static final String DEFAULT_NAME = "objectbox";

会发现以上 的都是在设置数据库的文件夹路径directory,所以由此看ObjectBox存储路径是 getAndroidFilesDir(Object context) / objectbox /objectbox/ ,接着我们看看ObjectBox数据库文件名及文件格式。接着看 “ .build()” 方法 中的:

 checkProvisionInitialDbFile();

追踪看看:

    private void checkProvisionInitialDbFile() {
        if (initialDbFileFactory != null) {
            String dataDir = BoxStore.getCanonicalPath(directory);
            File file = new File(dataDir, "data.mdb");
            if (!file.exists()) {
                InputStream in = null;
                OutputStream out = null;
                try {
                    in = initialDbFileFactory.provide();
                    if (in == null) {
                        throw new DbException("Factory did not provide a resource");
                    }
                    in = new BufferedInputStream(in);
                    out = new BufferedOutputStream(new FileOutputStream(file));
                    IoUtils.copyAllBytes(in, out);
                } catch (Exception e) {
                    throw new DbException("Could not provision initial data file", e);
                } finally {
                    IoUtils.safeClose(out);
                    IoUtils.safeClose(in);
                }
            }
        }
    }

其中有一行:

 File file = new File(dataDir, "data.mdb");

据此,我们知道ObjectBox的存储默认文件为:"data.mdb 。
ok,通过以上的追踪,得出ObjectBox默认存储路径为:

getAndroidFilesDir(Object context) / objectbox /objectbox/ data.mdb
getAndroidFilesDir(Object context) / objectbox /objectbox/ data.mdb

由于getAndroidFilesDir(Object context)是源码中一个私有方法。第一种方案,你可以将此方法拷贝出来,然后运行查看路径。第二种方案:我们大致可以看出此路径是在项目app的内部的,这里我直接运行自己的项目,然后查看手机app安装目录,在
/data/data/app包名/files/objectbox/objectbox/ 目录下看到以下截图

即,当 BoxStore 在初始化时,以:

    public static void init(Context context) {
        boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();
        LogUtil.i("===BoxStore.version="+BoxStore.getVersion()+"  BoxStore.versionNative="+BoxStore.getVersionNative());
    }

方式创建的时候,ObjectBox数据库默认文件存储路径为:

/data/data/app包名/files/objectbox/objectbox/data.mdb

二.ObjectBox自定义存储路径

经过上面的研究,我们可以发现 boxStore对象是通过

 boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();

获取到的,其实

  boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();

而 androidContext(context.getApplicationContext()) 只不过是 boxStoreBuilder 的一个方法,boxStore 初始化本质是:

boxStore = boxStoreBuilder.build(); 

查看ObjectBox官网doc发现

BoxStoreBuilder 类的 directory(File directory) 方法可以设置数据库文件存储路径。

irectory(File directory) 中的 File 参数是一个文件夹路径。那么让我们先设置一个文件夹路径看看:

String filePath=context.getExternalFilesDir("objectbox").getAbsolutePath()+File.separator;
        File file=new File(filePath);
        BoxStoreBuilder boxStoreBuilder = MyObjectBox.builder()
                .directory(setDBFilePath(context));//自定义数据库存储路径
        mBoxStore = boxStoreBuilder.build();

查看设备中ObjectBox数据库文件路径:

Sdcard/Android/data/app包名/files/objectbox/  

如下图:

注意:自定义数据库存储路径时,通过 directory(File directory) 方法只能设置一个文件夹路径,不能设置具体文件路径。而路径虽然自定义了,但文件名依然会默认是"data.mdb"。

废话不多说了,正片来了

三.ObjectBox数据库管理类封装

为了方便使用,我将ObjectBox封装成一个单例对象ObjectBoxManager。在Application中初始化ObjectBox数据库框架:

public class AppContext extends ComContext {

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


        //初始化ObjectBox
        ObjectBoxManager.getInstance().init(this);

    }

在MainActivity中处理数据类似下面这样(其中User为数据实体类):

 Box userBox = ObjectBoxManager.getInstance().getBox(User.class);
        //添加数据
        User user=new User();
        user.setAge(15);
        user.setName("小明");
        long id=userBox.put(user);
        LogUtil.i("===存储id==="+id);
        LogUtil.i("Inserted new note, ID: " + user.getId());

下面贴出ObjectBoxManager代码:

import android.content.Context;
import android.util.Log;

import java.io.File;

import io.objectbox.Box;
import io.objectbox.BoxStore;
import io.objectbox.BoxStoreBuilder;
import io.objectbox.android.AndroidObjectBrowser;

/**
 * Title:ObjectBox数据库管理单例对象
 */
public class ObjectBoxManager {
    private static final String TAG = "ObjectBoxManager";
    //浏览器地址:http://localhost:8090/index.html
    //adb指令:adb forward tcp:8090 tcp:8090

    //设备/浏览器 设置数据库数据调试(只在调试模式时设置为true)
    private static boolean isObjectBoxDebug=true;

    private BoxStore mBoxStore;

    private ObjectBoxManager(){}

    private static class Holder {
        private static ObjectBoxManager instance = new ObjectBoxManager();
    }

    public static ObjectBoxManager getInstance() {
        return Holder.instance;
    }

    /**
     * 在 Application 中初始化
     * @param context 上下文
     * @param isDefaultPath 是否启用默认路径
     * @param dataBaseDirPath 数据库文件保存路径
     */
    public void init(Context context,boolean isDefaultPath,String dataBaseDirPath) {
        //自定义objectBox数据库文件路径
        //  /storage/emulated/0/Android/data/com.example.testdemo/files/objectbox/data.mdb
        //自定义时只能定义文件夹路径,具体文件名仍然默认是 “data.mdb”
        BoxStoreBuilder boxStoreBuilder;
        if (isDefaultPath){
            boxStoreBuilder=MyObjectBox.builder()
                    .androidContext(context.getApplicationContext());
        }else{
            boxStoreBuilder = MyObjectBox.builder()
                    .directory(setDBFilePath(dataBaseDirPath))//自定义数据库存储路径
                    .androidContext(context);
        }
        

      
        //获取BoxStore对象
        mBoxStore = boxStoreBuilder.build();
        Log.i(TAG,"===BoxStore.version="+BoxStore.getVersion()+"  BoxStore.versionNative="+BoxStore.getVersionNative());
        if(isObjectBoxDebug){
            //可以理解为初始化连接浏览器(可以在浏览器中查看数据)
            boolean start= new AndroidObjectBrowser(mBoxStore).start(context.getApplicationContext());
            Log.i(TAG,"=====boxStore===start="+start);
        }
    }

    /**自定义数据库存储路径**/
    private File setDBFilePath(String dataBaseDirPath){
        //自定义objectBox数据库文件路径
        //  /storage/emulated/0/Android/data/com.example.testdemo/files/objectbox/data.mdb
        //自定义时只能定义文件夹路径,具体文件名仍然默认是 “data.mdb”
        //String filePath=context.getExternalFilesDir("objectbox").getAbsolutePath()+File.separator;
        return new File(dataBaseDirPath);
    }

    /***
     * 获取Box对象
     * @param cls 实体类对象,如:User.class
     * @return 返回box操作对象
     */
    public Box<?> getBox(Class<?>cls){
        return mBoxStore.boxFor(cls);
    }

    /**获取BoxStore对象**/
    public BoxStore getBoxStore(){
        return mBoxStore;
    }

    /**
     * 删除整个数据库文件(慎用)
     * @return 返回boolean,为true表示删除数据库文件成功
     */
    public boolean deleteDataBase() {
        boolean isDelete = false;
        if (mBoxStore != null) {
            //关闭数据库
            mBoxStore.close();
            //删除数据库文件
            isDelete = mBoxStore.deleteAllFiles();
            Log.i(TAG,"=======delete database AllFiles=====" + isDelete);
        }
        return isDelete;
    }
}

注意 : 封装类 ObjectBoxManager 中的 deleteDataBase 方法是删除整个数据库文件,一定要慎用。

ok,关于ObjectBox数据库文件存储路径相关知识就讲到这里了,谢谢大家



版权声明:本文为weixin_47884471原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>