博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android GreenDao操作外部DB数据库文件
阅读量:7050 次
发布时间:2019-06-28

本文共 5837 字,大约阅读时间需要 19 分钟。

1.背景

所谓外部数据库文件此处指的就是一个在外部单独创建的db文件,假设有这么一个场景,我们项目中有一些本地数据,不需要接口去获取的(不需要进行网络操作),写死的数据,比如全国各个省各个市的一些基本信息,每个市的信息可以作为表里的一条记录存放,在项目中使用,此时如何我们已经有了包含这些信息的db文件,我们就可以通过greendao来操作这个db文件,更具方便进行开发工作,当然这只是个模拟情况,至于合不合理,有没有更好的方式,此处不过多讨论,重点讲这么一种方式,这种方式可以用于一些不经常变化的数据。

2.项目配置

  • 首先看一下项目结构:

这里写图片描述

res/raw目录存放的就是外部的db文件的压缩文件,我们可以打开看一下数据库结构,db文件包含两张表,student和teacher里面简单的插入了几条测试数据:

这里写图片描述 

这里写图片描述

  • 引入greendao库文件或者引用库工程:

这里写图片描述

2.代码实现

实现之前先说一下具体的思路,程序运行,首先把raw目录下的db文件拷贝到数据库存储的默认目录,然后通过greendao的api对这个文件进行操作即可;

    • 我们需要获取应用db存储的路径,通过如下方式:

 

private void getAppInfo()    {        // 获取packageManager的实例        PackageManager packageManager = getPackageManager();        // getPackageName()是你当前类的包名,0代表是获取版本信息        try        {            packInfo = packageManager.getPackageInfo(getPackageName(), 0);        }        catch (NameNotFoundException e)        {            e.printStackTrace();        }    }

 

    • 通过以上方式即可获取到数据库的路径: 

      这里写图片描述

    • 拷贝操作:

 

public static boolean copyRawDBToApkDb(Context context, int copyRawDbResId, String apkDbPath, String dbName,boolean refresh)        throws IOException    {        boolean b = false;        File f = new File(apkDbPath);        if (!f.exists())        {            f.mkdirs();        }        File dbFile = new File(apkDbPath + dbName);        b = isDbFileExists(dbFile,refresh);        if (!b)        {            InputStream is = context.getResources().openRawResource(copyRawDbResId);            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));            ZipEntry entry;            while ((entry = zis.getNextEntry()) != null)            {                int size;                byte[] buffer = new byte[1024 * 2];                OutputStream fos = new FileOutputStream(apkDbPath + entry.getName());                BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);                while ((size = zis.read(buffer, 0, buffer.length)) != -1)                {                    bos.write(buffer, 0, size);                }                bos.flush();                bos.close();            }            zis.close();            is.close();        }        return !b;    }

此处是拷贝操作的关键代码,需要我们传入raw资源ID,数据库的拷贝路径,数据库文件名,是否覆盖已经存在的db文件,@return 拷贝是否成功,关于refresh参数,我们一般希望只拷贝一次,当我们在某些情况下更新了这个db文件的话就可以设置为true进行覆盖操作;

  • 使用greenDao java工程,生成外部db文件所对应表的实体类Dao类等代码:

这里写图片描述

上图中的DBController类是我封装的数据库操作类,更方便我们去进行操作,DBController的关键代码如下:

/** * 外部数据库控制类 */public class DBController{    private static DaoMaster daoMasterEcmc;    private static DaoMaster daoMasterSchool;    // 默认DB    private static DaoSession daoSessionDefault;    // 拷贝的db    private static DaoSession daoSchoolSession;    /**     * 默认数据库名称:localdata     */    public static final String DATABASE_NAME = "localdata.db";    /**     * 拷贝数据库名称:school     */    public static final String DATABASE_SCHOOL_NAME = "school.db";    private static DaoMaster obtainMaster(Context context, String dbName)    {        return new DaoMaster(new DaoMaster.DevOpenHelper(context, dbName, null).getWritableDatabase());    }    private static DaoMaster getDaoMaster(Context context, String dbName)    {        if (dbName == null)            return null;        if (daoMasterEcmc == null)        {            daoMasterEcmc = obtainMaster(context, dbName);        }        return daoMasterEcmc;    }    private static DaoMaster getSchoolDaoMaster(Context context, String dbName)    {        if (dbName == null)            return null;        if (daoMasterSchool == null)        {            daoMasterSchool = obtainMaster(context, dbName);        }        return daoMasterSchool;    }    /**     * 取得DaoSession     *     * @return     */    public static DaoSession getDaoSession(String dbName)    {        if (daoSchoolSession == null)        {            daoSchoolSession = getSchoolDaoMaster(MainApplication.getIns(), dbName).newSession();        }        return daoSchoolSession;    }    /**     * 默认操作localdata数据库     */    public static DaoSession getDaoSession()    {        if (daoSessionDefault == null)        {            daoSessionDefault = getDaoMaster(MainApplication.getIns(), DATABASE_NAME).newSession();        }        return daoSessionDefault;    }}
  • 可能我们还需要默认的greendao数据库进行其他的操作,至于默认的操作此处不再详细介绍,不了解的可以看,此处我们演示的外部DB文件命名为school.db,默认的greenDao数据库命名为history.db,下面我们在MainActivity进行测试操作:

 

public class MainActivity extends Activity{    private StringBuilder builder;    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //创建默认的数据,并插入一条数据        HistoryDao historyDao = DBLocalController.getDaoSession().getHistoryDao();        History entity = new History();        entity.setName("科罗拉多");        entity.setImageUrl("http://www.baidu.com");        historyDao.insert(entity);        //拷贝外部DB文件到指定目录        copyRawDB();        //通过greendao查询外部db文件数据        selDBData();    }    private void selDBData()    {        StudentDao student = DBController.getDaoSession(DBController.DATABASE_SCHOOL_NAME).getStudentDao();        List
students = student.queryBuilder().list(); builder = new StringBuilder(); for (int i = 0; i < students.size(); i++) { builder.append(students.get(i).getName() + "---"); } Toast.makeText(MainActivity.this, builder.toString(), Toast.LENGTH_SHORT).show(); } private void copyRawDB() { try { // 拷贝res/raw/xxxxdb.zip 到 // /data/data/com.xinhang.mobileclient/databases/ 目录下面 boolean isSuccess = DBUtils.copyRawDBToApkDb(MainActivity.this, R.raw.schooldb, DBUtils.APK_DB_PATH, DBUtils.ECMC_DB_NAME, false); } catch (IOException e) { e.printStackTrace(); } }}

 

运行结果:

这里写图片描述

可以看到我们的外部db文件已经拷贝到数据库默认路径下,还有我们的默认数据库也创建成功;区分两个数据库的方式是通过DBLocalController.getDaoSession(name)方法,想操作哪个数据库传入对应的数据库名称即可,gif操作图如下;

这里写图片描述


源码下载:

 

你可能感兴趣的文章
VC++6.0 按F1无法打开 MSDN 的解决办法
查看>>
Eclipse自动部署项目到Tomcat的webapps下的有效方法
查看>>
Extjs4快速上手三——实现主界面
查看>>
如何替代Flex?
查看>>
控制属性修改时间,控制时间,联合主键
查看>>
android-包签名
查看>>
Android开发和调试必备工具-SDK Tools
查看>>
【LeetCode】107. Binary Tree Level Order Traversal II (2 solutions)
查看>>
《微软的软件测试之道》读书笔记 之 结构测试技术
查看>>
ASP.NET中Session的个人浅谈
查看>>
数学图形之Kuen Surface
查看>>
ORACLE里锁有以下几种模式,v$locked_object,locked_mode
查看>>
【树莓派】Linux 测网速及树莓派源
查看>>
Java用户线程和守护线程
查看>>
[TypeScript] Use the never type to avoid code with dead ends using TypeScript
查看>>
Javascript 与 SPA单页Web富应用
查看>>
SpringMVC之访问静态文件
查看>>
【java设计模式】之 模板方法(Template Method)模式
查看>>
小米手机会不会更好
查看>>
atitit.Sealink2000国际海运信息管理系统
查看>>