【Android】GreenDao操作外部DB数据库文件

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数据库进行其他的操作,至于默认的操作此处不再详细介绍,不了解的可以看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<Student> 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操作图如下;



源码下载:源码下载,有问题欢迎交流讨论!

时间: 2024-10-28 21:21:15

【Android】GreenDao操作外部DB数据库文件的相关文章

GreenDao操作本地db文件(使用greendao 新版3.2.2 )

项目需求:省市区使用本地db文件,数据库使用greendao框架.现在不想使用SQL语句,用greendao直接查询本地数据库表(至于为啥使用GreenDao,可以百度一下它的优势). 思路: 1.将db文件copy到数据库默认目录下 /data/data/你的项目包名/databases/表名(与greendao生成的表相同) 2.greendao生成对应表的实体.Dao文件,使用greendao封装的方法操作已copy过来的数据库表. 遇到的问题: 1.android.database.sq

android将asseet当中的数据库文件拷到程序目录

/** * 将asseet当中的数据库文件拷到程序目录 * @param activity 当前Activity * @param filePath 你的程序目录 getApplicationContext().getFilesDir().getAbsolutePath(); * @param fileName 你的数据库名称 */ public static void copyEmbassy2Databases(Activity activity, String filePath, Strin

查看Android下生成的.db数据库

1.在cmd中找到sdk中的platform-tools文件夹. 2.输入adb shell命令. 3.再输入sqlite3 /data/data/com.svs.db/databases/svs.db com.svs.db为项目的包名,svs.db为数据库 4.   .tables为查询所用表. .schema为查询表的创建语句.

android greendao的外部封装不太友好。

https://github.com/greenrobot/greenDAO 下载下官网的示例,有完整的封装版本,但自已封装是碰到很多问题. 因greenDao的Master和Session中很多方法完全是隐藏的,只属于此类. 很多信息也是隐藏的. 只能基于继承此两类来实现(像官网示例一样) 想通过公有方法来实现最基本的一个demo也碰到很多坑. 这是示例 Master.DevOpenHelper dbhelp=new Master.DevOpenHelper(this,"dbname"

Unity3D在Android平台使用嵌入式数据库Sqlite,解决无法找到数据库文件的问题

做一个需要嵌入式数据库Sqlite 的unity3d项目,在pc机上运行良好,需要发布到Android平台上,于是,各种坑爹...会遇到找不到数据库文件的问题.当在pc机上使用sqlite时,当执行SqliteConnection dbConnection = new SqliteConnection("data source = test.db");语句时,如果有这个数据库文件则建立连接,如果没有则创建出这个文件,然后建立连接.当在Android平台上时,扯淡的事情就开始了,总之便不

通过adb shell操作android真机的SQLite数据库

要通过命令行直接操作android真机上的SQLite数据库,可以直接通过adb shell来完成,不过,前提是必须获得root权限. 另外,android系统其实就是linux的shell,这个应该大家都知道,不过一般情况下,在/system/xbin/目录下, 没有sqlite3命令,需要手动copy一个进去,通常情况下,需要两个文件 sqlite3.libncurses.so 解压后两个文件都有了,比如解压到:~/Downloads/sqlite3/ 然后就是通过下面的这些个命令,一步一步

Android下创建一个SQLite数据库

数据库:SQLite(轻量级,嵌入式的数据库) 大量的相似结构的数据的储存,快速的查询.特殊的文件(按照一定的格式生成) 数据库的创建 创建文件 1.声明文件对象,文件是不会被创建出来的. File file = new File("文件名称"); 2.写文件(文件才会被创建出来) FileOutputStream fos = new FileOutputStream(file); fos.write("hdahfdsaklfh".getbytes()); 创建数据

Android -- com.android.providers.media,external.db

external.db android是管理多媒体文件(音频.视频.图片)的信息是在/data/data/com.android.providers.media下的数据库文件external.db. 在media表格下,可以看到文件路径(_data)和Uri的标示ID(_id)的对应关系. Code 获取路径: Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERN

Android 查看和管理sqlite数据库

在Android中可以使用Eclipse插件DDMS来查看,也可以使用Android工具包中的adb工具来查看.android项目中的sqlite数据库位于/data/data/项目包/databases中. 使用DDMS导出sqlite数据库. 1.首先打开android项目的调试模式,然后找到显示DDMS: 选择DDMS 2.切换到DDMS,显示File Explorer窗口,找到/data/data/ 然后找到程序包的文件夹,打开databases,就能看到sqlite数据库文件了.选择将