day03數據庫及listview

經驗:1.sqlite表中的類型限定并不起作用,底層所有的數據都是String,為了節約手機內存

2.4.0版本以后數據庫在創建時會產生一個臨時文件

3.4.4版本以后虛擬機引用了ART模式,使速度更快

4.開發分包示例

1.android下數據庫的創建

什么時候使用數據庫做數據存儲? 有大量具有相同結構的數據需要存儲時。

mysql sql2008 sqlite 內置的 輕量級

SqliteOpenHelper:

1.創建一個類繼承SqliteOpenHelper,寫一個構造方法用來指定數據庫的名稱版本

2.實現兩個方法:

//構造方法 ,用來指定數據庫的名稱和版本號

public MySqliteOpenHelper(Context context) {

//context :上下文?? name: 數據庫文件的名稱? factory:用來創建cursor對象,默認傳null?? version:數據庫的版本,從android4.0之后只能升不能降。

super(context, "info.db", null, 2);

}

onCreate:數據庫第一次創建的時候調用onCreate方法, 特別適合做表結構的初始化

//數據庫第一次創建的時候調用onCreate方法, 特別適合做表結構的初始化

@Override

public void onCreate(SQLiteDatabase db) {

//做表結構的初始化就需要執行create table這樣的sql語句

//使用db執行sql語句

db.execSQL("create table info (_id integer primary key autoincrement ,name varchar(20) )");

}

//當數據庫的版本發生改變的時候會調用onUpgrade方法;特別適合做表結構的修改

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

//做表結構的修改需要執行sql語句

//????????? db.execSQL("alter table info add? phone varchar(20)");

System.out.println("oldVersion:"+oldVersion +"? newVersion: "+newVersion);

}

onUpgrade:當數據庫的版本發生改變的時候會調用onUpgrade方法;特別適合做表結構的修改

3.創建一個幫助類的實例化對象,并調用getReadableDatabase或getWritableDatabase方法,可以幫助我們創建或打開一個數據庫。

*******getReadableDatabase和getWritableDatabase區別:

getReadableDatabase:首先嘗試以讀寫的方式打開數據庫,如果磁盤空間滿了,會再次嘗試以只讀方式打開數據庫。

getWritableDatabase: 直接以讀寫方式打開數據庫,如果磁盤空間滿了,直接報錯。

2.Android下數據庫的第一種增刪改查方法(沒有返回值,適合查詢使用)

public class InfoDaoUtils {

private MySqliteOpenHelper mySqliteOpenHelper;

public InfoDaoUtils (Context context){

//1.創建幫助類對象

mySqliteOpenHelper = new MySqliteOpenHelper(context);

}

//增加方法

public void insert(UserBean bean){

//執行sql語句需要SqliteDatabase對象

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();//這個方法不要再構造函數中初始化,不方便數據庫操作

//3.執行sql語句? sql:sql語句?? bindArgs:?sql語句中占位符的值。

db.execSQL("insert into info(name,phone) values(?,?);", new Object[]{bean.name,bean.phone});

//4.關閉數據庫對象

db.close();

}

//刪除方法

public void delete(String name){

//執行sql語句需要SqliteDatabase對象

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.執行sql語句? sql:sql語句?? bindArgs:?sql語句中占位符的值。

db.execSQL("delete from info where name=?;", new Object[]{name});

//4.關閉數據庫對象

db.close();

}

//更新方法

public void update(UserBean newuserBean){

//執行sql語句需要SqliteDatabase對象

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.執行sql語句? sql:sql語句?? bindArgs:?sql語句中占位符的值。

db.execSQL("update info set phone=? where name=?;", new Object[]{newuserBean.phone,newuserBean.name});

//4.關閉數據庫對象

db.close();

}

//查詢方法

public void query(String name){

//執行sql語句需要SqliteDatabase對象

ArrayList list = new ArrayList();

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.執行sql語句? sql:sql語句?? selectionArgs:?sql語句中查詢條件的占位符的值。? 返回一個cursor游標結果集對象

Cursor cursor = db.rawQuery("select name,phone from info where name = ? ", new String[]{name});

//4.獲取結果集中的數據封裝到list中

if(cursor != null && cursor.getCount() > 0){//說明結果集中有數據

while(cursor.moveToNext()){//游標可以指向下一行

//解析一行數據

String name_str = cursor.getString(cursor.getColumnIndex("name"));//通過獲取字段編號再獲得字段值,不會弄錯編號

String phone_str = cursor.getString(cursor.getColumnIndex("phone"));

System.out.println("name : "+name_str + "? phone:"+phone_str);

UserBean userBean = new UserBean();

userBean.name = name_str;

userBean.phone = phone_str;

list.add(userBean);

}

//關閉游標對象

cursor.close();

}

//5.關閉數據庫對象

db.close();

}

3.Android下另一種增刪改查(谷歌封裝的API,有返回值,適合增刪改)

public class InfoDaoUtils2 {

private MySqliteOpenHelper mySqliteOpenHelper;

public InfoDaoUtils2 (Context context){

//1.創建幫助類對象

mySqliteOpenHelper = new MySqliteOpenHelper(context);

}

//增加方法

public boolean insert(UserBean bean){

//執行sql語句需要SqliteDatabase對象

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

// db.execSQL("insert into info(name,phone) values(?,?);", new Object[]{bean.name,bean.phone});

ContentValues values = new ContentValues();//底層封裝的是一個map

values.put("name", bean.name);

values.put("phone", bean.phone);

//3.執行sql語句

//table: 表名 nullColumnHack:可以為null values:封裝要添加的列的值 返回值:新添加這一行的行的id,如果是-1標示添加失敗

long result = db.insert("info", null, values);

//4.關閉數據庫對象

db.close();

if(result == -1){

return false;

}else{

return true;

}

}

//刪除方法

public int delete(String name){

//執行sql語句需要SqliteDatabase對象

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.執行sql語句

//table:表名 whereClause:刪除的條件 whereArgs:刪除條件占位符的值 返回值:成功刪除了多少行

int result = db.delete("info", "name=?", new String []{name});

//4.關閉數據庫對象

db.close();

return result;

}

//更新方法

public int update(UserBean newuserBean){

//執行sql語句需要SqliteDatabase對象

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.執行sql語句

ContentValues values = new ContentValues();

values.put("phone", newuserBean.phone);

//table: values:要更新的列 whereClause:更新條件 whereArgs:更新條件占位符的值 返回值:成功修改了多少行

int result = db.update("info", values, "name=?", new String[]{newuserBean.name});

//4.關閉數據庫對象

db.close();

return result;

}

//查詢方法

public void query(String name){

//執行sql語句需要SqliteDatabase對象

ArrayList list = new ArrayList();

//2.調用getReadableDatabase獲取一個SqliteDatabase對象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.執行sql語句

//table :表名 columns:查詢哪些列 ,如果傳null代表查詢所有列 selection:查詢的條件 selectionArgs:條件占位符的值 groupBy:按什么分組 having:分組的條件 orderBy :按什么排序

Cursor cursor = db.query("info", new String[]{"name","phone"}, "name = ?", new String[]{name}, null, null, "_id desc");

//4.獲取結果集中的數據封裝到list中

if(cursor != null && cursor.getCount() > 0){//說明結果集中有數據

while(cursor.moveToNext()){//游標可以指向下一行

//解析一行數據

String name_str = cursor.getString(cursor.getColumnIndex("name"));

String phone_str = cursor.getString(cursor.getColumnIndex("phone"));

System.out.println("name : "+name_str + " phone:"+phone_str);

UserBean userBean = new UserBean();

userBean.name = name_str;

userBean.phone = phone_str;

list.add(userBean);

}

//關閉游標對象

cursor.close();

}

//5.關閉數據庫對象

db.close();

}

}

4.數據庫事務(適合銀行操作,代碼塊中同時成功或者同時失敗)

1.事務對于查詢安全性的作用

//做轉賬業務,執行sql語句

public void transtationAccount(View v){

AccountSqliteOpenHelper accountSqliteOpenHelper = new AccountSqliteOpenHelper(this);

SQLiteDatabase db = accountSqliteOpenHelper.getReadableDatabase();

//開啟事務

db.beginTransaction();

try {

db.execSQL("update account set money= money-200 where name=?",new String[]{"李四"});

//模擬一個異常

int i = 100/0;

db.execSQL("update account set money= money+200 where name=?",new String[]{"張三"});

db.setTransactionSuccessful();//設置一個成功的標記

} finally {

db.endTransaction();//結束事務,要判斷事務是否成功,如果成功提交所有sql語句,如果失敗,回滾所有的sql語句

}

db.close();

}

2.事務對于提高數據庫批量操作效率的作用

在批量修改數據的時候,由于事務是在進行事務提交時將要執行的SQL操作一次性打開數據庫連接執行,其執行速度比逐條執行SQL語句的速度快了很多倍。因此當我們開發中遇到對數據庫的批量操作那么,使用事務是提高效率的重要原則。

publicvoidtestTransactionEfficient(){

PersonOpenHelper helper =newPersonOpenHelper(getContext(),"person",null, 2);

SQLiteDatabase database = helper.getWritableDatabase();

//?????------測試不使用事務時插入1w條數據耗時--------------------

longbeginTime = System.currentTimeMillis();

for(inti=0;i<10000;i++){

database.execSQL("insert into person(name,age,phone) values('text'+"+i+","+i+",'"+(1320000+i)+""+"')");

}

longendTime = System.currentTimeMillis();

System.out.println("不使用事務插入1w條數據耗時:"+(endTime-beginTime)+"毫秒");

//?????---------測試使用事務時耗時-----------------------

beginTime = System.currentTimeMillis();

database.beginTransaction();

for(inti=0;i<10000;i++){

database.execSQL("insert into person(name,age,phone) values('text'+"+i+","+i+",'"+(1320000+i)+""+"')");

}

database.setTransactionSuccessful();

database.endTransaction();

endTime = System.currentTimeMillis();

System.out.println("使用事務插入1w條數據耗時:"+(endTime-beginTime)+"毫秒");

5.獲取listview顯示的步驟

ListView 是一個在垂直滾動的列表中展示條目的控件。ListView上的條目內容來自于ListAdapter.

1.寫布局

2.activity中找到listview

3.寫一個類繼承BaseAdapter,實現4個方法。

getcount:告訴listview要顯示多少個條目

getItem:獲取listview指定position條目上的數據對象。 該方法不影響listview的展示,可以先不實現。

getItemId:獲取listview指定條目的id. 該方法不影響listview的展示,可以先不實現。

getView:告訴listview每個條目上顯示的內容。 listview每顯示一個條目getView方法就會被調用一次。 convertView:之前消失的那個item上的view對象

4.創建一個Adapter對象,設置給listview做條目的適配

listview.setAdapter(ListAdapter adapter)

6 常用獲取inflate的寫法

a.使用View.inflate

//需要創建一個復雜的布局轉換成一個view對象。 context :上下文 ,resource :要填充的布局資源的id root:將要填充的布局用root包裹起來返回,一般傳null

view = View.inflate(context, R.layout.item_news, null);//將一個布局文件填充成一個view對象

b.使用context.getSystemService

LayoutInflater layoutInfalter = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

view = layoutInfalter.inflate(R.layout.item_news, null);

c.使用LayoutInflate.from

LayoutInflater layoutInfalter = LayoutInflater.from(context);

view = layoutInfalter.inflate(R.layout.item_news, null);

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,844評論 2 372