今天小編給大家分享一下Android的數(shù)據(jù)庫怎么使用的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、蘇州網(wǎng)絡(luò)推廣、成都小程序開發(fā)、蘇州網(wǎng)絡(luò)營銷、蘇州企業(yè)策劃、蘇州品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供蘇州建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
一、Android數(shù)據(jù)庫使用
Android中使用android.database.sqlite.SQLiteDatabase來表示一個數(shù)據(jù)庫對象,它提供了兩種模式來幫助開發(fā)者進行增刪改查等基本數(shù)據(jù)庫操作。
利用SQL語句描述操作
利用SQL語句調(diào)用SQLiteDatabase.execSql或SQLiteDatabase.rawQuery來執(zhí)行操作。
//利用sql查詢數(shù)據(jù) Cursor data = db.rawQuery("select id,name from table"); //利用sql插入數(shù)據(jù) db.execSql("insert into contacts (id,name) values (2,'cpacm')");
稍微學(xué)過sql語句的人應(yīng)該都看的懂上面的代碼(其實看語句的意思也能知道個大概~)
在 這里我來解釋一下Cursor(游標)的作用吧,游標不能顧名思義(up主當時學(xué)習(xí)數(shù)據(jù)庫時一度將游標當做與C語言里面的指針變量一樣,雖然有點對,但意 思還是理解錯了),Cursor它是系統(tǒng)為用戶開設(shè)的一個數(shù)據(jù)緩沖區(qū),是的,它是一塊數(shù)據(jù)區(qū)域,存放SQL語句的執(zhí)行結(jié)果。但是它也提供了能從包括多條數(shù) 據(jù)記錄的結(jié)果集中每次提取一條記錄的機制,這一點也跟指針很像。游標總是與一條SQL選擇語句相關(guān)聯(lián)因為游標由結(jié)果集(可以是零條、一條或由相關(guān)的選擇語 句檢索出的多條記錄)和結(jié)果集中指向特定記錄的游標位置組成。當決定對結(jié)果集進行處理 時,必須聲明一個指向該結(jié)果集的游標。用C語言作比較的話,如果寫過對文件進行處理的程序,那么游標就像您打開文件所得到的文件句柄一樣,只要文件打開成 功,該文件句柄就可代表該文件??傊涀。螛耸且粔K有著特有記號的一塊數(shù)據(jù)區(qū)域,能夠讓用戶逐條從中讀取出數(shù)據(jù)。
結(jié)構(gòu)化的方式描述數(shù)據(jù)庫的操作
這樣即使我們不熟悉SQL語句,也能使用最熟悉的面向?qū)ο蟮姆绞竭M行數(shù)據(jù)庫操作。
//結(jié)構(gòu)化的方式查詢數(shù)據(jù)
Cursor data = db.query("contacts",new String[]{"id","name"},null,null,null,null,null);
//結(jié)構(gòu)化方式插入數(shù)據(jù)
ContentValue values = new ContentValues();
values.put("id",2);
values.put("name","cpacm");
db.insert("table",null,values);
/** * 參數(shù)說明 * table:數(shù)據(jù)表名,columns:需要顯示的列名,如果為null則相當與* * selection:相當于sql語句的where條件;selectionArgs數(shù)組放的是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
那么我寫的代碼如下
//數(shù)據(jù)表名 String table = "Orders" ; //要顯示的列名 String[] columns = new String[] { "CustomerName" , "SUM(OrderPrice)" }; //選擇條件 String selection = "Country=?" ; //里面的變量對應(yīng)條件中的問號,多個的時候請一一入座。 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);
這樣就能實現(xiàn)數(shù)據(jù)庫的查詢了。其它的語句參數(shù)都是差不多的,這里就不一一介紹了。
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)
課外小知識:關(guān)于GroupBy和Having的使用
group by 顧名思義就是按照xxx進行分組,它必須有“聚合函數(shù)”來配合才能使用,使用時至少需要一個分組標識字段。聚合函數(shù)有:sum()、count()、 avg()等,使用group by目的就是要將數(shù)據(jù)分組進行匯總操作。比如上面sql語句的CustomerName,如果它有四個行{“張三”,“李四”,“張三”,“李四”},那 么此時就會分成兩組,分別為張三組和李四組,然后統(tǒng)計出他們使用的orderprice總和。
HAVING作用就是為每一個組指定條件,像 where指定條件一樣,也就是說,可以根據(jù)你指定的條件來選擇行。如果你要使用HAVING子句的話,它必須處在GROUP BY子句之后。還是上面的SQL語句,如果張三的SUM(OrderPrice)沒有超過500,那么張三組就不會顯示。
SQL語句的預(yù)編譯
在實踐中,有的SQL語句需要被反復(fù)使用,為了避免反復(fù)解析SQL語句產(chǎn)生的開銷,可以對需要復(fù)用的SQL語句進行預(yù)編譯,來提高數(shù)據(jù)庫操作的執(zhí)行效率。
//編譯復(fù)雜的SQL語句SQLiteStatement compiledSql = db.compileStatement(aSQL); //執(zhí)行SQLcompiledSql.execute();
//編譯復(fù)雜的SQL語句 SQLiteStatement compiledSql = db.compileStatement(aSQL); //執(zhí)行SQL compiledSql.execute();
課外小知識:所謂事務(wù)是用戶定義的一 個數(shù)據(jù)庫操作序列,這些操作要么全做要么全不做,是一個不可分割的工作單位。例如,在關(guān)系數(shù)據(jù)庫中,一個事務(wù)可以是一條SQL語句、一組SQL語句或整個 程序。 簡單舉個例子就是你要同時修改數(shù)據(jù)庫中兩個不同表的時候,如果它們不是一個事務(wù)的話,當***個表修改完,可是第二表改修出現(xiàn)了異常而沒能修改的情況下,就 只有第二個表回到未修改之前的狀態(tài),而***個表已經(jīng)被修改完畢。 而當你把它們設(shè)定為一個事務(wù)的時候,當***個表修改完,可是第二表改修出現(xiàn)了異常而沒能修改的情況下,***個表和第二個表都要回到未修改的狀態(tài)!這就是所 謂的事務(wù)回滾。
SQLiteOpenHelper
在SQLiteOpenHelper中,封裝了一個SqliteDatabase對象,使用著可以通過使用此類來進行數(shù)據(jù)庫的操作。
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的子類當中,必須有該構(gòu)造函數(shù) * @param context 上下文對象 * @param name 數(shù)據(jù)庫名稱 * @param factory * @param version 當前數(shù)據(jù)庫的版本,值必須是整數(shù)并且是遞增的狀態(tài) */ 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) { // 數(shù)據(jù)庫***構(gòu)造時,會調(diào)用該函數(shù),可以在這里構(gòu)造表、索引,等等 System.out.println("create a database"); //execSQL用于執(zhí)行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) { // 如果給定的當前數(shù)據(jù)庫版本高于已有數(shù)據(jù)庫版本,調(diào)用該函數(shù) System.out.println("upgrade a database"); } }
SQLiteOpenHelper的應(yīng)用
新建一個數(shù)據(jù)庫管理類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;//用于操作數(shù)據(jù)庫的對象 private DBHelper dh = null;//用于創(chuàng)建數(shù)據(jù)庫的對象 private String dbName = "note.db";//數(shù)據(jù)庫的名稱 private int dbVersion = 1;//數(shù)據(jù)庫的版本 public DBManager(Context context){ mContext = context; } public void open(){ try{ dh = new DBHelper(mContext, dbName, null, dbVersion);//建立數(shù)據(jù)庫 if(dh == null){ Log.v("msg", "is null"); return ; } mSQLiteDatabase = dh.getWritableDatabase();//以可寫方式打開數(shù)據(jù)庫 //dh.onOpen(mSQLiteDatabase); }catch(SQLiteException se){ se.printStackTrace(); } } public void close(){ mSQLiteDatabase.close();//關(guān)閉數(shù)據(jù)庫 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{ //結(jié)構(gòu)化方式操作 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{ //結(jié)構(gòu)化方式操作 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{ //結(jié)構(gòu)化方式操作 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; } }
獲取數(shù)據(jù)示例
private DBManager dm = null;// 數(shù)據(jù)庫管理對象 rivate Cursor cursor = null; dm = new DBManager(this);//數(shù)據(jù)庫操作對象 dm.open();//打開數(shù)據(jù)庫操作對象 cursor = dm.selectAll();//獲取所有數(shù)據(jù) cursor.moveToFirst();//將游標移動到***條數(shù)據(jù),使用前必須調(diào)用 int count = cursor.getCount();//個數(shù) ArrayListcontents = new ArrayList ();//圖片的所有集合 ArrayList imgs = new ArrayList ();//圖片的所有集合 ArrayList items = new ArrayList ();//標題的所有集合 ArrayList times = new ArrayList ();//時間的所有集合 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();//關(guān)閉數(shù)據(jù)操作對象
數(shù)據(jù)庫的并發(fā)問題
并發(fā)問題是使用數(shù)據(jù)庫過程中最容易碰到的問題,如果在開發(fā)中碰到了android.database.SQLException異常,并提示"database is locked",那很有可能是出現(xiàn)了數(shù)據(jù)庫的死鎖導(dǎo)致無法訪問。原因是Sqlite會對文件的讀寫進行加鎖,防止數(shù)據(jù)被破壞。而在Android框架層SqliteDatabase會對所有數(shù)據(jù)庫對象進行加鎖保護,一旦出現(xiàn)了指向同一個數(shù)據(jù)庫的多個SqliteDatabase對象同時在多個線程中被使用,那就跳脫了SqliteDatabase鎖保護,就會導(dǎo)致數(shù)據(jù)庫出現(xiàn)被鎖的異常。因此在實踐中,需要保證同時訪問數(shù)據(jù)庫的SqliteDatabase對象僅有一個。(可以使用全局變量來保存數(shù)據(jù)庫對象,在整個數(shù)據(jù)源對象中使用同一個連接)
課外小知識:在Android SDK中提供了工具Sqlite3,在shell模式下,可以對數(shù)據(jù)庫進行增刪改查。
cmd->adb shell ->sqlite3 <路徑>/<數(shù)據(jù)庫名> ->sqlite > select * from sqmple;
二、Android數(shù)據(jù)的云端服務(wù)
本質(zhì)上而言,云端存儲就是通過網(wǎng)絡(luò)將移動設(shè)備上的數(shù)據(jù)存儲到遠端 以上就是“Android的數(shù)據(jù)庫怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當前名稱:Android的數(shù)據(jù)庫怎么使用
轉(zhuǎn)載源于:http://weahome.cn/article/jphsdo.html