Android中SQLiteDatabase操作【附源码】
像我們做的很多應(yīng)用程序及網(wǎng)站一樣,基本都是對數(shù)據(jù)庫進(jìn)行增刪改查來實(shí)現(xiàn)相應(yīng)的功能。那么Android開發(fā)也一樣,不過由于在移動客戶端應(yīng)用,所以不會像sql server、mysql那么復(fù)雜,Android應(yīng)用程序支持本地?cái)?shù)據(jù)庫,SQLiteDatabase,通俗的說就是在手機(jī)上我們開發(fā)的應(yīng)用程序中創(chuàng)建一個數(shù)據(jù)庫,然后我們可以在手機(jī)上對我們的數(shù)據(jù)進(jìn)行增刪改查,不過這并不是絕對的,像前段時間我們開發(fā)一個小組OA,需要多人使用,功能簡單,但需要大家連接到一個數(shù)據(jù)庫中進(jìn)行數(shù)據(jù)讀取操作,所以這種情況下就要考慮到用mysql這樣的數(shù)據(jù)庫,最后選擇了用php操作后臺,然后然會Android進(jìn)行數(shù)據(jù)處理,不過對于我們使用的2G網(wǎng)絡(luò)很多程度上對速度還是有影響的。緩存這一塊接觸的比較少,計(jì)劃等到Android這一塊學(xué)的差不多了再研究其稍底層的一些開發(fā)。
這篇文章主要向大家分享如何操作SQLiteDatabase。
當(dāng)然首先我們要了解SQLiteDatabase,它具有很多優(yōu)點(diǎn):
SQLite特性:
????1.?輕量級
????2.?獨(dú)立性
????3.?隔離性
????????SQLite數(shù)據(jù)庫中所有的信息(比如表、視圖、觸發(fā)器等)都包含在一個文件內(nèi),方便管理和維護(hù)。
????4.?跨平臺
????5.?多語言接口
????6.?安全性
????????SQLite數(shù)據(jù)庫通過數(shù)據(jù)庫級上的獨(dú)占性和共享鎖來實(shí)現(xiàn)獨(dú)立事務(wù)處理。這意味著多個進(jìn)程可以在同一時間從同一數(shù)據(jù)庫讀取數(shù)據(jù),但只有一個可以寫入數(shù)據(jù)。在某個進(jìn)程或現(xiàn)成向數(shù)據(jù)庫執(zhí)行操作之前,必須獲得獨(dú)占鎖定。在發(fā)出獨(dú)占鎖定以后,其他的讀或?qū)懖僮鲗⒉粫侔l(fā)生。
?
創(chuàng)建和打開數(shù)據(jù)庫:
????openOrCreateDatabase(),自動檢測是否存在這個數(shù)據(jù)庫,如果存在則打開,否則創(chuàng)建,創(chuàng)建成功會返回一個SQLiteDatabase對象,否則拋出異常FileNotFoundException:
????????mSQLiteDatabase?=?this.openOrCreateDatabase("abc.db",MODE_PRIVATE,null);
創(chuàng)建表:
????execSQL():
????????String?Create_Table?=?"Create?table?table1...";
????????mSQLiteDatabase.execSQL(Create_Table);
?
向表中添加數(shù)據(jù):
????insert方法需要把數(shù)據(jù)打包到ContentValues中,ContentValues其實(shí)就是一個Map,Key值是字段名稱,Value值是字段的值。通過ContentValues的put方法就可以把數(shù)據(jù)放到ContentValues對象中,然后插入到表中:
????????ContentValue?cv?=?new?ContentValues();
????????cv.put(table_num,1);
????????mSQLiteDatabase.insert(TABLE_NAME,null,cv);
?
從表中刪除數(shù)據(jù):
????delete():
????????mSQLiteDatabase.delete("abc.db","where...",null);
?
修改表數(shù)據(jù):
????update():
????????ContentValues?cv?=?new?ContentValues();
????????cv.put(TABLE_NUM,3);
????????mSQLiteDatabase.update("table1",cv,"num"+"="+Integer.toString(0),null);
?
??當(dāng)然,插入、刪除和修改操作也可以通過execSQL(sql)方法來實(shí)現(xiàn)。
?
關(guān)閉數(shù)據(jù)庫:
????????mSQLiteDatabase.close();
?
刪除指定表:
????????mSQLiteDatabase.execSQL("DROP?TABLE?table1");
?
刪除數(shù)據(jù)庫:
????????this.deleteDatabase("abc.db");
?
查詢表中的某條記錄:
????????通過Cursor類實(shí)現(xiàn),當(dāng)使用SQLiteDatabase.query()方法時,會得到一個Cursor對象,Cursor指向的就是每一條數(shù)據(jù)。它提供了很多有關(guān)查詢的方法:
????????????
| 方法?? | 說明 |
| move | 以當(dāng)前位置為參考,將Cursor移動到指定的位置,成功返回true |
| moveToPosition | 將Cursor移動的指定的位置,返回boolean |
| moveToNext | 將Cursor向前移動一個位置,返回boolean |
| moveToLast | 將Cursor向后移動一個位置,返回boolean |
| moveToFirst | 將Cursor移動的第一行,返回boolean |
| isBeforeFirst | 返回Cursor是否指向第一項(xiàng)數(shù)據(jù)之前 |
| isAfterLast | 返回Cursor是否指向最后一項(xiàng)數(shù)據(jù)之后 |
| isClosed | 返回Cursor是否關(guān)閉 |
| isFirst | 返回Cursor是否指向第一項(xiàng)數(shù)據(jù) |
| isLast | 返回Cursor是否指向最后一項(xiàng)數(shù)據(jù) |
| isNull | 返回指定位置的值是否為null |
| getCount | 返回總的數(shù)據(jù)項(xiàng)數(shù) |
| getInt | 返回當(dāng)前行指定索引的數(shù)據(jù) |
?例如:
????????Cursor?cur?=?mSQLiteDatabase.rawQuery("select?*?from?table",null);
????????if(cur?!=?null)
????????{
????????????if(cur.moveToFirst())
????????????{
????????????????do{
????????????????????int?numColumn?=?cur.getColumnIndex("num");
????????????????????int?num?=?cur.getInt(numColumn);
??????????????????}while(cur.moveToNext());
????????????}
????????}
?????使用SQLiteDatabase數(shù)據(jù)庫后要及時關(guān)閉,否則可能會拋出SQLiteException異常。????
?
上面的方法像大部分基礎(chǔ)語法書上一樣直接執(zhí)行sql語句的形式,那么在Android中為了簡化用戶操作以及提高性能,Android系統(tǒng)提供了SQLiteOpenHelper,封裝了常用的數(shù)據(jù)庫操作方法。利用它我們可以很輕松的完成對數(shù)據(jù)庫的增刪改查。
?首先我們創(chuàng)建一個DBHelper類繼承SQLiteOpenHelper,用它來完成數(shù)據(jù)庫的初始化工作:創(chuàng)建數(shù)據(jù)庫,創(chuàng)建表等操作。
他包含一些借口方法,在下面的注釋里已經(jīng)注釋的很詳細(xì),就不再羅嗦。
1 package com.example.core; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 import android.database.sqlite.SQLiteOpenHelper; 7 8 public class DBHelper extends SQLiteOpenHelper{ 9 10 public DBHelper(Context context) { 11 //創(chuàng)建數(shù)據(jù)庫名為march_test.db的數(shù)據(jù)庫 12 super(context,"march_test.db",null,1); 13 } 14 15 /* (non-Javadoc) 16 * 數(shù)據(jù)庫每次被創(chuàng)建時調(diào)用 17 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase) 18 */ 19 @Override 20 public void onCreate(SQLiteDatabase db) { 21 //創(chuàng)建數(shù)據(jù)庫表 22 String create_sql = "CREATE TABLE student(id integer primary key autoincrement," + 23 "name varchar(20),age integer not null)"; 24 db.execSQL(create_sql); 25 } 26 27 /* (non-Javadoc) 28 * 版本號發(fā)生變化時執(zhí)行 29 * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int) 30 */ 31 @Override 32 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 33 // TODO Auto-generated method stub 34 String alter_sql = "ALTER TABLE student ADD money integer"; 35 db.execSQL(alter_sql); 36 } 37 38 }通過實(shí)例化這個類,可以創(chuàng)建一個名為march_test.db的數(shù)據(jù)庫。包含數(shù)據(jù)表student。可以文件系統(tǒng)中看到:
路徑為data/data/包名/databases/數(shù)據(jù)庫名:
?
這種db格式的數(shù)據(jù)庫在這里給大家推薦一個非常好用的工具SQLite Expert Professional,非常好用,在網(wǎng)上也很好找到。他mysql workbench等數(shù)據(jù)庫可視化工具一樣給我們提供了可視化數(shù)據(jù)庫操作,軟件界面如下:
我們可以把我們創(chuàng)建的表在文件系統(tǒng)中導(dǎo)出來然后放到這里查看。
?
首先要聲明我們要操作的數(shù)據(jù)類型類:
1 package com.example.sqllite; 2 3 public class Student{ 4 5 private Integer id; 6 private String name; 7 private Integer age; 8 9 public Student(Integer id, String name, Integer age) { 10 super(); 11 this.id = id; 12 this.name = name; 13 this.age = age; 14 } 15 16 public Student(String name , Integer age){ 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 22 public Integer getId() { 23 return id; 24 } 25 26 public void setId(Integer id) { 27 this.id = id; 28 } 29 30 public String getName() { 31 return name; 32 } 33 34 public void setName(String name) { 35 this.name = name; 36 } 37 38 public Integer getAge() { 39 return age; 40 } 41 42 public void setAge(Integer age) { 43 this.age = age; 44 } 45 46 @Override 47 public String toString() { 48 return "Student [id=" + id + ", name=" + name + ", age=" + age + "]"; 49 } 50 51 }?
?
下面要編寫對數(shù)據(jù)庫的增刪改查類,它繼承我們上面創(chuàng)建的SQLiteOpenHelper為基類的DBHelper類:
1 package com.example.core; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.content.Context; 7 import android.database.Cursor; 8 import android.database.sqlite.SQLiteDatabase; 9 10 import com.example.sqllite.Student; 11 12 /** 13 * @author fanchangfa 14 *數(shù)據(jù)庫操作類 15 *增刪改查 16 *獲取分頁查詢數(shù)據(jù) 17 *獲取表中記錄總數(shù) 18 */ 19 public class DbServer{ 20 21 private DBHelper dbhelper; 22 23 public DbServer(Context context){ 24 this.dbhelper = new DBHelper(context); 25 } 26 27 /** 28 * 增加信息 29 * @param student 增加的學(xué)生信息 30 */ 31 public void add(Student student){ 32 SQLiteDatabase db = dbhelper.getWritableDatabase(); 33 db.execSQL("insert into student(name , age) values(?,?)", 34 new Object[]{student.getName(),student.getAge()}); 35 } 36 37 /** 38 * 刪除信息 39 * @param id 要刪除的學(xué)生id 40 */ 41 public void delete(Integer id){ 42 SQLiteDatabase db = dbhelper.getWritableDatabase(); 43 db.execSQL("delete from student where id = ?",new Object[]{id}); 44 } 45 46 /** 47 * 修改指定id的學(xué)生信息 48 * @param stu 包括修改學(xué)生的id,以及修改的信息 49 */ 50 public void alter(Student stu){ 51 SQLiteDatabase db = dbhelper.getWritableDatabase(); 52 db.execSQL("update student set name=?,age=? where id=?", 53 new Object[]{stu.getName(),stu.getAge(),stu.getId()}); 54 } 55 56 /** 57 * 查找信息 58 * @param id 要查找的學(xué)生id 59 */ 60 public Student find(Integer id){ 61 SQLiteDatabase db = dbhelper.getReadableDatabase(); 62 Cursor cursor = db.rawQuery("select * from student where id = ?",new String[]{id.toString()}); 63 64 if(cursor.moveToFirst()) //如果查詢結(jié)果集中有數(shù)據(jù),將游標(biāo)指向第一條記錄 65 { 66 int sid = cursor.getInt(cursor.getColumnIndex("id")); 67 String name = cursor.getString(cursor.getColumnIndex("name")); 68 int age = cursor.getInt(cursor.getColumnIndex("age")); 69 70 return new Student(sid , name , age); 71 } 72 73 cursor.close(); 74 75 return null; 76 } 77 78 /** 79 * 分頁查詢數(shù)據(jù) 80 * @param start 分頁開始記錄數(shù) 81 * @param end 分頁結(jié)束記錄數(shù) 82 * @return 查詢結(jié)果集 83 */ 84 public List<Student> page(int start , int end){ 85 SQLiteDatabase db = dbhelper.getReadableDatabase(); 86 List<Student> page = new ArrayList<Student>(); 87 Cursor cur = db.rawQuery("select id,name,age from student order by id limit ?,?", 88 new String[]{String.valueOf(start),String.valueOf(end)}); 89 90 while(cur.moveToNext()){ 91 int id = cur.getInt(cur.getColumnIndex("id")); 92 String name = cur.getString(cur.getColumnIndex("name")); 93 int age= cur.getInt(cur.getColumnIndex("age")); 94 page.add(new Student(id,name,age)); 95 } 96 97 cur.close(); 98 99 return page; 100 } 101 102 /** 103 * 返回指定分頁數(shù)據(jù) 104 * @param start 105 * @param end 106 * @return Cursor型數(shù)據(jù) 107 */ 108 public Cursor curpage(int start , int end){ 109 SQLiteDatabase db = dbhelper.getReadableDatabase(); 110 Cursor cur = db.rawQuery("select id as _id,name,age from student order by id limit ?,?", 111 new String[]{String.valueOf(start),String.valueOf(end)}); 112 113 cur.moveToFirst(); 114 115 return cur; 116 } 117 118 /** 119 * 獲取表記錄總數(shù) 120 * @return 121 */ 122 public long getCount(){ 123 SQLiteDatabase db = dbhelper.getReadableDatabase(); 124 125 Cursor cur = db.rawQuery("select count(*) from student",null); 126 cur.moveToFirst(); 127 128 long count = cur.getLong(0); 129 130 cur.close(); 131 132 return count; 133 } 134 135 /** 136 * 執(zhí)行事務(wù) 137 */ 138 public void transaction(){ 139 SQLiteDatabase db = dbhelper.getWritableDatabase(); 140 db.beginTransaction(); 141 142 try{ 143 db.execSQL("update student set age = 21 where id =5"); 144 db.execSQL("update student set age= 22 where id=6"); 145 db.setTransactionSuccessful(); 146 //事務(wù)默認(rèn)有commit、rollback,默認(rèn)為False,即非提交狀態(tài),需要設(shè)置為commit 147 } 148 finally{ 149 db.endTransaction(); 150 } 151 152 } 153 }?
?
具體操作代碼中已經(jīng)注釋完善,可以進(jìn)行試驗(yàn)。
下面要對其進(jìn)行測試:
編寫測試單元如下:
1 package com.example.test; 2 3 import java.util.List; 4 5 import com.example.core.DbServer; 6 import com.example.sqllite.Student; 7 8 import android.test.AndroidTestCase; 9 import android.util.Log; 10 11 /** 12 * @author fanchangfa 13 * 數(shù)據(jù)庫操作單元測試 14 * 測試DbServer中數(shù)據(jù)的增刪改查 15 * 16 */ 17 public class DbServerTest extends AndroidTestCase{ 18 19 //控制臺打印信息標(biāo)志 20 private static final String TAG = "SQLtest"; 21 22 /** 23 * 添加數(shù)據(jù)測試 24 */ 25 public void addTest(){ 26 DbServer dbserver = new DbServer(this.getContext()); 27 for(int i = 0 ; i<20 ; i++) 28 { 29 Student stu = new Student("fanchangfa"+i,20); 30 dbserver.add(stu); 31 } 32 } 33 34 public void deleteTest(){ 35 DbServer dbserver = new DbServer(this.getContext()); 36 dbserver.delete(2); 37 } 38 39 public void alterTest(){ 40 DbServer dbserver = new DbServer(this.getContext()); 41 Student stu = dbserver.find(3); 42 stu.setName("liuzihang"); 43 stu.setAge(25); 44 dbserver.alter(stu); 45 } 46 47 /** 48 * 測試數(shù)據(jù)庫查找 49 * 根據(jù)提供id返回記錄結(jié)果 50 */ 51 public void findTest(){ 52 DbServer dbserver = new DbServer(this.getContext()); 53 Student stu = dbserver.find(5); 54 Log.i(TAG, stu.toString()); 55 } 56 57 /** 58 * 數(shù)據(jù)庫查找分頁測試 59 */ 60 public void findpage(){ 61 DbServer dbserver = new DbServer(this.getContext()); 62 List<Student> students = dbserver.page(0, 8); 63 64 for(Student stu : students){ 65 Log.i(TAG,stu.toString()); 66 } 67 68 } 69 70 /** 71 * 執(zhí)行事務(wù)測試 72 */ 73 public void transactionTest(){ 74 DbServer dbserver = new DbServer(this.getContext()); 75 dbserver.transaction(); 76 } 77 78 }?
經(jīng)驗(yàn)證,沒有問題,由于此文件系統(tǒng)和操作比較麻煩,我將自己寫的實(shí)例放到這里共大家下載,此實(shí)例中包括數(shù)據(jù)庫的操作以及SQLite中事物的使用,以及將在下一篇寫的關(guān)于ListView顯示數(shù)據(jù)的幾種方法,界面雖然很難看,不過這只是demo,希望多多諒解,有問題多多交流。希望這里會是我們擁有共同愛好的程序員們相互交流共同進(jìn)步的平臺,而不是只是為了增加訪問量而將文章放在這里。
?
轉(zhuǎn)載于:https://www.cnblogs.com/fanchangfa/archive/2012/08/21/2649710.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Android中SQLiteDatabase操作【附源码】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知识汇集
- 下一篇: 【Android】自带Theme