SQLite語法與Android數據庫操作

190100183 8年前發布 | 27K 次閱讀 SQLite Android開發 移動開發

本篇文章可以學到以下內容:

  • SQLite操作以及SQL基本語法
  • Android中的數據庫操作(增刪改查)
  • Android中ContentProvide內容提供者和ContentResolver內容解析者的使用

學習android的小伙伴們在使用Android的SQLiteDatabase類進行數據庫操作的時候總會有一些力不從心,特別是對于初涉數據庫的小伙伴來說更是如此。

這是因為Android的SQLiteDatabase原本就不是依賴于Android而存在的,而是單獨的作為一個個體而存在的,有著自己特有的體系和語言,而這就是SQL語法了。

關于SQLite數據庫的理論知識網上一搜一大片,這里就不多說。SQLite是一個輕量型的數據庫,它對于大型數據庫來說功能少,因此只需要學習一些通用的SQL語法就能夠輕松掌握,而這些SQL語法對于其他的數據庫來說也是基本不變化的。

但SQLite有個缺點,那就是作為輕量級選手的它,如果要保存大量數據會力有不及,因此它在android中適合保存個人設置等沒有大量數據的信息。

好了,下面就是正式學習SQLite了,只有掌握了SQLite,掌握SQL語法,才能對Android中的數據庫操作運用自如。

SQLite的數據類型

與Java語言一樣,SQLite也有其特有的數據類型,當然相比MySQL來說只有5種數據類型算是很少了

NULL:空值相當于Java中的null
  INTEGER:帶符號的整型,相當于Java中的int型
  REAL:浮點數字,相當于Java中float/double型
  TEXT/VARCHAR:字符串文本,相當于Java中String類
  BLOB:二進制對象,相當于Java中的byte數組,用于存放圖片、聲音等文件

Sqlite3中的約束

SQLite的約束是什么呢?約束就是限定數據庫字段的條件,如果有個student數據表,它里面有一個age年齡的屬性字段,我們要求數據庫保存age這個字段的時候必須有值,不能為空,那么就可以設置為:"age INTEGER NOT NULL"。這句話的意思就是age字段是不能為空的整型

NOT NULL :非空
  UNIQUE : 唯一
  PRIMARY KEY :主鍵
  FOREIGN KEY : 外鍵
  CHECK :條件檢查
  DEFAULT : 默認

創建表,此時可對表里的結構和字段進行約束限定,將約束條件放在需要約束的字段之后

創建表

數據庫是數據庫,數據表是存放在數據庫中存放信息的容器,這點大家要區分。

語法:
  create table tabname(col1 type1 [not null][primary key], col2 type2[not null], ··· )
注:
    tabname為表名
    col1、col2為字段名字
    type1、type2為字段類型
    在[]中的約束條件是可以選的

例:

字段名       類型            長度           約束            說明
  id        INTEGER                       主鍵,自增長       編號
  name      VARCHAR           20            非空            姓名
  cid       INTEGER                                        所在班級
  age       INTEGER                      大于18且小于60     年齡
  gender    BIT                          默認為1,表示男     性別
  score     REAL                                           成績

create table student(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(20) NOT NULL,
    cid INTEGER,
    age INTEGER CHECK(age>18 and age<60),
    gender BIT DEFAULT(1),
    score REAL);

注:SQL中不區分大小寫

insert插入語句

數據庫的操作無非四大類,增刪改查這幾種,因此必須要掌握這幾種語句,insert增加也就是在數據表中添加信息

語法

insert into table1(field1, field2) values(value1, value2);
    語法詳解,在表名為table1的表的field1和field2字段分別插入value1和value2的值

例:

給student表中的各個字段插入值
  insert into student (name, cid, age, gender, score) values ('tom', 1, 20, 1, 80.0);

注:其實可以在student后面不帶有字段名,即name,cid···等,但如果不攜帶字段信息但看insert語句就無法直接明了的知道插入的value是給哪個字段賦值

update更新語句

語法:

update table1 set field1=value1 where 范圍
語法詳解:set后面是某個字段要更改的值,where表示限定field1字段value值在某個范圍內才需要修改
set表示要修改哪個字段的值
where表示修改字段值的范圍

例:

update student set name='jack' where name='tom';
 將student表中name字段中value為tom的值修改為jack

select查詢語句

select查詢方法可以說是在數據庫操作中使用最頻繁的操作了,無論是想獲取數據還是得知數據庫中的信息都必須使用select語句,同時select語句也算得上在SQL語法中最復雜的語句了。

語法:

基礎查詢:
    select * from table1 where 范圍
    語法詳解:* 代表通配符,即所有的字段
    select col1, col2, col3 from table1 where 范圍;
    查看col1, col2, col3字段的信息

    例:

        select * from student where name="jack"
        查詢student表中名字叫jack的所有字段的信息

        select id, name, score from student;
        查詢student表中所有學生的編號、名字、分數

限制查詢:

LIMIT關鍵字
select * from table1 LIMIT 5;
查詢table1中前5行中的數據,LIMIT關鍵字后面加數字可限定返回多少條數據
OFFSET關鍵字
 select * from table1 limit 5 offset 5;
 查詢table1中從第5行起的5行數據,OFFSET前面必須有LIMIT限定

例子:
select * from student limit 5;
查詢table1中前5行中的數據
select * from limit 5 offset 5;
查詢table1中從第5行起的5行數據

排序查詢:

ORDER BY關鍵字
 select * from table1 order by col1;
 查詢table1中所有數據,然后按照col1字段的升序排列(A-Z, 0-9)
  select * from table1 order by col1, col2;
  查詢table1中所有數據,然后先按照col1字段的排列,然后按照col2字段排序

  例子:
      select * from student order by score;
      查詢student中所有數據,然后按照score字段的升序排列
      select * from student order by name, score;
      查詢student中所有數據,然后先按照name字段的排列,然后按照score字段排序

  DESC關鍵字
  select * from student order by name, score DESC;
  查詢student中所有數據,然后先按照name字段的排列,然后按照name字段降序排序
  注:DESC為降序排序,即(Z-A,9-0),DESC是DESCENDING縮寫。
      DESC必須跟著ORDER BY關鍵字后面;
      DESC關鍵字只應用在直接位于其前面的列名;
      與DESC相反的是ASC(即ASCENDING),在升序排序時可指定ASC,但這一關鍵字并沒什么用處,因為升序是默認的

where過濾語句

where是過濾語句,數據會根據where自居的搜索條件進行過濾,一般情況下where跟在insert、delete、update、select后面。這是一個需要值得注意的語句,使用它能夠極大的提高查詢數據庫的效率,而使用delete語句如果不帶上過濾語句,則會把數據表中的所有信息刪除!

注:當ORDER BY關鍵字和where一起使用的時候,ORDER BY應該位于where后面,否則會報錯。

where子句后面跟著的是過濾條件,過濾條件可使用邏輯符號,即>、<、=、!=等等邏輯符號,與計算機通用的邏輯符合并沒有什么不同

例子:
    select * from student where score>70.0 ORDER BY name;
    查詢student表中成績大于70分的數據,同時按照名字升序排列

高級過濾:
    AND關鍵字:必須滿足前后兩個條件的數據
    select * from student where score>60 and score< 100;
    查詢student表中成績大于60分并且小于100分的數據
    OR關鍵字:只要滿足前后任意一個條件即可
    select * from student where score>90 or score<70;
    查詢student表中成績大于90分并且或者小于70分的數據

    AND和OR連用(and的優先級比or要高,兩者連用的時候最后在各自的條件中添加圓括號()進行分組)
    select * from student where (score>90 or score<70) and (age>19);

    BETWEEN關鍵字:
     select * from student where score between 70 and 80;
     查詢student表中分數在70至80分之間的數據

    IN關鍵字:用于指定范圍,范圍中的每個條件都進行匹配,IN由一組逗號分隔、括在圓括號中的合法值
    select * from student where name in('tom', 'Denesy');
    查詢student表中名字為tom和Denesy的數據

    注:在指定要匹配值得清單的關鍵字中,IN和OR功能相當
    IN可與and和or等其他操作符使用
    IN操作符比一組OR操作符執行快
    可以包含其他的SELECT語句

    NOT關鍵字:否定其后條件的關鍵字
    select * from student where not name='tom';
    獲取不包含名字為tom的信息
    select * from student where not score>80;
    獲取分數不是大于80分的信息

    空值檢查:
    select * from student where score is not null;
    查詢student表中score字段不為空的信息

delete刪除語句

語法:

delete from table1 where 范圍
語法詳解:從table中刪除某一范圍內的數據(只能一條一條的刪除,不能刪除某個字段中的值)
注:不要漏掉where,否則會清空整個表中的信息

例:

delete from student where name='tom';
  從student表中刪除名字為tom的信息

  delete from student where score< 90;
  從student表中刪除分數小于90分的信息

Android中的數據庫操作

Android中的數據庫操作其實只要掌握了上面的SQLite的基本知識,那么就很簡單了。

首先我們要創建一個類繼承自SQLiteOpenHelper,這個類的作用在于創建數據庫和數據表。在Android中已經幫我們封裝好了創建數據庫的方法,因此只要寫好創建數據表的語句就好了,而創建數據表的方法是使用原生的SQL語法,僅僅如此就讓你不得不學習SQL語法了。

MyDatabaseHelper代碼如下:

public class MyDatabaseHelper extends SQLiteOpenHelper {
        // 創建Book數據表語法
        public static final String CREATE_BOOK = "create table Book ("
                + "id integer primary key autoincrement, " 
                + "author text, "
                + "price real, " 
                + "pages integer, " 
                + "bookname text)";

        // 通過構造方法創建數據庫,其中name為數據庫名稱
        public MyDatabaseHelper(Context context, String name) {
            super(context, name, null, 1);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // 執行創建數據表的語法
            db.execSQL(CREATE_BOOK);
        }
    ···

    }

數據庫操作類

為了方便大家閱讀,這里將數據庫操作都封裝到一個類中,同時,將原本需要從外部傳入的數據也直接在類中寫入。

代碼如下:

public class BookDao {
    private MyDatabaseHelper helper;

    public BookDao(Context context) {
        helper = new MyDatabaseHelper(context, "BookStore.db");
    }
    /**
     * 添加數據到Book表中
     * @param values    傳入ContentValues
     * @return    返回新插入的行號,如果插入失敗返回-1
     */
    public long addData() {
        SQLiteDatabase database = helper.getReadableDatabase();
        // 使用anddroid封裝的SQL語法
        ContentValues values = new ContentValues();
        values.put("bookname", "The Da Vinci Code");
        values.put("author", "Dan Brown");
        values.put("pages", 454);
        values.put("price", 16.96);
        long insert = database.insert("Book", null, values);
        values.clear();
        values.put("bookname", "The Lost Symbol");
        values.put("author", "Dan Brown");
        values.put("pages", 510);
        values.put("price", 19.95);
        long insert1 = database.insert("Book", null, values);

        return insert;
    }

    /**
     * 更新Book表中的數據
     * @param values    傳入ContentValues
     * @param whereClause    需要更新的字段(where 語句限定)
     * @param whereArgs        需要更字段的字
     * @return    返回受影響的行
     */
    public int updateData() {
        SQLiteDatabase database = helper.getReadableDatabase();
        // 使用anddroid封裝的SQL語法
        ContentValues values = new ContentValues();
        values.put("price", 10.99);
        int update = database.update("Book", values,  "bookname = ?", new String[] { "The Da Vinci Code" });

        return update;
    }
    /**
     * 刪除Book中的數據
     * @param whereClause
     * @param whereArgs
     * @return    返回受影響的行
     */
    public int delete() {
        SQLiteDatabase database = helper.getReadableDatabase();
        // 使用anddroid封裝的SQL語法
        int delete = database.delete("Book", "pages > ?", new String[] { "500" });

        return delete;    
    }
    /**
     * 查詢Book表中的數據
     */
    public void query() {
        SQLiteDatabase database = helper.getReadableDatabase();
        // 使用原生SQL語法
        Cursor cursor = database.query("Book", null, "price=?", new String[]{"10.99"}, "bookname", "author='Baby lin'", "author");

        if (cursor.moveToFirst()) {
            do {
                String bookname = cursor.getString(cursor.getColumnIndex("bookname"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                double price = cursor.getDouble(cursor.getColumnIndex("price"));
                System.out.println("書名:" + bookname + "  作者:" + author + "  頁數" + pages + "   價格" + price);
            } while (cursor.moveToNext());
        }
        cursor.close();    
    }    
}

上面的代碼雖然有些長,但其功能卻很簡單,也就是實現了數據庫的增刪查改這是個方法。

首先我們看到每個方法都有這么一行代碼:

SQLiteDatabase database = helper.getReadableDatabase();

這一行代碼是通過MyDatabaseHelper使用父類SQLiteOpenHelper 中有兩個非常重要的實例方法,getReadableDatabase() 和getWritableDatabase()。這兩個方法都可以創建或打開一個現有的數據庫(如果數據庫已存在則直接打開,否則創建一個新的數據庫),并返回一個可對數據庫進行讀寫操作的對象。不同的是,當數據庫不可寫入的時候(如磁盤空間已滿)getReadableDatabase()方法返回的對象將以只讀的方式去打開數據庫,而getWritableDatabase()方法則將出現異常。

詳解addData()方法

其次,在addData()插入數據中有ContentValue這個類,這個類是用來存儲要插入數據表中的數據的。

舉個比較熟悉的例子,如ArrayList數據列表,我們可以在它里面存儲String或者HashMap<key, value>,而ContentValue就是類似ArrayList這樣的容器。

實際上ContentValue里面存儲的也是HashMap<key, value>。

通過ContentValue存儲數據,然后再使用Android封裝的insert方法,能夠解析其中的數據,然后保存到數據表中。

其實深入Android中的insert方法,可以看到Android只是將insert方法中的參數取出還原為SQL原生語句,然后保存到數據表中。那么怎么在Android使用原生的SQL方法呢?android在SQLiteDatabase對象中封裝了execSQL()方法,可直接使用,當然,execSQL()方法又有完全使用SQL語句,一半使用SQL語句一半使用Android參數的方法。下面是使用原生的SQL語句的代碼:

public long addData() {
    SQLiteDatabase database = helper.getReadableDatabase();

    // 使用原生SQL語法
    database.execSQL("insert into Book(bookname, author, pages, price) values('The Da Vinci Code', 'Dan Brown', 454, 16.96)");

    // 使用原生與android封裝方法,在values(?,?,?,?)有4個問號,
    // 代表的是占位符,分別對應后面的String數組中的四個值。
    database.execSQL("insert into Book(bookname, author, pages, price) values(?, ?, ?, ?)", 
            new String[]{"The Lost Symbol", "Dan Brown", "510", "19.95"});
    return 0;
}

我們看到如果使用原生的SQL語句來保存數據庫,代碼量減少了很多。但是android為什么推薦我們使用它封裝的方法呢?這是因為使用原生SQL語法不能獲取返回值,因此一但出現問題,會造成App崩潰;同時使用SQL語句的時候不能拼錯單詞或出現其他問題,否則也會崩潰。

同時我們看到使用SQL語句中保持的數字都是String,與數據表中的限定的值不同,這是因為在保存過程中只要數據類型正確,會自動將"510"還原為整數型。

詳解query()方法

除此之外,需要特別注意的便是查詢數據庫的query()方法

query(String table, String[] columns, String selection,

String[] selectionArgs, String groupBy, String having,

String orderBy) ;

這幾個參數的意思是:

table:指定查詢的表名,對應:from table_name
    columns:指定查詢的列名,對應select column1, column2
    selection:指定where 的約束條件,對應:where column = value
    selectionArgs:為where 中的占位符提供具體的值
    groupBy:指定需要group by 的列,對應:group by column
    having:value 對group by 后的結果進一步約束,對應:having column = value
    orderBy:指定查詢結果的排序方式,對應:order by column1, column2

這些參數中在SQL語法中都是有的,其后面對應的是相應的SQL語句。

group By這個關鍵字是歸組的意思,用于與 SELECT 語句一起使用,來對相同的數據進行分組。在 SELECT 語句中,GROUP BY 子句放在 WHERE 子句之后,放在 ORDER BY 子句之前。

也就是說如果使用GROUP BY子句,那么會見所有相同的字段的值合并為一條信息返回。

HAVING 子句允許指定條件來過濾將出現在最終結果中的分組結果。WHERE 子句在所選列上設置條件,而 HAVING 子句則在由 GROUP BY 子句創建的分組上設置條件。

為了獲取查詢結構,首先插入這些數據:

database.execSQL(
            "insert into Book(bookname, author, pages, price) values('The Da Vinci Code', 'Dan Brown', 454, 16.96)");
    database.execSQL(
            "insert into Book(bookname, author, pages, price) values('The Lost Symbol', 'Dan Brown', 510, 19.95)");
    database.execSQL(
            "insert into Book(bookname, author, pages, price) values('piao liu chuan shuo', 'Baby lin', 189, 12.99)");
    database.execSQL(
            "insert into Book(bookname, author, pages, price) values('lv bing xun chuan qi', 'Baby lin', 470, 10.99)");
    database.execSQL(
            "insert into Book(bookname, author, pages, price) values('bing yu huo zhi ge', 'Dan Brown', 624, 10.99)");
    database.execSQL(
            "insert into Book(bookname, author, pages, price) values('bing yu huo zhi ge', 'Dan Brown', 624, 10.99)");
    database.execSQL(
            "insert into Book(bookname, author, pages, price) values('wo yao du shu', 'Dan Brown', 510, 10.99)");

他們只有些許的區別,現在我們想查詢價格是10.99元,然后按照bookname進行歸組,找出組里作者是Baby lin的那條信息,最后按照author排序(實質只有一條信息,沒必要排序)。

這條信息由兩種寫法,一種是上面代碼演示的,一種用原生SQL,如下:

Cursor cursor = database.rawQuery(
            "select * from Book where price=10.99 group by bookname having author='Baby lin' order by author", null);

這兩種寫法都可以的到Cursor這個對象,然后通過Cursor獲得數據庫中的數據。

Cursor的用法相對固定,通過while遍歷,每次使用cursor.moveToNext()將游標移到下一行數據,如果能移動下一行數據則返回True,否則為false。

cursor.getString(int index)或者cursor.getInt(int index)傳入相應字段在數據表中的排序便能獲得在當前行的字段的值。

修改和刪除

修改和刪除就比前面兩種方法簡單多了。

修改update數據表的三種方法:

// 使用anddroid封裝的SQL語法
    ContentValues values = new ContentValues();
    values.put("price", 10.99);
    int update = database.update("Book", values, "bookname = ?", new String[] { "The Da Vinci Code" });
    // 使用原生SQL語法
    // database.execSQL("update Book SET price=10.99 where bookname='The Da
    // Vinci Code' ");
    // 使用原生與android封裝方法
    // database.execSQL("update Book SET price=? where bookname=? ", new String[] { "10.99", "The Da Vinci Code" });

刪除delete數據表的三種方法:

int delete = database.delete("Book", "pages > ?", new String[] { "500" });
    // 使用原生SQL語法

// database.execSQL("delete from Book where pages > 500");

// 使用原生與android封裝方法

// database.execSQL("delete from Book where pages > ?", new String[] { "500" });

以上就是android中對于數據庫操作的全部內容了!

內容提供者

研究完數據庫,那么與數據庫密切相關的內容提供者就不得不說說的,因為內容提供者也是依賴于數據庫的實現的。

內容提供者也就是將當前應用的數據提供出去給其他的app使用,這是一個很好的功能,可惜一般情況下沒有人會使用你的應用的信息,因為不知道是不是有陷阱。當然啦,支付寶、微博這些肯定會有人用的。

言歸正傳,我們來說說如何構建一個內容提供者,在這里以上一個項目的數據庫作為內容提供者。

創建一個類繼承自ContentProvider

ContentProvider有六個方法必須實現,他們是onCreate()和getType()以及數據庫的增刪查改四個方法,其中他們每個方法都會使用的Uri參數,這個參數是調用ContentResolver內容解析者的增刪改查方法時傳遞過來的。

我們首先創建MyContentProvider繼承ContentProvider。

然后在AndroidManifest.xml的application中添加內容提供者的注冊清單:

<provider
        android:name="com.example.databasecontentprovider.MyContentProvider"
        android:authorities="com.example.databasecontentprovider.provider"
        android:exported="true" >
    </provider>

其中android:name是ContentProvider的全類名,android:authorities 屬性中指定了該內容提供器的權限,android:exported表示該應用是否可供外部訪問。

然后回到MyContentProvider中,我們寫下以下代碼:

public class MyContentProvider extends ContentProvider{
    //定一個一個uri路徑匹配器
    private static final UriMatcher sUrimatcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static final int QUERYSUCESS = 0;  //ctrl+shift+X  變大寫   小寫加y
    private static final int INSERTSUCESS = 1;
    private static final int UPDATESUCESS = 2;
    private static final int DELETESUCESS = 3;
    private MyDatabaseHelper databaseHelper;

    static {
        sUrimatcher.addURI("com.example.databasecontentprovider.provider", "query", QUERYSUCESS);
        sUrimatcher.addURI("com.example.databasecontentprovider.provider", "insert", INSERTSUCESS);
        sUrimatcher.addURI("com.example.databasecontentprovider.provider", "update", UPDATESUCESS);
        sUrimatcher.addURI("com.example.databasecontentprovider.provider", "delete", DELETESUCESS);
    }

    @Override
    public boolean onCreate() {
        databaseHelper = new MyDatabaseHelper(getContext(), "BookStore.db");
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        int code = sUrimatcher.match(uri);
        if (code == QUERYSUCESS) {
            SQLiteDatabase readableDatabase = databaseHelper.getReadableDatabase();
            Cursor cursor = readableDatabase.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
            return cursor;
        } else {

            return null;
        }
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int code = sUrimatcher.match(uri);
        if (code == INSERTSUCESS){
            SQLiteDatabase readableDatabase = databaseHelper.getReadableDatabase();
            long insert = readableDatabase.insert("Book", null, values);
            Uri myUri = Uri.parse("com.youCanDoIt/" + insert);
            return myUri;
        } else {
            return null;
        }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int code = sUrimatcher.match(uri);
        if (code == DELETESUCESS) {
            SQLiteDatabase readableDatabase = databaseHelper.getReadableDatabase();
            int delete = readableDatabase.delete("Book", selection, selectionArgs);
            return delete;
        } else {
            return 0;
        }

    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int code = sUrimatcher.match(uri);
        if (code == UPDATESUCESS){
            SQLiteDatabase readableDatabase = databaseHelper.getReadableDatabase();
            int update = readableDatabase.update("Book", values, selection, selectionArgs);
            return update;
        } else {
            return 0;
        }
    }

}

其中UriMatcher這個實用類,我們可以當作是路徑匹配器,它添加訪問需要的路徑名。

在UriMatcher構造方法中有UriMatcher.NO_MATCH這個參數,表示的是Uri不匹配時返回的code

其中sUrimatcher.addURI("com.example.databasecontentprovider.provider", "query", QUERYSUCESS);這個方法,

第一個參數這是在AndroidManifest.xml中內容提供者注冊清單中的authorities,第二個參數需要匹配的路徑名,第三個參數這是路徑匹配時所返回的值。

那么query這個路徑該怎么訪問呢?

這時使用Uri url = Uri url = Uri.parse("content://com.example.databasecontentprovider.provider/query");就能夠解析這個路徑,其中content://是協議,跟 http://差不多。

設置好匹配器,也設置了訪問路徑,接下來就是提供給外部的權限方法了,現在我們先讓其他的app有對數據庫增刪查改的方法,那么就要重新MyContentProvider中增刪查改是個方法。

首先判斷sUrimatcher.match(uri)是否能夠匹配傳過來的uri,如果返回的值剛好就與定義好的值相等,那么就返回這里增刪查改方法中要返回的數據類型。

如public Cursor query(···)中要返回一個Cursor游標,那么就返回一個Cursor對象。

而public Uri insert( ···)最特殊,它要返回一個Uri,事實上這個Uri可以自定義,只需要符合相應規則就行,即com.xxxx即可,它最大的功能是讓外部應用得到是否成功執行插入數據的操作。

這樣一來,一個內容提供者就完成了。

總結一下,有以下幾個步驟:

1、定義內容提供者 定義一個類繼承contentProvider  
2、在清單文件里面配置一下 內容提供者
3、定義一個Urimatcher 
4、寫一個靜態代碼塊 ,添加匹配規則 
5、按照我們添加的匹配規則,暴露想暴露的方法

內容訪問者

內容提供者設置好之后,便要有訪問者,內容訪問者很簡單,只要得到Uri路徑,然后使用ContentResolver內容訪問者就好了。

我們新建一個MyContentResolver應用,添加增刪查改四個按鈕,然后在MainActivity中添加以下代碼:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button addData = (Button) findViewById(R.id.add_data);
        Button queryData = (Button) findViewById(R.id.query_data);
        Button updateData = (Button) findViewById(R.id.update_data);
        Button deleteData = (Button) findViewById(R.id.delete_data);

        addData.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Uri url = Uri.parse("content://com.example.databasecontentprovider.provider/insert");
                ContentValues values = new ContentValues();
                values.put("bookname", "A Clash of Kings");
                values.put("author", "George Martin");
                values.put("pages", 1040);
                values.put("price", 55.55);
                ContentResolver contentResolver = getContentResolver();
                Uri insert = contentResolver.insert(url, values);
                System.out.println(insert);
            }
        });

        queryData.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Uri url = Uri.parse("content://com.example.databasecontentprovider.provider/query");    
                ContentResolver contentResolver = getContentResolver();
                Cursor query = contentResolver.query(url, null, null, null, null);
                if (query != null) {
                    while (query.moveToNext()){
                        String autor = query.getString(1);
                        String prices = query.getString(2);
                        String pages = query.getString(3);
                        String bookname = query.getString(4);
                        System.out.println(autor + "   " + prices + "   " + pages +"   " + bookname);
                    }
                }
            }
        });

        updateData.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Uri url = Uri.parse("content://com.example.databasecontentprovider.provider/update");
                ContentValues values = new ContentValues();
                values.put("bookname", "A Storm of Swords");
                values.put("pages", 1216);
                values.put("price", 24.05);    
                ContentResolver contentResolver = getContentResolver();
                int update = contentResolver.update(url, values, null, null);
                System.out.println("更新了" + update + "條數據");
            }
        });

        deleteData.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Uri url = Uri.parse("content://com.example.databasecontentprovider.provider/delete");
                ContentResolver contentResolver = getContentResolver();
                int delete = contentResolver.delete(url, "bookname = ?", new String[]{"A Storm of Swords"});
                System.out.println("刪除了" + delete + "條數據");
            }
        });
    }

}

在這里,我們通過Activity中的getContentResolver()得到ContentResolver(),然后通過ContentResolver對象傳出想要修改或查詢的數據。當然在這里就不能夠寫SQL原生的語句了,只能夠按照Android的封裝的方法來走。

內容解析者的操作簡略為以下幾步:

1、通過Uri地址獲取Uri對象

2、通過getContentResolver()得到ContentResolver對象

3、通過ContentResolver對象進行增刪改查等動作,方法與數據庫操作基本相同。

 

 

 

來自:http://www.jianshu.com/p/06309249f2a0

 

 本文由用戶 190100183 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!