Android開發筆記:如何使用預先制作好的SQLite數據庫(整理自網絡)


參考:[Android]發布Sqlite數據庫

在實際開發中,我們經常遇到需使用自己已經定制好數據的數據庫,一般的做法是:

1、用Sqlite數據庫工具制作數據庫文件,網上有許多這類工具,可以自己搜索下載,我用的是SqliteStudio

需要注意的是android對其使用的Sqlite數據庫有一些固定的要求,包括:

1)數據庫文件中必須有一個名為“android_metadata”的表,這個表只包括一個字段:locale,也只需要一條記錄,默認值為“en_US”。

 

CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'zh_CN')
INSERT INTO "android_metadata" VALUES ('zh_CN')

 

2)數據庫文件中的其它表,必須包括一個名字“_id”的關鍵字字段,ListView等使用的適配器自動綁定'_id'如果沒有會報錯

2、將制作好的數據庫文件放在Android項目的assets文件夾或res/raw文件夾下(我習慣放在assets文件夾下)。

3Android項目使用的數據庫文件一般在/data/data/項目包名/databases/下,使用代碼使程序在運行時進行判斷,如該路徑下沒有指定的文件,則進行復制,否則不做任何操作。

4、如數據庫文件不超過1M,可以直接復制,否則需要預先將數據庫文分割為幾個不超過1M的文件,復制到目標路徑后再組合一一起。 

實例:

使用一個DBHelper類來實現判斷和復制數據庫的操作,這個類繼承自SQLiteOpenHelper類。

package com.bluehowk.homecooking;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

/**
* 用法:
* DBHelper dbHelper = new DBHelper(this);
* dbHelper.createDataBase();
* SQLiteDatabase db = dbHelper.getWritableDatabase();
* Cursor cursor = db.query()
* db.execSQL(sqlString);
* 注意:execSQL不支持帶;的多條SQL語句
* 見execSQL的源碼注釋 (Multiple statements separated by ;s are not supported.)
* 將把assets下的數據庫文件直接復制到DB_PATH,但數據庫文件大小限制在1M以下
* 如果有超過1M的大文件,則需要先分割為N個小文件,然后使用copyBigDatabase()替換copyDatabase()
*/
public class DBHelper extends SQLiteOpenHelper {
   //用戶數據庫文件的版本
   private static final int DB_VERSION    = 1;
   //數據庫文件目標存放路徑為系統默認位置,cn.arthur.examples 是你的包名
   private static String DB_PATH        = "/data/data/com.bluehowk.homecooking/databases/";
/*
   //如果你想把數據庫文件存放在SD卡的話
   private static String DB_PATH        = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
                                       + "目標路徑";
*/
   //下面兩個靜態變量分別是目標文件的名稱和在assets文件夾下的文件名
   private static String DB_NAME         = "cookdata.db";
   private static String ASSETS_NAME     = "cookdata.db";

   private SQLiteDatabase myDataBase    = null;
   private final Context myContext;

    /** 
     * 如果數據庫文件較大,使用FileSplit分割為小於1M的小文件
     * 此例中分割為 hello.db.101    hello.db.102    hello.db.103
     */
   //第一個文件名后綴
   private static final int ASSETS_SUFFIX_BEGIN    = 101;
   //最后一個文件名后綴
   private static final int ASSETS_SUFFIX_END        = 103;
   
   /**
    * 在SQLiteOpenHelper的子類當中,必須有該構造函數
    * @param context    上下文對象
    * @param name        數據庫名稱
    * @param factory    一般都是null
    * @param version    當前數據庫的版本,值必須是整數並且是遞增的狀態
    */
   public DBHelper(Context context, String name, CursorFactory factory, int version) {
       //必須通過super調用父類當中的構造函數
       super(context, name, null, version);
       this.myContext = context;
   }
   
   public DBHelper(Context context, String name, int version){
       this(context,name,null,version);
   }

   public DBHelper(Context context, String name){
       this(context,name,DB_VERSION);
   }
   
   public DBHelper (Context context) {
       this(context, DB_PATH + DB_NAME);
   }
   
   public void createDataBase() throws IOException{
       boolean dbExist = checkDataBase();
       if(dbExist)
       {
           //數據庫已存在,不做任何操作
       }
       else
       {
           //創建數據庫
           try {
               File dir = new File(DB_PATH);
               if(!dir.exists()){
                   dir.mkdirs();
               }
               File dbf = new File(DB_PATH + DB_NAME);
               if(dbf.exists()){
                   dbf.delete();
               }
               SQLiteDatabase.openOrCreateDatabase(dbf, null);
               // 復制asseets中的數據庫文件到DB_PATH下
               copyDataBase();
           } catch (IOException e) {
               throw new Error("數據庫創建失敗");
           }
       }
   }
   
   //檢查數據庫是否有效
   private boolean checkDataBase(){
       SQLiteDatabase checkDB = null;
       String myPath = DB_PATH + DB_NAME;
       try{            
           checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
       }catch(SQLiteException e){
           //database does't exist yet.
       }
       if(checkDB != null){
           checkDB.close();
       }
        return checkDB != null ? true : false;
   }

   /**
    * 復制assets文件中的數據庫到指定路徑
    * 使用輸入輸出流進行復制
   **/
   private void copyDataBase() throws IOException{
       
       InputStream myInput = myContext.getAssets().open(ASSETS_NAME);
       String outFileName = DB_PATH + DB_NAME;
       OutputStream myOutput = new FileOutputStream(outFileName);
       byte[] buffer = new byte[1024];
       int length;
       while ((length = myInput.read(buffer))>0){
           myOutput.write(buffer, 0, length);
       }
       myOutput.flush();
       myOutput.close();
       myInput.close();
   }
   
   //復制assets下的大數據庫文件時用這個
   private void copyBigDataBase() throws IOException{
       InputStream myInput;
       String outFileName = DB_PATH + DB_NAME;
       OutputStream myOutput = new FileOutputStream(outFileName);
       for (int i = ASSETS_SUFFIX_BEGIN; i < ASSETS_SUFFIX_END+1; i++) {
           myInput = myContext.getAssets().open(ASSETS_NAME + "." + i);
           byte[] buffer = new byte[1024];
           int length;
           while ((length = myInput.read(buffer))>0){
               myOutput.write(buffer, 0, length);
           }
           myOutput.flush();
           myInput.close();
       }
       myOutput.close();
   }
   
   @Override
   public synchronized void close() {
       if(myDataBase != null){
           myDataBase.close();
       }
       super.close();
   }
   
   
   @Override
   public void onCreate(SQLiteDatabase db) 
   {
   }
   
   /**
    * 數據庫創建時執行,如果不是預制的數據庫,可以在這些寫一些創建表和添加初始化數據的操作
    * 如:db.execSQL("create table cookdata (_id integer primary key,cook_name 
    * varchar(20),cook_sort varchar(20))");
    */
   @Override
   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
   {
       /**
        * 數據庫升級時執行,前面我們定義的DB_VERSION就是數據庫版本,在版本升高時執行
        * 一般做一些數據備份和恢復到新數據庫的操作。
        */
   }
}

可以使用如下代碼進行調用:

helper=new DBHelper(context);
        try {
            helper.createDataBase();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM