Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 【Android】GreenDao操作外部DB數據庫文件

【Android】GreenDao操作外部DB數據庫文件

編輯:關於Android編程

1.背景

所謂外部數據庫文件此處指的就是一個在外部單獨創建的db文件,假設有這麼一個場景,我們項目中有一些本地數據,不需要接口去獲取的(不需要進行網絡操作),寫死的數據,比如全國各個省各個市的一些基本信息,每個市的信息可以作為表裡的一條記錄存放,在項目中使用,此時如何我們已經有了包含這些信息的db文件,我們就可以通過greendao來操作這個db文件,更具方便進行開發工作,當然這只是個模擬情況,至於合不合理,有沒有更好的方式,此處不過多討論,重點講這麼一種方式,這種方式可以用於一些不經常變化的數據。

2.項目配置

首先看一下項目結構:

這裡寫圖片描述

res喎?/kf/ware/vc/" target="_blank" class="keylink">vcmF3xL/CvLTmt8W1xL7NysfN4rK/tcRkYs7EvP61xNG5y/XOxLz+o6zO0sPHv8nS1LTyv6q/tNK7z8LK/b7dv+K94bm5o6xkYs7EvP6w/Lqswb3VxbHto6xzdHVkZW50us10ZWFjaGVywO/D5rzytaW1xLLlyOvBy7y4zPWy4srUyv2+3aO6PC9wPg0KPHA+PGltZyBhbHQ9"這裡寫圖片描述" src="/uploadfile/Collfiles/20160714/201607140921281301.png" title="\" />
這裡寫圖片描述

引入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 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操作圖如下;

這裡寫圖片描述


源碼下載:源碼下載,有問題歡迎交流討論!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved