黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

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

系統(tǒng) 2262 0

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

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


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

?

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

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

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

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

Note:

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

例如,下例為一個(gè)簡(jiǎn)單的表定義了表名和列名:

      
        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)建一個(gè)數(shù)據(jù)庫(kù)

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

      
        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 )中所存儲(chǔ)的文件一樣,Android會(huì)將你的數(shù)據(jù)庫(kù)存儲(chǔ)在一個(gè)和應(yīng)用有關(guān)聯(lián)的私有磁盤空間中。你的數(shù)據(jù)將是安全的,因?yàn)槟J(rèn)情況下這些數(shù)據(jù)不會(huì)被其他應(yīng)用訪問到。

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

Note:

因?yàn)樗鼈兛赡軙?huì)消耗比較長(zhǎng)的時(shí)間,所以請(qǐng)確保你在一個(gè)后臺(tái)線程調(diào)用 getWritableDatabase() 或者 getReadableDatabase() ,比如: AsyncTask 或者 IntentService

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

例如,下面是一個(gè) SQLiteOpenHelper 的實(shí)現(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ù)庫(kù),實(shí)例化你的 SQLiteOpenHelper 子類:

      FeedReaderDbHelper mDbHelper = 
      
        new
      
       FeedReaderDbHelper(getContext());
    

?

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

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

      
        //
      
      
         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() 方法的第一個(gè)參數(shù)就是表名。第二個(gè)參數(shù)提供了一個(gè)列名,當(dāng) ContentValues 為空時(shí),框架會(huì)插入一個(gè)NULL。(如果你將這個(gè)參數(shù)設(shè)置為“ null ”,那么當(dāng)輸入時(shí)空時(shí),框架不會(huì)添加一個(gè)新列)

?

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

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

      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 中的一個(gè)移動(dòng)方法,這個(gè)方法你必須在開始讀數(shù)據(jù)時(shí)一直調(diào)用。一般地,你應(yīng)該從調(diào)用 moveToFirst() 開始,這樣將讀取位置放置到結(jié)果的第一個(gè)記錄。對(duì)于每一行,你可以你可以讀取某一列的值,通過調(diào)用 Cursor 的一個(gè)get方法,比如: getString() 或者 getLong() 。對(duì)于每個(gè)get方法,你必須傳入你期望的列的索引號(hào),你可以通過調(diào)用 getColumnIndex() 或者 getColumnIndexOrThrow() 來得到索引號(hào)。

      
        cursor.moveToFirst();


      
      
        long
      
       itemId =
      
         cursor.getLong(

    cursor.getColumnIndexOrThrow(FeedEntry._ID)

);
      
    

?

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

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

?

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

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

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

      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ù)庫(kù)中保存數(shù)據(jù)


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論