【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Day03-SQLite數(shù)據(jù)庫操作及ListView詳解_第1頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Day03-SQLite數(shù)據(jù)庫操作及ListView詳解_第2頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Day03-SQLite數(shù)據(jù)庫操作及ListView詳解_第3頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Day03-SQLite數(shù)據(jù)庫操作及ListView詳解_第4頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Day03-SQLite數(shù)據(jù)庫操作及ListView詳解_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】AndroidDay03-SQLite數(shù)據(jù)庫操作及ListView詳解

開源數(shù)據(jù)庫開源庫:OrmliteSQLite支持的字段類型及建表/blog/2118252SQLite查詢/Excellent/archive/2011/11/19/2254888.html一、Android中的數(shù)據(jù)庫的創(chuàng)建和操作

在Android中如果進(jìn)行大量的具有相同數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)時(shí),需要用到SQLite數(shù)據(jù)庫。

1.SQLite的特點(diǎn):

1)它是一個(gè)輕量級(jí)的數(shù)據(jù)庫,其實(shí)就是一個(gè)文件。當(dāng)然它的容量有有限的,畢竟是運(yùn)行在

手機(jī)Android系統(tǒng)中的。

2)它雖然小,但是它功能卻十分的強(qiáng)大,操作起來非常簡便。

2.SQLite的創(chuàng)建

第1步:創(chuàng)建一個(gè)類繼承SQLiteOpenHelper類,實(shí)現(xiàn)它的2個(gè)方法onCreate()和onUpgrade()。public

class

MyOpenHelper

extends

SQLiteOpenHelper

{

//本來構(gòu)造方法應(yīng)該有4個(gè)參數(shù),super調(diào)用的時(shí)候把參數(shù)寫死了,這里就只傳context參數(shù)了。

public

MyOpenHelper(Context

context)

{

/*

*

Parameters

context

上下文

name

SQLite數(shù)據(jù)庫名稱

factory

用于創(chuàng)建Cursor,一般寫null。

version

數(shù)據(jù)庫的版本號(hào)

*/

super(context,

"user.db",

null,

3); //調(diào)用父類的構(gòu)造方法初始化數(shù)據(jù)庫,在調(diào)用MYOpenHelper才去判斷數(shù)據(jù)庫是否存在。

}

/*

*

onCreate 數(shù)據(jù)庫第一次創(chuàng)建的時(shí)候會(huì)被調(diào)用

,如果數(shù)據(jù)庫已經(jīng)存在,不會(huì)被調(diào)用。

*

SQLiteDatabase 數(shù)據(jù)庫對(duì)象,可以執(zhí)行SQL語句。

*/

@Override

public

void

onCreate(SQLiteDatabase

db)

{

//此方法一般用來寫創(chuàng)建表的代碼

db.execSQL("create

table

info

(_id

integer

primary

key

autoincrement,name

varchar(20))");

//注意這里的sql語句是mysql中使用的sql語句的區(qū)別,int變成integer,autoincr

ement中間沒有下劃線

}

/*

*

onUpgrade 當(dāng)數(shù)據(jù)庫升級(jí)的時(shí)候調(diào)用。

*

oldVersion 新版本

*

newVersion 老版本

*

注意修改表結(jié)構(gòu)時(shí)不能添加重復(fù)字段

*/

@Override

public

void

onUpgrade(SQLiteDatabase

db,

int

oldVersion,

int

newVersion)

{

//此方法一般用來寫修改表結(jié)構(gòu)的代碼

db.execSQL("alter

table

info

add

phone

varchar(11)");

}

}

第2步:創(chuàng)建上面定義這個(gè)數(shù)據(jù)庫打開助手類的實(shí)例MyOpenHelper

myOpenHelper

=

new

MyOpenHelper(this);

第3步:利用數(shù)據(jù)庫打開助手類來創(chuàng)建數(shù)據(jù)庫(兩種方式)//getReadableDatabase()方法首先會(huì)調(diào)用getWritableDatabase()方法,如果數(shù)據(jù)庫在磁盤中的存儲(chǔ)空間已滿,就會(huì)以只讀方式打開數(shù)據(jù)庫。

SQLiteDatabase

readableDatabase

=

myOpenHelper.getReadableDatabase();

//建議使用

//getWritableDatabase()會(huì)以讀寫方式打開數(shù)據(jù)庫,如果磁盤中的存儲(chǔ)空間已滿,就會(huì)直接報(bào)錯(cuò)。

SQLiteDatabase

writableDatabase

=

myOpenHelper.getWritableDatabase();

數(shù)據(jù)庫創(chuàng)建成功后,會(huì)生成在/data/data/應(yīng)用程序包名/databases目錄下,即私有目錄。之前還學(xué)過files、shared_prefs目錄。

3.SQLite增刪改查操作

SQLite的增刪改查的流程是一致的,只是中間執(zhí)行的sql語句有所不同。

》通過數(shù)據(jù)庫助手打開助手返回一個(gè)數(shù)據(jù)庫對(duì)象SQLiteDatabase

》通過SQLiteDatabase對(duì)象執(zhí)行sql語句,2種方式。

》關(guān)閉數(shù)據(jù)庫。

下面就說上面的第2步操作,執(zhí)行sql。

*傳統(tǒng)方式:

SQLiteDatabase.execSQL("sql語句"[,點(diǎn)位符參數(shù)數(shù)組Object類型]);

這種方式的弊端就是容易將sql語句寫錯(cuò),如有中文字符、圓角字符等;而且execSQL的方法

沒有返回值,無法判斷sql操作是否成功。

*調(diào)用方法

SQLiteDatabase類定義了和sql語句相對(duì)應(yīng)的方法,雖然此方式減小了書寫sql語句出

錯(cuò)的機(jī)率,但是方法的參數(shù)比較多,用起來比較麻煩。

public

class

UserDaoImpl

implements

UserDao{

private

MyOpenHelper

sqlHelper;

//在構(gòu)造函數(shù)中創(chuàng)建SQLiteOpenHelper數(shù)據(jù)庫打開助手對(duì)象

public

UserDaoImpl(Context

context)

{

sqlHelper

=

new

MyOpenHelper(context);

}

//增加操作

/*

*

insert方法的第3個(gè)參數(shù)為

ContentValues類型,底層用的是map。存取的是要添加

*

的字段的名稱和值。

*/

@Override

public

long

add(UserBean

user)

{

//得到數(shù)據(jù)庫對(duì)象

SQLiteDatabase

database

=

sqlHelper.getWritableDatabase();

// database.execSQL("insert

into

info

values(null,?,?)",new

Object[]{,user.phone});

//利用SQLiteDatabase自帶的有返回值的方法來替代sql語句。

ContentValues

values

=

new

ContentValues();

values.put("name",

);

values.put("phone",

user.phone);

long

row_id

=

database.insert("info",

null,

values);

database.close();

return

row_id;

}

//刪除操作

@Override

public

long

del(String

name)

{

SQLiteDatabase

database

=

sqlHelper.getWritableDatabase();

// database.execSQL("delete

from

info

where

name

like

?",new

Object[]{name});

long

delete_rows

=

database.delete("info",

"name

like

?",

new

String[]{name});

//注意條件是沒有where關(guān)鍵字的

database.close();

return

delete_rows;

}

//更新操作

/*

*

update方法的第2個(gè)參數(shù)為

ContentValues類型,底層用的是map。鍵就是要更

*

改的字段,值就是修改后的字段對(duì)應(yīng)的值。

*/

@Override

public

int

update(UserBean

user)

{

SQLiteDatabase

database

=

sqlHelper.getWritableDatabase();

// database.execSQL("update

info

set

name

=

?,phone

=

?",new

Object[]{

+

"_修改",user.phone

+

"_修改"});

ContentValues

values

=

new

ContentValues();

values.put("phone",

user.phone

+

"_修改");

int

update_rows

=

database.update("info",

values,

"name=?",

new

String[]{});

database.close();

return

update_rows;

}

//查詢操作

/*

*query方法的第2參數(shù)為要查詢的項(xiàng)

*/

@Override

public

List<UserBean>

query()

{

SQLiteDatabase

database

=

sqlHelper.getWritableDatabase();

//創(chuàng)建一個(gè)List集合,返回?cái)?shù)據(jù)

List<UserBean>

list_user

=

new

ArrayList<UserBean>();

//得到查詢集合

//Cursor

cursor

=

database.rawQuery("select

name,phone

from

info",

null);

Cursor

cursor

=

database.query("info",

new

String[]{"name","phone"},

null,

null,

null,

null,

null);

if(cursor

!=

null

&

cursor.getCount()

>

0)

{

while(cursor.moveToNext())

{

//注意索引是相對(duì)于Cursor的,不是相對(duì)于數(shù)據(jù)庫的,第1列為name

String

name

=

cursor.getString(0);

//得到電話

String

phone

=

cursor.getString(1);

list_user.add(new

UserBean(name,phone));

}

return

list_user;

}

return

null;

}

}對(duì)于Cursor,特別要注意:Cursor得到之后,要調(diào)用一次moveToFirst或者moveToNext。否則就會(huì)將表頭誤認(rèn)為表的記錄。

cursorgetCount不為0,但是遍歷卻一個(gè)也沒有遍歷出來。/p/ba722c2271d64.SQLite數(shù)據(jù)庫的事物

事務(wù)

要么多條sql語句同時(shí)成功執(zhí)行,要么同時(shí)失敗

銀行轉(zhuǎn)賬

//開啟事物

db.beginTransaction();

try

{

//

轉(zhuǎn)賬

db.execSQL("update

account

set

money=

money-200

where

name=?",new

String[]{"李四"});

db.execSQL("update

account

set

money=

money+200

where

name=?",new

String[]{"張三"});

//設(shè)置事物已經(jīng)成功執(zhí)行

db.setTransactionSuccessful();

}

finally

{

//結(jié)束事物

db.endTransaction();

}

5.在linux命令行下執(zhí)行SQLite數(shù)據(jù)庫的命令

在多線程訪問數(shù)據(jù)庫的時(shí)候會(huì)出現(xiàn)這樣的異常:java.lang.IllegalStateException:Cannotperformthisoperationbecausetheconnectionpoolhasbeenclosed.或

java.lang.IllegalStateException:attempttore-openanalready-closedobject:SQLiteDatabase:或java.lang.IllegalStateException:attempttore-openanalready-closedobject:SQLiteDatabase:

6.數(shù)據(jù)庫查詢

1)如何從后往前查詢

方式1:寫sql語句,用desc關(guān)鍵字。

方式2:用sqlite自帶的query方法,得到cursor,操作cursor的指針

List<T>

list;

boolean

result

=

cursor.moveToLast();

if(result){

list.add(result);

}

while(cursor.moveToPrevious()){

...

list.add();

}

return

list;

2)查詢指定時(shí)間范圍內(nèi)的數(shù)據(jù)

存儲(chǔ)記錄的時(shí)候,存儲(chǔ)一個(gè)時(shí)間戳,寫sql的時(shí)候就好寫了。否則sql語句是不支持自定義的函數(shù)的。

6.Sqlite數(shù)據(jù)庫的幾大坑要注意:

1)database在app退出的時(shí)候記得關(guān)掉

2)cursor做完查詢后也要關(guān)掉

3)記得往數(shù)據(jù)庫存儲(chǔ)的時(shí)候用的什么類型,取的時(shí)候類型也要對(duì)應(yīng)。特別是在存儲(chǔ)long型時(shí)間戳?xí)r,定義表用的雖然是Integer類型,但是取的時(shí)候還是要

cursor.getLong來取。

4)數(shù)據(jù)庫的結(jié)構(gòu)發(fā)生變化:表的字段發(fā)生變化時(shí),一定要寫相關(guān)的升級(jí)代碼,不要直接跑程序。否則就會(huì)發(fā)生錯(cuò)誤。

二、Android中ListView的使用

1.ListView的使用流程:

第1步:創(chuàng)建有ListView的布局,并創(chuàng)建ListView的item項(xiàng)的UI。

第2步:得到要傳遞給適配器構(gòu)造函數(shù)的數(shù)據(jù),可以模擬或從網(wǎng)絡(luò)上解析獲取。

第3步:創(chuàng)建一個(gè)適配器對(duì)象,一般先會(huì)定義一個(gè)類繼承BaseAdapter這個(gè)抽象適配器類,實(shí)現(xiàn)

它的4個(gè)基本方法,并創(chuàng)建一個(gè)帶有數(shù)據(jù)參數(shù)的構(gòu)造函數(shù)。通過那4個(gè)方法將構(gòu)造函數(shù)

傳遞初始化的數(shù)據(jù)參數(shù)綁定給lListView的各個(gè)item項(xiàng)。

第4步:在java代碼中找到ListView,調(diào)用它的setAdapter方法關(guān)聯(lián)創(chuàng)建的適配器對(duì)象。

2.ListView的代碼實(shí)現(xiàn):

以網(wǎng)易新聞客戶端為例,來說明ListView的實(shí)現(xiàn)。

開發(fā)步驟:

第1步:設(shè)計(jì)UI

第2步:模擬適配器的數(shù)據(jù)(實(shí)際是從網(wǎng)絡(luò)解析的)

第3步:定義適配器類繼承BaseAdapter類,并創(chuàng)建適配器對(duì)象。

第4步:在java代碼中得到ListView,關(guān)聯(lián)適配器對(duì)象。

第1步:設(shè)計(jì)UI

主UI設(shè)計(jì):

子UI設(shè)計(jì):

第2步:模擬數(shù)據(jù)

創(chuàng)建一個(gè)bean包,在里面創(chuàng)建一個(gè)NewsBean類,定義3

個(gè)屬性

class

NewsBean{

public

Drawablepic;

//代表圖片

publicString

title,des,url;

//代表主題、內(nèi)容、鏈接地址

}

在工具類中創(chuàng)建一個(gè)靜態(tài)方法,返回List<NewsBean>的集合。

第3步:定義適配器(最重要、最復(fù)雜的一步)*********************************class

MyAdapter

extends

BaseAdapter

{

List<NewsBean>

news

=

null;

//定義構(gòu)造方法來初始化要綁定給適配器的數(shù)據(jù)集

public

MyAdapter(List<NewsBean>

news)

{

this.news

=

news;

}

//getCount返回ListView要顯示的Item條數(shù),一般返回?cái)?shù)據(jù)集的長度。

@Override

public

int

getCount()

{

return

news.size();

}

//getItem返回的是指定位置的數(shù)據(jù)集,并不是item本身。

@Override

public

Object

getItem(int

position)

{

return

news.get(position);

}

//getItemId返回的指定位置item項(xiàng)對(duì)應(yīng)的的id,一般保持與position一致。

@Override

public

long

getItemId(int

position)

{

return

position;

}

//綁定指定位置的item的視圖

@Override

public

View

getView(int

position,

View

convertView,

ViewGroup

pare

nt)

{

View

view

=

null;

/*

ListView的優(yōu)化,在ListView滾動(dòng)的時(shí)候,不會(huì)創(chuàng)建新的view,會(huì)引用前面第一

屏創(chuàng)建好的view對(duì)象。

*/

if(convertView

!=

null)

{

view

=

convertView;

}else

{

view

=

View.inflate(mContext,

R.layout.newsitem,

null);

/*

下面為另外兩種獲取item的view的方式。

view

=

LayoutInflater.from(mContext).inflate(R.layout.n

ewsitem,

null);

LayoutInflater

inflater

=

(LayoutInflater)

mContext.g

etSystemService(LAYOUT_INFLATER_SERVICE);

view

=

inflater.inflate(R.layout.newsitem,

null);

*/

}

//得到item視圖中的組件

ImageView

imgItem

=

(ImageView)

view.findViewById(R.id.img);

TextView

titleItem

=

(TextView)

view.findViewById(R.id.title);

TextView

desItem

=

(TextView)

view.findViewById(R.id.des);

//獲取指定position的對(duì)應(yīng)于數(shù)據(jù)集的數(shù)據(jù)。

NewsBean

newItem

=

news.get(position);

//為item組件綁定數(shù)據(jù)

imgItem.setImageDrawable(newItem.pic);

titleItem.setText(newItem.title);

desItem.setText(newItem.des);

return

view;

//最開始就寫好,不要忘了返回item的顯示視圖。

}

}

第4步:獲取ListView,創(chuàng)建并綁定適配器。//創(chuàng)建javaBean和適配器

List<NewsBean>

news

=

NewsUtils.getAllNews(mContext);

MyAdapter

adapter

=

new

MyAdapter(news);

//關(guān)聯(lián)listView的適配器

ListView

lv_news

=

(ListView)

findViewById(R.id.lv_news);

lv_news.setAdapter(adapter);

最終效果:

▉其它的一些適配器

它們都是非抽象類,可以直接用構(gòu)造函數(shù)來傳遞數(shù)據(jù)并創(chuàng)建對(duì)象。

■ArrayAdapter

它的常用的一個(gè)構(gòu)造方法

publicArrayAdapter(Contextcontext,intresource,inttextViewResourceId,T[]objects)

Parameters

context

上下文

resource

Item項(xiàng)的布局文件R.

textViewResourceId

Item項(xiàng)中TextView的id,指的是resource布局中的id.

objects

要顯示在item上的數(shù)據(jù),有多個(gè)數(shù)據(jù),就顯示多少

個(gè)item。

這種適配器比較粗糙,單純的用構(gòu)造函數(shù)來構(gòu)造的話,也不不能設(shè)置Itemview的樣

式,而且一個(gè)item只能給子布局中的一個(gè)TextView適配數(shù)據(jù)。

示例代碼及其效果:

mContext

=

this;

ListView

lv_arr

=

(ListView)findViewById(R.id.lv_arr);

Integer[]

items

=

new

Integer[100];

for(int

i

=

0;

i<items.length;

i++)

{

items[i]

=

i;

}

ArrayAdapterarrAdapter

=

newArrayAdapter<Object>(mContext,R.layout.item_arradapte

r,

R.id.tv_arrItem,

items);

lv_arr.setAdapter(arrAdapter);

效果圖:

■SimpleAdapter

與ArrayAdapter不同,它可以綁定多個(gè)TextView的數(shù)據(jù),它綁定的數(shù)據(jù)稍微復(fù)雜

點(diǎn)。

它的常用構(gòu)造方法

publicSimpleAdapter(Contextcontext,List<?extendsMap<String,?>>data,

intresource,String[]from,int[]to)

Parameters

context

上下文

data

List<?extendsMap<String,?>>類型的集合

resource

Item項(xiàng)的布局文件,至少要包含"to"參數(shù)中指定的

textview,但允許它有其它的組件。

from

map的鍵的名稱數(shù)組,它對(duì)應(yīng)的值會(huì)被”to”中對(duì)應(yīng)的textview

顯示

to

顯示"from"數(shù)組中map鍵對(duì)應(yīng)的值組件id數(shù)組

示例代碼:List<Map<String,String>>

data

=

newArrayList<Map<String,String>>();

for(int

i=

0;i

<40;i++)

{

Map<String,String>

map

=

newHashMap<String,String>();

map.put("name",

"張飛");

map.put("age",

"30");

data.add(map);

Map<String,String>

map1

=

newHashMap<String,String>();

map1.put(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論