版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 電機(jī)學(xué)課件-清華大學(xué)
- 2024年全新裝修設(shè)計(jì)合作協(xié)議2篇
- 廣西大學(xué)附屬中學(xué)消防講座課件張琳敏課件
- 房屋擔(dān)保租賃合同(2篇)
- 2024年互聯(lián)網(wǎng)租賃平臺(tái)自行車退租退款及押金返還協(xié)議3篇
- 2025年貴州貨運(yùn)從業(yè)資格考試模擬考試題庫及答案解析
- 2025年福州貨運(yùn)從業(yè)資格試題答案解析
- 2025年武漢貨運(yùn)從業(yè)資格證考試模擬考試題及答案
- 2025年克拉瑪依b2考貨運(yùn)資格證要多久
- 2025年塔城貨運(yùn)資格證培訓(xùn)考試題
- 2023-2024學(xué)年湖北省武漢市洪山區(qū)九年級(jí)(上)期末物理試卷(含答案)
- 心理健康教育(共35張課件)
- 2024年直播銷售員(五級(jí))職業(yè)鑒定(重點(diǎn))備考試題庫300題(附答案)
- 欣賞物理學(xué)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 義務(wù)教育法主題班會(huì)課件
- 古詩詞誦讀《客至》課件+2023-2024學(xué)年統(tǒng)編版高中語文選擇性必修下冊(cè)
- 統(tǒng)編四上《中國古代神話故事》導(dǎo)讀課教學(xué)設(shè)計(jì)含反思
- 2024秋期國家開放大學(xué)本科《合同法》一平臺(tái)在線形考(任務(wù)1至4)試題及答案
- 碳排放管理員(中級(jí))職業(yè)鑒定考試題及答案
- 期權(quán)合同模板三篇
- 陜西延長石油集團(tuán)招聘筆試題庫2024
評(píng)論
0/150
提交評(píng)論