亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【Android Developers Training】 26. 在SQL數(shù)

系統(tǒng) 1833 0

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接: http://developer.android.com/training/basics/data-storage/databases.html


在數(shù)據(jù)庫中保存數(shù)據(jù),對于重復(fù)性的或者結(jié)構(gòu)化的數(shù)據(jù)來說是很理想的,比如:聯(lián)系人信息。這節(jié)課我們假定你對SQL數(shù)據(jù)庫有一個大致的了解,并且?guī)椭阍贏ndroid上開始使用SQLite數(shù)據(jù)庫。你在Android的數(shù)據(jù)庫上需要使用的APIs在 android.database.sqlite 包中。

?

一). 定義一個架構(gòu)(Schema)和契約(Contract)

SQL數(shù)據(jù)庫的主要核心之一是:一個數(shù)據(jù)庫是如何組織的正式聲明。架構(gòu)所對應(yīng)的就是你用來創(chuàng)建數(shù)據(jù)庫的SQL語句聲明。你會發(fā)現(xiàn)創(chuàng)建一個輔助類( companion class ),即所謂的合同類(contract ?class ),它通過一個系統(tǒng)的和自文檔化的方式來顯示地指定你的架構(gòu)布局。

一個合同類是一個容器,它包含了那些定義了URI,表和列的名稱的常量。合同類允許你在同一個包內(nèi)所有類之間使用相同的名字。這樣可以使你想要改變列名時只需在一個地方修改,就能影響到所有使用到它的代碼。

一個良好的組織合同類的方式是:在類的根位置處,放置那些你的數(shù)據(jù)庫的全局定義。然后為每一個表創(chuàng)建一個內(nèi)部類,來枚舉它的列。

Note:

通過實現(xiàn)基列( BaseColumns )接口,你的內(nèi)部類可以繼承一個主鍵字段,叫做:“ _ID ”。一些Android類,比如光標適配器( cursor adaptors )會期望它能夠擁有這個。雖然這個不是必須的,但是它能夠幫助你的數(shù)據(jù)庫和Android更協(xié)同地工作。

例如,下例為一個簡單的表定義了表名和列名:

      
        public
      
      
        final
      
      
        class
      
      
         FeedReaderContract {

    
      
      
        //
      
      
         To prevent someone from accidentally instantiating the contract class,

    
      
      
        //
      
      
         give it an empty constructor.
      
      
        public
      
      
         FeedReaderContract() {}



    
      
      
        /*
      
      
         Inner class that defines the table contents 
      
      
        */
      
      
        public
      
      
        static
      
      
        abstract
      
      
        class
      
       FeedEntry 
      
        implements
      
      
         BaseColumns {

        
      
      
        public
      
      
        static
      
      
        final
      
       String TABLE_NAME = "entry"
      
        ;

        
      
      
        public
      
      
        static
      
      
        final
      
       String COLUMN_NAME_ENTRY_ID = "entryid"
      
        ;

        
      
      
        public
      
      
        static
      
      
        final
      
       String COLUMN_NAME_TITLE = "title"
      
        ;

        
      
      
        public
      
      
        static
      
      
        final
      
       String COLUMN_NAME_SUBTITLE = "subtitle"
      
        ;

        ...

    }

}
      
    

?

?二). 使用SQL助手創(chuàng)建一個數(shù)據(jù)庫

一旦你定義了你的數(shù)據(jù)庫,你應(yīng)該實現(xiàn)一些方法來創(chuàng)建和維護你的數(shù)據(jù)庫及表。下例是一些標準的創(chuàng)建和刪除數(shù)據(jù)庫的聲明:

      
        private
      
      
        static
      
      
        final
      
       String TEXT_TYPE = " TEXT"
      
        ;


      
      
        private
      
      
        static
      
      
        final
      
       String COMMA_SEP = ","
      
        ;


      
      
        private
      
      
        static
      
      
        final
      
       String SQL_CREATE_ENTRIES =

    "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
      
        

    FeedEntry._ID 
      
      + " INTEGER PRIMARY KEY," +
      
        

    FeedEntry.COLUMN_NAME_ENTRY_ID 
      
      + TEXT_TYPE + COMMA_SEP +
      
        

    FeedEntry.COLUMN_NAME_TITLE 
      
      + TEXT_TYPE + COMMA_SEP +
      
        

    ... 
      
      
        //
      
      
         Any other options for the CREATE command
      
      

    " )"
      
        ;




      
      
        private
      
      
        static
      
      
        final
      
       String SQL_DELETE_ENTRIES =

    "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;
    

就好像在設(shè)備內(nèi)存( internal storage )中所存儲的文件一樣,Android會將你的數(shù)據(jù)庫存儲在一個和應(yīng)用有關(guān)聯(lián)的私有磁盤空間中。你的數(shù)據(jù)將是安全的,因為默認情況下這些數(shù)據(jù)不會被其他應(yīng)用訪問到。

一個有用的APIs集合在 SQLiteOpenHelper 類中。當(dāng)你使用這個類來獲取你的數(shù)據(jù)庫的引用時,系統(tǒng)會僅在需要時(不在應(yīng)用啟動時)執(zhí)行一些可能需要消耗較長時間的操作,如:創(chuàng)建,更新數(shù)據(jù)庫。所有你需要的是調(diào)用 getWritableDatabase() 或者 getReadableDatabase()

Note:

因為它們可能會消耗比較長的時間,所以請確保你在一個后臺線程調(diào)用 getWritableDatabase() 或者 getReadableDatabase() ,比如: AsyncTask 或者 IntentService

要使用 SQLiteOpenHelper ,創(chuàng)建一個子類,覆寫 onCreate() onUpgrade() onOpen() 回調(diào)函數(shù)。你可能還需要實現(xiàn) onDowngrade() ,但這不是必須的。

例如,下面是一個 SQLiteOpenHelper 的實現(xiàn),它使用了之前所列舉的一些命令:

      
        public
      
      
        class
      
       FeedReaderDbHelper 
      
        extends
      
      
         SQLiteOpenHelper {

    
      
      
        //
      
      
         If you change the database schema, you must increment the database version.
      
      
        public
      
      
        static
      
      
        final
      
      
        int
      
       DATABASE_VERSION = 1
      
        ;

    
      
      
        public
      
      
        static
      
      
        final
      
       String DATABASE_NAME = "FeedReader.db"
      
        ;



    
      
      
        public
      
      
         FeedReaderDbHelper(Context context) {

        
      
      
        super
      
      (context, DATABASE_NAME, 
      
        null
      
      
        , DATABASE_VERSION);

    }

    
      
      
        public
      
      
        void
      
      
         onCreate(SQLiteDatabase db) {

        db.execSQL(SQL_CREATE_ENTRIES);

    }

    
      
      
        public
      
      
        void
      
       onUpgrade(SQLiteDatabase db, 
      
        int
      
       oldVersion, 
      
        int
      
      
         newVersion) {

        
      
      
        //
      
      
         This database is only a cache for online data, so its upgrade policy is

        
      
      
        //
      
      
         to simply to discard the data and start over
      
      
                db.execSQL(SQL_DELETE_ENTRIES);

        onCreate(db);

    }

    
      
      
        public
      
      
        void
      
       onDowngrade(SQLiteDatabase db, 
      
        int
      
       oldVersion, 
      
        int
      
      
         newVersion) {

        onUpgrade(db, oldVersion, newVersion);

    }

}
      
    

要訪問你的數(shù)據(jù)庫,實例化你的 SQLiteOpenHelper 子類:

      FeedReaderDbHelper mDbHelper = 
      
        new
      
       FeedReaderDbHelper(getContext());
    

?

三). 將信息添加到數(shù)據(jù)庫中

可以將一個 ContentValues 對象傳入 insert() 方法,來將數(shù)據(jù)添加到數(shù)據(jù)庫中:

      
        //
      
      
         Gets the data repository in write mode
      
      

SQLiteDatabase db =
      
         mDbHelper.getWritableDatabase();




      
      
        //
      
      
         Create a new map of values, where column names are the keys
      
      

ContentValues values = 
      
        new
      
      
         ContentValues();

values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);

values.put(FeedEntry.COLUMN_NAME_TITLE, title);

values.put(FeedEntry.COLUMN_NAME_CONTENT, content);




      
      
        //
      
      
         Insert the new row, returning the primary key value of the new row
      
      
        long
      
      
         newRowId;

newRowId 
      
      =
      
         db.insert(

         FeedEntry.TABLE_NAME,

         FeedEntry.COLUMN_NAME_NULLABLE,

         values);
      
    

insert() 方法的第一個參數(shù)就是表名。第二個參數(shù)提供了一個列名,當(dāng) ContentValues 為空時,框架會插入一個NULL。(如果你將這個參數(shù)設(shè)置為“ null ”,那么當(dāng)輸入時空時,框架不會添加一個新列)

?

四). 從數(shù)據(jù)庫中讀取數(shù)據(jù)

為了從數(shù)據(jù)庫中讀取數(shù)據(jù),使用 query() 方法,傳遞給它你的選擇標準和期望查找的列。這個方法結(jié)合了 insert() update() ,除了定義了你希望獲取數(shù)據(jù) (不是你希望插入的數(shù)據(jù)) 的列清單。查詢的結(jié)果將會以一個 Cursor 對象返回。

      SQLiteDatabase db =
      
         mDbHelper.getReadableDatabase();




      
      
        //
      
      
         Define a projection that specifies which columns from the database


      
      
        //
      
      
         you will actually use after this query.
      
      

String[] projection =
      
         {

    FeedEntry._ID,

    FeedEntry.COLUMN_NAME_TITLE,

    FeedEntry.COLUMN_NAME_UPDATED,

    ...

    };




      
      
        //
      
      
         How you want the results sorted in the resulting Cursor
      
      

String sortOrder =
      
        

    FeedEntry.COLUMN_NAME_UPDATED 
      
      + " DESC"
      
        ;



Cursor c 
      
      =
      
         db.query(

    FeedEntry.TABLE_NAME,  
      
      
        //
      
      
         The table to query
      
      

    projection,                               
      
        //
      
      
         The columns to return
      
      

    selection,                                
      
        //
      
      
         The columns for the WHERE clause
      
      

    selectionArgs,                            
      
        //
      
      
         The values for the WHERE clause
      
      
        null
      
      ,                                     
      
        //
      
      
         don't group the rows
      
      
        null
      
      ,                                     
      
        //
      
      
         don't filter by row groups
      
      

    sortOrder                                 
      
        //
      
      
         The sort order
      
      

    );
    

為了查詢 cursor中的一行,使用 Cursor 中的一個移動方法,這個方法你必須在開始讀數(shù)據(jù)時一直調(diào)用。一般地,你應(yīng)該從調(diào)用 moveToFirst() 開始,這樣將讀取位置放置到結(jié)果的第一個記錄。對于每一行,你可以你可以讀取某一列的值,通過調(diào)用 Cursor 的一個get方法,比如: getString() 或者 getLong() 。對于每個get方法,你必須傳入你期望的列的索引號,你可以通過調(diào)用 getColumnIndex() 或者 getColumnIndexOrThrow() 來得到索引號。

      
        cursor.moveToFirst();


      
      
        long
      
       itemId =
      
         cursor.getLong(

    cursor.getColumnIndexOrThrow(FeedEntry._ID)

);
      
    

?

五). 從數(shù)據(jù)庫中刪除數(shù)據(jù)

為了從數(shù)據(jù)庫中刪除一行數(shù)據(jù),你需要提供一個選擇標準來指定一行。數(shù)據(jù)庫的API提供了一個創(chuàng)建選擇標準的機制來防止SQL注入攻擊。這個機制將選擇語句分為了選擇命令段(selection clause)和選擇參數(shù)。命令段指定了要尋找的列,并且允許你可以結(jié)合一些列測試。參數(shù)是要測試的值,它是和命令段相對應(yīng)的。因為這個結(jié)果和通常的SQL語句聲明處理起來不一樣,所以能夠方式SQL注入。

      
        //
      
      
         Define 'where' part of query.
      
      

String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"
      
        ;


      
      
        //
      
      
         Specify arguments in placeholder order.
      
      

String[] selectionArgs =
      
         { String.valueOf(rowId) };


      
      
        //
      
      
         Issue SQL statement.
      
      

db.delete(table_name, selection, selectionArgs);
    

?

六). 更新一個數(shù)據(jù)庫

當(dāng)你需要修改一個數(shù)據(jù)庫值的子集,可以使用 update() 方法。

更新表結(jié)合了 insert() 的內(nèi)容語法和 delete() 的“ where ”語法。

      SQLiteDatabase db =
      
         mDbHelper.getReadableDatabase();




      
      
        //
      
      
         New value for one column
      
      

ContentValues values = 
      
        new
      
      
         ContentValues();

values.put(FeedEntry.COLUMN_NAME_TITLE, title);




      
      
        //
      
      
         Which row to update, based on the ID
      
      

String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"
      
        ;

String[] selectionArgs 
      
      =
      
         { String.valueOf(rowId) };




      
      
        int
      
       count =
      
         db.update(

    FeedReaderDbHelper.FeedEntry.TABLE_NAME,

    values,

    selection,

    selectionArgs);
      
    

【Android Developers Training】 26. 在SQL數(shù)據(jù)庫中保存數(shù)據(jù)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 在线观看www成人影院 | 国产成人综合久久亚洲精品 | 四虎影午夜成年免费精品 | 国内自拍 在线播放 网红 | 狠狠色丁香久久婷婷综 | 久久精品视频99 | 欧美一级成人一区二区三区 | 欧美日本在线 | 日韩欧美黄色 | 黄色午夜影院 | 亚欧在线精品免费观看一区 | 亚洲伦理中文字幕 | 中文字幕色婷婷在线视频 | 99精品久久 | 天天色天天操天天 | 四虎成年永久免费网站 | 99久久99久久久精品久久 | 国产综合成人亚洲区 | 日本高清不卡一区久久精品 | 精品久久久中文字幕一区 | 四虎影院免费在线 | 国产福利影院在线观看 | 视频国产在线 | 精品欧美一区二区三区精品久久 | 深夜福利视频网址 | 色婷婷久久 | 四虎国产精品永久地址99 | 人人做天天爱夜夜爽中字 | 国产毛片久久久久久国产毛片 | 依人成人综合网 | 欧美韩国日本一区 | 成人欧美午夜视频毛片 | 真实国产乱人伦在线视频播放 | 国产女人久久精品 | 色综合久久夜色精品国产 | 中国一级毛片aaa片 中国一级毛片录像 | 欧美乱插 | 在线观看三级拍拍视频 | 国产普通话自拍 | 欧美日韩北条麻妃一区二区 | 免费久久精品视频 |