摘要:所謂的,其實就是數據庫的基本操作,代表,代表,代表,則代表。數據庫好幫手上面已經給出了創建表并定義字段的方法,在別的地方它可以在終端或者腳本中運行,在世界里自然要在類中大展宏圖。
一 前言
經常聽到已經工作的程序員說每天的工作很無聊,總是一些CURD操作,沒什么技術含量,對,今天我們就要勇敢的探索一下這所謂的“無聊工作”--CURD,并想辦法讓它有趣起來。所謂的CURD,其實就是數據庫的基本操作,C代表create,U代表update,R代表read,D則代表delete。寫過后臺腳本的朋友對這個應該很熟悉,你就可以隨便翻翻啦,而不太了解數據庫操作的朋友,我在這里拋磚引玉,講一下怎么將內存中的數據保存到本地數據庫中,您看完后可以更加深入的去尋找一些資料學習,千萬要記得不管別人說什么無聊或者沒有技術含量,我們還是要一步一個腳印,堅持敲下去!
二 創建伴隨類前面說了我們要把這簡單的操作講的有趣些,那我就玩點套路,不直接講API,先來看一個類:
package com.aristark.note.database; public class NoteDbScheme { public static final class NoteTable{ public static final String name = "notes"; public static final class Cols{ public static final String UUID = "uuid"; public static final String TITLE = "title"; public static final String CONTENT = "content"; public static final String DATE = "date"; public static final String TAG = "tag"; } } }
類的名字叫NoteDbScheme,表明它是一個關于“計劃”的類,而且和database少不了干系,再來回憶Note這個類:
public class Note { private UUID uuid; private String title; private String content; private Date date; private String tag; public Note(){ uuid = UUID.randomUUID(); date = new Date(); } public UUID getUuid() { return uuid; } public Date getDate() { return date; } public void setTitle(String title) { this.title = title; } public String getTitle() { return title; } public void setContent(String content) { this.content = content; } public String getContent() { return content; } public void setTag(String tag) { this.tag = tag; } public String getTag() { return tag; } }
很容易看出來Note類里的私有字段和NoteDbScheme里常量的值是一致的,言下之意,我們可以從數據庫里取值賦給Note類中的字段,也可以把Note類中字段的值存入數據庫。再回憶一下之前我們是怎么用Note類的,我們在NoteLab創建了一個泛型為Note的ArrayList,然后通過NoteListActivity把它渲染到layout,也就是用戶的界面上,這樣看來,Note類隱隱約約好像作為一個溝通的橋梁(其實了解MVC模式的朋友應該很好理解)。
三 創建數據庫1.sql簡介:了解sql知識點這里
了解sqlite知識點這里
懶得看的就直接看這段sql語句,強行接受我的解釋就行了:
create table note( _int integer primary key autoincrement, uuid text, title text, content text, date text, tag text )
這段SQL語句的意思是,創建一個名叫“note”的表,包含6個字段,以第一個字段為例,_int為字段名,integer為字段類型,primary key autoincrement表示它是主鍵并自增。請大家記住這個套路。
2.SQLiteOpenHelper---數據庫好幫手
上面已經給出了創建表并定義字段的方法,在別的地方它可以在終端或者腳本中運行,在Android世界里自然要在類中大展宏圖。如果你的英語還可以請你打開Android->sdk>doc,在官方文檔中搜索SQLiteOpenHelper,你會發現你要做的這個類基本上已經幫你封裝好了,你要做的就是繼承它,并依照你的需求去敲敲打打就行。好,來寫代碼:
public class NoteBaseHelper extends SQLiteOpenHelper { @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
這里需要覆寫的onCreate方法就是我們創建表的地方,當NoteBaseHelper被實例化時,它會自動檢測數據庫中有沒有note這個表,如果沒有就調用該方法。所以我們把剛剛的sql語句寫進去:
@Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " +NoteDbScheme.NoteTable.name+"(" + "_id integer primary key autoincrement," +NoteDbScheme.NoteTable.Cols.UUID+"," +NoteDbScheme.NoteTable.Cols.TITLE+"," +NoteDbScheme.NoteTable.Cols.CONTENT+"," +NoteDbScheme.NoteTable.Cols.DATE+"," +NoteDbScheme.NoteTable.Cols.TAG +")" ); }
這里寫的和上面其實是完全一樣的,只不過我們是用NoteDbScheme中的常量代替了字符串而已,這樣做的好處是如果以后表中的字段需要變更的話我們只要在NoteDbScheme中變更就行了,而不需要動這里的代碼。另一個需要覆寫的onUpgrade在數據庫需要更新的時候調用。我們再添加兩個常量來標記數據庫的名字和版本:
public class NoteBaseHelper extends SQLiteOpenHelper { public static final int VERSON = 1; public static final String DATABASE_NAME = "NoteBase"; @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " +NoteDbScheme.NoteTable.name+"(" + "_id integer primary key autoincrement," +NoteDbScheme.NoteTable.Cols.UUID+"," +NoteDbScheme.NoteTable.Cols.TITLE+"," +NoteDbScheme.NoteTable.Cols.CONTENT+"," +NoteDbScheme.NoteTable.Cols.DATE+"," +NoteDbScheme.NoteTable.Cols.TAG +")" ); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
最后別忘了創建NoteBaseHelper的構造方法:
public NoteBaseHelper(Context context) { super(context,DATABASE_NAME,null,VERSON); }
DATABASE_NAME和VERSON就是我們剛才定義過的。
3.創建數據庫和表
前面我們分析了,我們用NoteLab類將數據渲染到前臺用戶界面,同樣的我們也用它來與后臺數據庫交互,先來回顧一下NoteLab類:
public class NoteLab { private static NoteLab sNoteLab; //for the global use private ArrayListnotes; private NoteLab(Context context){ notes = new ArrayList (); //generate 100 Note Objects // for (int i=0;i<100;i++){ // Note note = new Note(); // note.setTitle("this is title "+i); // note.setContent("this is content "+i+"balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala "); // notes.add(note); // } } public static NoteLab getNoteLab(Context context){ if (sNoteLab == null){ sNoteLab = new NoteLab(context); } return sNoteLab; } public ArrayList getNotes() { return notes; } public void addNote(Note note){ notes.add(note); } public Note getNote(UUID uuid){ for (Note note : notes){ if (note.getUuid().equals(uuid)){ return note; } } return null; } }
每個方法的用途都可以通過命名來體現,實在看不懂的翻看我前面兩篇文章就行了。
public SQLiteDatabase getWritableDatabase ()
Added in API level 1
Create and/or open a database that will be used for reading and writing. The first time this is called, the database will be opened and onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int) and/or onOpen(SQLiteDatabase) will be called.
Once opened successfully, the database is cached, so you can call this method every time you need to write to the database. (Make sure to call close() when you no longer need the database.) Errors such as bad permissions or a full disk may cause this method to fail, but future attempts may succeed if the problem is fixed.
Database upgrade may take a long time, you should not call this method from the application main thread, including from ContentProvider.onCreate().
Returns
a read/write database object valid until close() is called
Throws
SQLiteException if the database cannot be opened for writing
這是Google官方文檔中關于SQLiteOpenHelper類的一個方法,用來創建或者打開一個數據庫,好,我們就在NoteLab類的構造方法中來使用這個方法:
public class NoteLab { private static NoteLab sNoteLab; //for the global use private ArrayListnotes; private Context context; private SQLiteDatabase database; private NoteLab(Context context){ notes = new ArrayList (); database = new NoteBaseHelper(context).getWritableDatabase(); //generate 100 Note Objects // for (int i=0;i<100;i++){ // Note note = new Note(); // note.setTitle("this is title "+i); // note.setContent("this is content "+i+"balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala balabalabalabalalabalabalabalabalala "); // notes.add(note); // } } ...... }
這樣我們在創建NoteLab的同時也就創建了NoteBase數據庫和note表。好,編譯,運行,這時候打開Android Device Monitor(Android Studio問號左邊的小機器人按鈕)
在Android中,所有App的本地數據庫都在data->data下,找到我們這個應用的包名之下的databases目錄下,我們看到了NoteBase數據庫,說明我們成功創建了note表!
插入數據無非就是將一組鍵值對提交給操作數據的API,而這里的鍵值對就是以ContentValues來組裝的(大家在這里一定要去官方文檔搜到這個類好好讀一下,不然可能會在這里卡住),我們現在在NoteLab類中添加如下方法:
private ContentValues getValues(Note note){ ContentValues values = new ContentValues(); values.put(NoteDbScheme.NoteTable.Cols.UUID,note.getUuid().toString()![圖片描述][5]); values.put(NoteDbScheme.NoteTable.Cols.TITLE,note.getTitle()); values.put(NoteDbScheme.NoteTable.Cols.CONTENT,note.getContent()); values.put(NoteDbScheme.NoteTable.Cols.DATE,note.getDate().toString()); values.put(NoteDbScheme.NoteTable.Cols.TAG,note.getTag()); return values; }
代碼很容易讀,put方法接受的就是key--value對,這里再一次用到了NoteDbScheme類,是不是覺得很奇妙很方便?現在我們改寫之前的addNote方法:
public void addNote(Note note){ // notes.add(note); ContentValues values = getValues(note); database.insert(NoteDbScheme.NoteTable.name,null,values); }
這里著重掌握insert方法,第一個參數接受將要插入的表名,第三個參數就是我們需要組裝的ContentValues,第二個參數是關于插入空記錄的相關設置,大家可以去查看文檔。好,編譯,運行:
點擊右上角加號,輸入數據幾組數據
很遺憾我現在并不會檢驗數據是否寫進表,不管了繼續寫代碼,去把數據庫的記錄讀出來!
寫了這么多有點寫不下去了,不知道你是不是也看不下去了,你心里肯定想這太冗雜了(誰讓咱們使用java寫android呢,隨便寫寫就感覺好多的樣子,但是換個角度想我們可以對外吹我們的代碼量很多啊哈哈,雖然并沒有什么卵用)。扯店犢子,大家回顧一下C語言中的指針和java語言中的引用(句柄?handle?指針?),或者是數組中的索引,我們會發現這些重要的抽象對于我們操作數據是很有用的,對了,在Android我們有Cursor(中文意思是游標,對,就是游標卡尺的那個游標),我們可以變相的把它理解為一個帶有指針的數組,我們可以通過操作“指針”來獲取其中的數組。每次我們通過一定的條件進行數據庫查詢時,返回的就是一個Cursor, 它可以依次指向查詢結果記錄的每一條。不小心又說多了,來,寫代碼,在NoteLab中創建如下方法:
private Cursor queryNote(String whereClause,String[] whereArgs){ Cursor cursor = database.query( NoteDbScheme.NoteTable.name, null, whereClause, whereArgs, null, null, null ); return cursor }
我們需要關注的是query方法,第一個參數是要查詢的表名,第三個參數和第四個參數對應SQL語句中的where(少年,去回顧一下sql語句吧)。
但Cursor還不不太利于我們的操作,來粉飾一波,在Cursor外面再裹上一層,因此就有了CursorWrapper,創建一個類讓它繼承CursorWrapper:
public class NoteCursorWrapper extends CursorWrapper { public NoteCursorWrapper(Cursor cursor){ super(cursor); } }
變更剛剛的queryNote方法:
private CursorWrapper queryNote(String whereClause, String[] whereArgs){
Cursor cursor = database.query( NoteDbScheme.NoteTable.name, null, whereClause, whereArgs, null, null, null ); return new CursorWrapper(cursor);
}
之所以說CursorWrapper方便,是因為我們將查詢返回的Cursor傳入該類之后,可以很方便的把查詢的值取出來,還是看代碼:
......
......
別看了,太晚了,寫之前沒料到會有這么長。明天繼續寫。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65586.html
摘要:業務層,業務層,是最為核心的一層。對于和的狀態保存恢復也通過處理。對于的綁定操作和命令操作都是暴露的,也易于測試。需要注意的是標簽的節點中要使用到根節點中標簽里設置的的話需要這樣設置抽象類中設置了和注解,只起到清晰提醒作用。 原文發表于:Rockos blog(rocko.xyz)] - MVVM_Android-CleanArchitecture 前言 Architecture is...
閱讀 3140·2021-09-28 09:36
閱讀 3685·2021-09-08 09:45
閱讀 1793·2021-09-01 10:43
閱讀 3470·2019-08-30 12:44
閱讀 3345·2019-08-29 17:25
閱讀 1370·2019-08-29 11:03
閱讀 1992·2019-08-26 13:36
閱讀 693·2019-08-23 18:24