編輯:關於Android編程
前言
對於Android平台來說,系統內置了豐富的API來供開發人員操作SQLite,我們可以輕松的完成對數據的存取。下面就向大家介紹一下SQLite常用的操作方法。本篇文章主要用到SQLiteDatabase的一些函數。廢話少說,直接貼代碼!由於數據庫中操作的對象時Student類,因此我們看一下Student.java代碼:
[java]
package com.example.njupt.zhb.sqlite1;
import java.lang.String;
public class Student {
int _id;//與所建立的表對應
String name;
int age;
int grade;
String info;
public Student(String name,int age,int grade,String info){
this.name=name;
this.age=age;
this.grade=grade;
this.info=info;
}
public Student(){
}
}
從Student類的定義可以看出,它有5個成員變量,其中第一個成員變量是其‘主鍵’,這個名稱與數據庫中表的主鍵要完全一致。
下面我們看一下MainActivity.java代碼:
[java]
package com.example.njupt.zhb.sqlite1;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity implements OnClickListener{
public static final String DB_NAME="studentdata.db";
Button insertBtn;
Button updataGBtn;
Button updataABtn;
Button deleteBtn;
Button selectBtn;
Button displayBtn;
Button closeBtn;
ListView mListView;
SQLiteDatabase db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView=new ListView(this);
BtnInit();
OpenCreateDB();
}
public void OpenCreateDB(){
db = openOrCreateDatabase(DB_NAME, this.MODE_PRIVATE, null);
db.execSQL("DROP TABLE IF EXISTS students");
db.execSQL("CREATE TABLE IF NOT EXISTS students (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER,grade INTEGER, info VARCHAR)");
}
//插入數據到students表
public void InsertData(){
Student liSi =new Student("李四", 22, 87, "南京郵電大學 通信工程");
Student liHua = new Student("李華", 23, 78, "南京郵電大學 軟件工程");
db.execSQL("INSERT INTO students VALUES (NULL,?,?,?,?)", new Object[]{"張三",21,98,"南京郵電大學 電子信息工程"});
db.execSQL("INSERT INTO students VALUES (NULL,?,?,?,?)", new Object[]{liSi.name,liSi.age,liSi.grade,liSi.info});
db.execSQL("INSERT INTO students VALUES (NULL,'王五',19,99,'南京郵電大學 網絡工程')");
ContentValues cvOfLiHua = new ContentValues();
cvOfLiHua.put("name", liHua.name);
cvOfLiHua.put("age", liHua.age);
cvOfLiHua.put("grade", liHua.grade);
cvOfLiHua.put("info", liHua.info);
db.insert("students", null, cvOfLiHua);
Log.d("msg","插入結束");
Toast.makeText(this, "插入數據完成!", Toast.LENGTH_SHORT).show();
}
public void UpdateGrade(){
ContentValues cv = new ContentValues();
cv.put("grade", 85);
//更新數據,將李四的成績改為85分
db.update("students", cv, "name = ?", new String[]{"李四"});
Log.d("msg","李四的成績已更新");
Toast.makeText(this, "李四的成績已更新", Toast.LENGTH_SHORT).show();
}
public void UpdateAge(){
String sqlString="UPDATE students SET age=18 WHERE grade= 78";
db.execSQL(sqlString);
Log.d("msg","李華的年齡已更新");
Toast.makeText(this, "李華的年齡已更新", Toast.LENGTH_SHORT).show();
}
public void Delete(){
db.execSQL("DELETE FROM students WHERE name='張三'");
Log.d("msg","張三的信息已經被刪除");
Toast.makeText(this, "張三的信息已經被刪除", Toast.LENGTH_SHORT).show();
}
public void Select(){
List<String> list=new ArrayList<String>();
Cursor c = db.rawQuery("SELECT * FROM students WHERE grade >= ?", new String[]{"86"});
Log.d("msg","--------------大於86分的同學----------------------------");
while (c.moveToNext()) {
Student person = new Student();
person._id = c.getInt(c.getColumnIndex("_id"));
person.name = c.getString(c.getColumnIndex("name"));
person.grade=c.getInt(c.getColumnIndex("grade"));
person.age = c.getInt(c.getColumnIndex("age"));
person.info = c.getString(c.getColumnIndex("info"));
String string=""+person._id+" "+person.name+" "+person.grade+" "+person.age+" "+person.info;
list.add(string);
Log.d("msg",string);
}
c.close();
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,list);
mListView.setAdapter(adapter);
}
public void Display(){
List<String> list=new ArrayList<String>();
Cursor c = db.rawQuery("SELECT * FROM students", null);
while (c.moveToNext()) {
Student person = new Student();
person._id = c.getInt(c.getColumnIndex("_id"));
person.name = c.getString(c.getColumnIndex("name"));
person.grade=c.getInt(c.getColumnIndex("grade"));
person.age = c.getInt(c.getColumnIndex("age"));
person.info = c.getString(c.getColumnIndex("info"));
String string=""+person._id+" "+person.name+" "+person.grade+" "+person.age+" "+person.info;
list.add(string);
Log.d("msg",string);
}
c.close();
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,list);
mListView.setAdapter(adapter);
}
public void Close(){
db.close();
}
public void BtnInit(){
insertBtn=(Button)findViewById(R.id.insert);
updataGBtn=(Button)findViewById(R.id.updataG);
updataABtn=(Button)findViewById(R.id.updataA);
deleteBtn=(Button)findViewById(R.id.delete);
selectBtn=(Button)findViewById(R.id.select);
displayBtn=(Button)findViewById(R.id.display);
closeBtn=(Button)findViewById(R.id.close);
mListView=(ListView)findViewById(R.id.listview);
insertBtn.setOnClickListener(this);
updataABtn.setOnClickListener(this);
updataGBtn.setOnClickListener(this);
deleteBtn.setOnClickListener(this);
selectBtn.setOnClickListener(this);
displayBtn.setOnClickListener(this);
closeBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.insert:
InsertData();
break;
case R.id.updataA:
UpdateAge();
break;
case R.id.updataG:
UpdateGrade();
break;
case R.id.display:
Display();
break;
case R.id.delete:
Delete();
break;
case R.id.select:
Select();
break;
case R.id.close:
Close();
break;
}
}
}
我們一點點的看吧。
1. 布局:這個Activity和一般的Activity沒有太大的區別,它有7個按鈕控件和一個ListView控件(詳細布局見見面的布局文件)。BtnInit()函數是將控件與布局文件相關聯,並且設置相應的點擊事件處理。每一個點擊分別對應一個函數。
2. 數據庫的建立與打開:OpenCreateDB()函數完成。我們聲明一個成員變量SQLiteDatabasedb;通過執行系統的API函數openOrCreateDatabase打開或新建一個數據庫。通過執行db的execSQL函數執行創建表的一個SQL語句來創建students表。執行完之後,會在系統的/data/data/[PACKAGE_NAME]/databases目錄下出現數據庫文件
[圖1]
此時,相當於有一張students的空表:
students
_id[INTEGER]
name[VARCHAR]
grade[INTEGER]
age[INTEGER]
info[VARCHAR]
3. 插入操作:插入操作由函數InsertData()函數完成。我們用了三種方式插入數據。
(a)publicvoid execSQL (Stringsql)
(b)publicvoid execSQL (Stringsql,Object[]bindArgs)
(c)ContentValues與insert函數相結合的方式
執行完之後,我們可以通過點擊‘顯示當前數據庫’按鈕,來查看當前數據庫中的信息。
_id[INTEGER]
name[VARCHAR]
grade[INTEGER]
age[INTEGER]
info[VARCHAR]
1
張三
98
21
南京郵電大學電子信息工程
2
李四
87
22
南京郵電大學通信工程
3
王五
99
19
南京郵電大學網絡工程
4
李華
78
23
南京郵電大學軟件工程
4. 更新操作:UpdateAge()和UpdateGrade()兩個函數完成。體現了更新數據兩種方式:
(a) publicvoid execSQL (Stringsql)
(b) ContentValues與update函數相結合的方式
publicint update(Stringtable,ContentValuesvalues,StringwhereClause,String[]whereArgs)
(c) 當然,我們也可以用publicvoid execSQL (Stringsql,Object[]bindArgs)函數,將參數先用’?’代替,然後再bindArgs中賦值。
5. 刪除操作:由Delete函數完成。刪除操作可以直接用execSQL執行SQL語言。當然,也可以用publicint delete (Stringtable,StringwhereClause,String[]whereArgs)函數,和更新一樣,也有三種調用方式,在此不然贅述。
6. 查詢操作:由函數Select()函數完成。查詢操作時最復雜的操作。需要rawQuery函數,還有游標Cursor類的使用。首先,我們將我們的查找需求寫成SQL語言,然後執行數據庫的rawQuery函數,返回的是一個Cursor類型的對象。這個對象指向查詢結果集第一行。我們可以通過調用Cursor的moveToNext函數對查詢到的結果集進行遍歷。
查詢的函數還有:
db.rawQuery(String sql, String[] selectionArgs);
db.query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy);
db.query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy, Stringlimit);
db.query(String distinct, String table, String[] columns, Stringselection, String[] selectionArgs, String groupBy, String having, StringorderBy, String limit);
常用的Cursor的方法如下:
c.move(int offset); //以當前位置為參考,移動到指定行
c.moveToFirst(); //移動到第一行
c.moveToLast(); //移動到最後一行
c.moveToPosition(intposition); //移動到指定行
c.moveToPrevious(); //移動到前一行
c.moveToNext(); //移動到下一行
c.isFirst(); //是否指向第一條
c.isLast(); //是否指向最後一條
c.isBeforeFirst(); //是否指向第一條之前
c.isAfterLast(); //是否指向最後一條之後
c.isNull(intcolumnIndex); //指定列是否為空(列基數為0)
c.isClosed(); //游標是否已關閉
c.getCount(); //總數據項數
c.getPosition(); //返回當前游標所指向的行數
c.getColumnIndex(StringcolumnName);//返回某列名對應的列索引值
c.getString(intcolumnIndex); //返回當前行指定列的值
7.顯示操作:Display函數完成。我們首先獲得表中第一列的Cursor對象,然後逐步遍歷即可。我們可以通過如下語句獲得:
Cursor c = db.rawQuery("SELECT * FROM students",null);
總結:完成數據庫的操作,大多數情況下我們都可以用execSQL函數來執行SQL語言即可。附錄中列舉了常見的簡單SQL語言的操作。
程序運行界面:
[圖2]
布局文件為:
[html]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/insert"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="插入"/>
<Button
android:id="@+id/updataG"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="更新分數"/>
<Button
android:id="@+id/updataA"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="更新年齡"/>
<Button
android:id="@+id/delete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="刪除"/>
<Button
android:id="@+id/select"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查找"/>
<Button
android:id="@+id/display"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="顯示當前數據庫"/>
<Button
android:id="@+id/close"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="關閉"/>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
整個項目的源代碼:http://download.csdn.net/detail/nuptboyzhb/4515791
參考:
1.http://blog.csdn.net/liuhe688/article/details/6715983
2. http://www.cnblogs.com/rockdean/articles/2425843.html
附錄:
SQLite3支持的數據類型
一般數據采用的固定的靜態數據類型,而SQLite采用的是動態數據類型,會根據存入值自動判斷。SQLite具有以下五種數據類型:
1.NULL:空值。
2.INTEGER:帶符號的整型,具體取決有存入數字的范圍大小。
3.REAL:浮點數字,存儲為8-byte IEEE浮點數。
4.TEXT:字符串文本。
5.BLOB:二進制對象。
但實際上,sqlite3也接受如下的數據類型:
smallint 16 位元的整數。
interger 32 位元的整數。
decimal(p,s) p 精確值和 s 大小的十進位整數,精確值p是指全部有幾個數(digits)大小值,s是指小數點後有幾位數。如果沒有特別指定,則系統會設為 p=5; s=0 。
float 32位元的實數。
double 64位元的實數。
char(n) n 長度的字串,n不能超過 254。
varchar(n) 長度不固定且其最大長度為 n的字串,n不能超過 4000。
graphic(n) 和 char(n)一樣,不過其單位是兩個字元 double-bytes, n不能超過127。這個形態是為了支援兩個字元長度的字體,例如中文字。
vargraphic(n)可變長度且其最大長度為 n的雙字元字串,n不能超過 2000
date 包含了年份、月份、日期。
time 包含了小時、分鐘、秒。
timestamp 包含了年、月、日、時、分、秒、千分之一秒。
datetime 包含日期時間格式,必須寫成'2010-08-05'不能寫為'2010-8-5',否則在讀取時會產生錯誤!
sql語言的基本語句
(一)表的建立
關系數據庫的主要特點之一就是用表的方式組織數據。表是SQL語言存放數據、查找數據以及更新數據的基本數據結構。在SQL語言中,表有嚴格的定義,它是一種二維表,對於這種表有如下規定:
1)每一張表都有一個名字,通常稱為表名或關系名。表名必須以字母開頭,最大長度為30個字符。
2)一張表可以由若干列組成,列名唯一,列名也稱作屬性名。
3)表中的一行稱為一個元組,它相當於一條記錄。
4)同一列的數據必須具有相同的數據類型。
5)表中的每一個列值必須是不可分割的基本數據項。
注意:當用戶需要新的數據結構或表存放數據時,首先要生成一個表。
語法:
CREATE TABLE 表名 [表約束]
(列名1數據類型 [缺省值1,列約束1]
(列名2數據類型 [缺省值2,列約束2]
…
列名n 數據類型 [缺省值n,列約束n]
[TABLESPACE 表空間名稱]
[STORAGE (存貯的子句)]
[ENABLE 約束名]
[DISABLE 約束名]
(一)插入數據
當一個表新建成時,它裡面沒有數據,通過向表中扦入數據,建成表的實例。
語句句法:
INSERT INTO 表名[(列名1,…)]
VALUES(值1,值2,…,值n)
[子查詢];
假設有一張表Student如下所示:
NO
NAME
AGE
1001
A
12
1002
B
14
將新學生E增加到上表中,並按照表的結構將信息添加完整,需要如下語句:
INSERT INTO STUDENT VALUSE(1003, 'E',12);
(三)修改數據
對表中已有數據進行修改,語句句法:
UPDATE 表名SET列名1=表達式1,列名2=表達式2,…
WHERE 條件;
例如:對下表Student
NO
NAME
AGE
1001
A
12
1002
B
14
將B的年紀改為18;應該執行以下語句:
UPDATE STUDENT SET AGE=18 WHERE NAME='B';
(四)刪除數據
刪除表中已有數據,不能刪除不存在的數據。
語句句法:
DELETE FROM 表名 WHERE 條件;
例如:
對下面Student表進行刪除,要刪除其中年紀為12的學生;
NO
NAME
AGE
1001
A
12
1002
B
14
DELETE FROM STUDENT WHERE AGE=12;
(五)表結構的修改
在已存在的表中增加新列,語句句法:
ALTER TABLE 表名 ADD(新列名數據類型(長度));
例如:
ALTER TABLE STUDENT ADD (DEPARTMENT CHAR(8));
b.增加已有列的數據類型。
例如:
ALTER TABLE STUDENT MODIFY(NAME VARCHAR2(25));
(六)表的刪除
將已經存在的表刪除,語句句法:
DROP TABLE表名;
例如:
DROP TABLE EMP;
(七)查詢語句 (復雜)
SELECT命令的語法為:
SELECT [DISTINCT|ALL] {*|模式名.] {表名|視圖名|
快照名] .*…| {表達式[列別名]…} } [, [模式名. ] {表名|
視圖名|} .*…| 表達式[列別名] ]…
FROM [模式名.] {表名|視圖名|快照名} [@數據庫鏈名] [表別名]
[, [模式名.] {表名|視圖名|快照名} [@數據庫鏈名]
[表別名] ]…
[WHERE條件]
[START WITH條件 CONNECT BY條件]
[GROUP BY表達式[,表達式] …[HAVING條件]
[UNION|UNION ALL |INTERSECT|MINUS]SELECT命令
[ORDER BY{表達式|位置} [ASC|DESC] [, {表達式|位置[ASC|DESC]}]…]
例如:對於STUDENT表:
NO
NAME
AGE
1001
AE
12
1002
BT
14
(1) 查詢年紀為12的學生姓名;
SELECT STUDENT.NAME FROM STUDENT WHERE AGE=12;
(2) 查詢年紀在12至16歲之間的學生姓名;
SELECT STUDENT.NAME FROM STUDENT WHERE AGE BETWEEN 12 AND16;
(3) 查詢年紀不在12至16歲之間的學生姓名;
SELECT STUDENT.NAME FROM STUDENT WHERE AGE NOT BETWEEN 12AND 16;
(4) 查詢所有姓名以A開頭的學生的姓名;
SELECT STUDENT.NAME FROM STUDENT WHERE NAME LIKE 'A%';
(5) 列出所有學生年紀的和,年紀的平均值,最大值,最小值,最大值與最小值之間的差值;
SELECT AVG(AGE), SUM(AGE), MAX(AGE), MIN(AGE),MAX(AGE)-MIN(AGE);
(6) 將所有學生按學號順序升序排列;
SELECT * FROM STUDENT ORDER BY NO DESC;
(7) 將所有學生按學號順序升序排列;
SELECT * FROM STUDENT ORDER BY NO ASC;
概述:此部分內容涉及到android的自定義View、自定義屬性和Android圖形圖像處理的綜合應用:Bitmap、Path、Matrix、Canvas。圖片打碼以及如
背景隨著 Material Design設計概念的提出,使得很多的開發過程中對動畫和UI的優化越來越重要,其中一個重要的動畫就是Material Deisgn : Mat
今天給大家詳解一下Android中Activity的生命周期,我希望我的講解不像網上大多數文章一樣,基本都是翻譯Android API,過於籠統,相信大家看了,會有一點點
很多Android手機用戶都喜歡收集APK安裝包並保存在存儲卡內。可是,網上下載的APK大都以英文或亂碼命名,管理起來好不麻煩。那麼,無需借助PC,我們能否
前言:在上篇中,分析了MediaPlayer的從創建到setDataSo