中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android的數據庫怎么使用

發布時間:2022-01-12 20:08:05 來源:億速云 閱讀:331 作者:iii 欄目:移動開發

今天小編給大家分享一下Android的數據庫怎么使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

一、Android數據庫使用

Android中使用android.database.sqlite.SQLiteDatabase來表示一個數據庫對象,它提供了兩種模式來幫助開發者進行增刪改查等基本數據庫操作。

利用SQL語句描述操作
利用SQL語句調用SQLiteDatabase.execSql或SQLiteDatabase.rawQuery來執行操作。

//利用sql查詢數據 Cursor data = db.rawQuery("select id,name from table");  //利用sql插入數據 db.execSql("insert into contacts (id,name) values (2,'cpacm')");

稍微學過sql語句的人應該都看的懂上面的代碼(其實看語句的意思也能知道個大概~)
在 這里我來解釋一下Cursor(游標)的作用吧,游標不能顧名思義(up主當時學習數據庫時一度將游標當做與C語言里面的指針變量一樣,雖然有點對,但意 思還是理解錯了),Cursor它是系統為用戶開設的一個數據緩沖區,是的,它是一塊數據區域,存放SQL語句的執行結果。但是它也提供了能從包括多條數 據記錄的結果集中每次提取一條記錄的機制,這一點也跟指針很像。游標總是與一條SQL選擇語句相關聯因為游標由結果集(可以是零條、一條或由相關的選擇語 句檢索出的多條記錄)和結果集中指向特定記錄的游標位置組成。當決定對結果集進行處理  時,必須聲明一個指向該結果集的游標。用C語言作比較的話,如果寫過對文件進行處理的程序,那么游標就像您打開文件所得到的文件句柄一樣,只要文件打開成 功,該文件句柄就可代表該文件。總之記住,游標是一塊有著特有記號的一塊數據區域,能夠讓用戶逐條從中讀取出數據。
結構化的方式描述數據庫的操作
這樣即使我們不熟悉SQL語句,也能使用最熟悉的面向對象的方式進行數據庫操作。

  1. //結構化的方式查詢數據 

  2. Cursor data = db.query("contacts",new String[]{"id","name"},null,null,null,null,null); 

  3.  

  4. //結構化方式插入數據 

  5. ContentValue values = new ContentValues(); 

  6. values.put("id",2); 

  7. values.put("name","cpacm"); 

  8. db.insert("table",null,values);

/** * 參數說明 * table:數據表名,columns:需要顯示的列名,如果為null則相當與* * selection:相當于sql語句的where條件;selectionArgs數組放的是where條件要替換的?號 * groupBy:SQL語句的Group, orderBy: 排序,默認asc **/ public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy){ }

比如說我要查詢的SQL語句為

SELECT CustomerName, SUM(OrderPrice) FROM Orders WHERE Country=?        GROUP BY CustomerName        HAVING SUM(OrderPrice)>500  ORDER BY CustomerName

那么我寫的代碼如下

//數據表名 String table =  "Orders" ;   //要顯示的列名 String[] columns = new  String[] { "CustomerName" ,  "SUM(OrderPrice)" };   //選擇條件 String selection = "Country=?" ;   //里面的變量對應條件中的問號,多個的時候請一一入座。 String[] selectionArgs = new  String[]{ "China" };   //分組名 String groupBy = "CustomerName" ;   //分組的條件 String having = "SUM(OrderPrice)>500" ;   //按字段排序 String orderBy = "CustomerName" ;   Cursor c = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);

這樣就能實現數據庫的查詢了。其它的語句參數都是差不多的,這里就不一一介紹了。

public long insert (String table, String nullColumnHack, ContentValues values)
public int delete(String table, String whereClause, String[] whereArgs)
public int update(String table, ContentValues values, String whereClause, String[] whereArgs)

課外小知識:關于GroupBy和Having的使用
group  by  顧名思義就是按照xxx進行分組,它必須有“聚合函數”來配合才能使用,使用時至少需要一個分組標識字段。聚合函數有:sum()、count()、 avg()等,使用group  by目的就是要將數據分組進行匯總操作。比如上面sql語句的CustomerName,如果它有四個行{“張三”,“李四”,“張三”,“李四”},那 么此時就會分成兩組,分別為張三組和李四組,然后統計出他們使用的orderprice總和。
HAVING作用就是為每一個組指定條件,像 where指定條件一樣,也就是說,可以根據你指定的條件來選擇行。如果你要使用HAVING子句的話,它必須處在GROUP  BY子句之后。還是上面的SQL語句,如果張三的SUM(OrderPrice)沒有超過500,那么張三組就不會顯示。

SQL語句的預編譯
在實踐中,有的SQL語句需要被反復使用,為了避免反復解析SQL語句產生的開銷,可以對需要復用的SQL語句進行預編譯,來提高數據庫操作的執行效率。

//編譯復雜的SQL語句SQLiteStatement compiledSql = db.compileStatement(aSQL); //執行SQLcompiledSql.execute();
//編譯復雜的SQL語句 SQLiteStatement compiledSql = db.compileStatement(aSQL); //執行SQL compiledSql.execute();

課外小知識:所謂事務是用戶定義的一 個數據庫操作序列,這些操作要么全做要么全不做,是一個不可分割的工作單位。例如,在關系數據庫中,一個事務可以是一條SQL語句、一組SQL語句或整個 程序。  簡單舉個例子就是你要同時修改數據庫中兩個不同表的時候,如果它們不是一個事務的話,當***個表修改完,可是第二表改修出現了異常而沒能修改的情況下,就 只有第二個表回到未修改之前的狀態,而***個表已經被修改完畢。  而當你把它們設定為一個事務的時候,當***個表修改完,可是第二表改修出現了異常而沒能修改的情況下,***個表和第二個表都要回到未修改的狀態!這就是所 謂的事務回滾。

SQLiteOpenHelper
在SQLiteOpenHelper中,封裝了一個SqliteDatabase對象,使用著可以通過使用此類來進行數據庫的操作。

package com.example.notebook;  import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory;   public class DBHelper extends SQLiteOpenHelper{     private static final int VERSION=1;     /**       * 在SQLiteOpenHelper的子類當中,必須有該構造函數       * @param context   上下文對象       * @param name      數據庫名稱       * @param factory       * @param version   當前數據庫的版本,值必須是整數并且是遞增的狀態       */     public DBHelper(Context context,String name,CursorFactory factory,int version){         super(context,name,factory,version);     }     public DBHelper(Context context, String name, int version){           this(context,name,null,version);       }          public DBHelper(Context context, String name){           this(context,name,VERSION);       }     @Override     public void onCreate(SQLiteDatabase db) {          // 數據庫***構造時,會調用該函數,可以在這里構造表、索引,等等          System.out.println("create a database");           //execSQL用于執行SQL語句           db.execSQL("create table notebook(_id integer primary key autoincrement,pic varchar(50),title varchar(20),content text,time varchar)");              }     @Override     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {         // 如果給定的當前數據庫版本高于已有數據庫版本,調用該函數         System.out.println("upgrade a database");     }    }

SQLiteOpenHelper的應用
新建一個數據庫管理類DBManager

package com.example.notebook;  import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.util.Log;  public class DBManager {      private Context mContext = null;          private SQLiteDatabase mSQLiteDatabase = null;//用于操作數據庫的對象     private DBHelper dh = null;//用于創建數據庫的對象          private String dbName = "note.db";//數據庫的名稱     private int dbVersion = 1;//數據庫的版本     public DBManager(Context context){         mContext = context;     }      public void open(){         try{             dh = new DBHelper(mContext, dbName, null, dbVersion);//建立數據庫             if(dh == null){                 Log.v("msg", "is null");                 return ;             }             mSQLiteDatabase = dh.getWritableDatabase();//以可寫方式打開數據庫             //dh.onOpen(mSQLiteDatabase);         }catch(SQLiteException se){             se.printStackTrace();         }     } public void close(){          mSQLiteDatabase.close();//關閉數據庫     dh.close();      } public Cursor selectAll(){     Cursor cursor = null;     try{         //sql語句操作         String sql = "select * from notebook";         cursor = mSQLiteDatabase.rawQuery(sql, null);     }catch(Exception ex){         ex.printStackTrace();         cursor = null;     }     return cursor; } public Cursor selectById(int id){          //String result[] = {};     Cursor cursor = null;     try{         //sql語句操作         String sql = "select * from notebook where _id='" + id +"'";         cursor = mSQLiteDatabase.rawQuery(sql, null);     }catch(Exception ex){         ex.printStackTrace();         cursor = null;     }          return cursor; } public long insert(String title, String content,String pic){          long datetime = System.currentTimeMillis();     long l = -1;     try{         //結構化方式操作         ContentValues cv = new ContentValues();         cv.put("title", title);         cv.put("content", content);         cv.put("time", datetime);         cv.put("pic", pic);         l = mSQLiteDatabase.insert("notebook", null, cv);     //    Log.v("datetime", datetime+""+l);     }catch(Exception ex){         ex.printStackTrace();         l = -1;     }     return l;      } public int delete(int id){     int affect = 0;     try{         //結構化方式操作         affect = mSQLiteDatabase.delete("notebook", "_id=?", new String[]{String.valueOf(id)});     }catch(Exception ex){         ex.printStackTrace();         affect = -1;     }          return affect; } public int update(int id, String title, String content,String pic){     int affect = 0;     try{         //結構化方式操作         ContentValues cv = new ContentValues();         cv.put("title", title);         cv.put("content", content);         cv.put("pic", pic);         String w[] = {String.valueOf(id)};         affect = mSQLiteDatabase.update("notebook", cv, "_id=?", w);     }catch(Exception ex){         ex.printStackTrace();         affect = -1;     }     return affect; }  }

獲取數據示例

private DBManager dm = null;// 數據庫管理對象 rivate Cursor cursor = null;            dm = new DBManager(this);//數據庫操作對象            dm.open();//打開數據庫操作對象            cursor = dm.selectAll();//獲取所有數據            cursor.moveToFirst();//將游標移動到***條數據,使用前必須調用                        int count = cursor.getCount();//個數            ArrayList<String> contents = new ArrayList<String>();//圖片的所有集合            ArrayList<String> imgs = new ArrayList<String>();//圖片的所有集合            ArrayList<String> items = new ArrayList<String>();//標題的所有集合            ArrayList<String> times = new ArrayList<String>();//時間的所有集合            for(int i= 0; i < count; i++){                contents.add(cursor.getString(cursor.getColumnIndex("content")));                imgs.add(cursor.getString(cursor.getColumnIndex("pic")));                items.add(cursor.getString(cursor.getColumnIndex("title")));                times.add(cursor.getString(cursor.getColumnIndex("time")));                //cursor.getInt(cursor.getColumnIndex("_id"))                cursor.moveToNext();//將游標指向下一個            }            dm.close();//關閉數據操作對象

數據庫的并發問題
并發問題是使用數據庫過程中最容易碰到的問題,如果在開發中碰到了android.database.SQLException異常,并提示"database is locked",那很有可能是出現了數據庫的死鎖導致無法訪問。原因是Sqlite會對文件的讀寫進行加鎖,防止數據被破壞。而在Android框架層SqliteDatabase會對所有數據庫對象進行加鎖保護,一旦出現了指向同一個數據庫的多個SqliteDatabase對象同時在多個線程中被使用,那就跳脫了SqliteDatabase鎖保護,就會導致數據庫出現被鎖的異常。因此在實踐中,需要保證同時訪問數據庫的SqliteDatabase對象僅有一個。(可以使用全局變量來保存數據庫對象,在整個數據源對象中使用同一個連接)
課外小知識:在Android SDK中提供了工具Sqlite3,在shell模式下,可以對數據庫進行增刪改查。  
cmd->adb shell ->sqlite3 <路徑>/<數據庫名> ->sqlite > select * from sqmple;

二、Android數據的云端服務

本質上而言,云端存儲就是通過網絡將移動設備上的數據存儲到遠端服務器上。在Android中,增加了一些輔助功能,使得整個流程的實現變得更為簡單。首先是通過Google賬號來標識用戶身份。在android中,默認支持使用Google賬號作為用戶身份的標識,系統上各個應用都可以通過賬號系統獲得用戶的登錄信息。其次,有了Google賬號,使得開發者不需要自行構建后臺服務系統。

Android的云端數據存取由系統服務BackupManagerService來統一管理。當應用提交備份數據請求時,BackupManagerService會將該請求放入備份隊列中,該隊列會按照一定的控制邏輯定時提交到云端。當有新應用安裝到系統時,會觸發數據恢復事件,BackupManagerService會憑借應用包名和用戶賬號從云端取出相應的備份數據,嘗試恢復。

在實踐中,Android會構造一個派生自BackupAgent類的子類android.app.backup.BackupAgentHelper的對象,來更方便地構建云端存儲組件。

Android不會自行將數據提交到云端,開發者需要顯性調用android.app.backup.BackupManager的dataChanged函數來觸發。

和所有組件一樣,云端存儲組件是由系統進行托管的。這就需要把組件的相關信息放入配置文件中。

<application android:backupAgent = "MyBackupAgent"  ...>

以上就是“Android的數據庫怎么使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

延寿县| 太保市| 三河市| 沽源县| 杭锦后旗| 凤山市| 灵台县| 会同县| 明水县| 台安县| 麟游县| 稷山县| 宣恩县| 平昌县| 乐亭县| 武平县| 东方市| 忻州市| 延寿县| 绥中县| 五常市| 额济纳旗| 遂平县| 监利县| 舒城县| 孟津县| 长泰县| 广州市| 东海县| 宝坻区| 吐鲁番市| 汶川县| 南汇区| 天镇县| 云南省| 新密市| 育儿| 普宁市| 宜兰市| 涟源市| 遵义县|