使用嵌入式關係型SQLite數據庫存儲數據java
除了可使用文件或SharedPreferences存儲數據,還能夠選擇使用SQLite數據庫存儲數據。mysql
在Android平臺上,集成了一個嵌入式關係型數據庫—SQLite,android
一、SQLite3支持 NULL、INTEGER、REAL(浮點數字)、TEXT(字符串文本)和BLOB(二進制對象)數據類型,雖然它支持的類型雖然只有五種,但實際上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等數據類型,只不過在運算或保存時會轉成對應的五種數據類型。程序員
二、SQLite最大的特色是你能夠保存任何類型的數據到任何字段中,不管這列聲明的數據類型是什麼。例如:能夠在Integer字段中存放字符串,或者在布爾型字段中存放浮點數,或者在字符型字段中存放日期型值。sql
三、但有一種狀況例外:定義爲INTEGER PRIMARY KEY的字段只能存儲64位整數, 當向這種字段中保存除整數之外的數據時,將會產生錯誤。數據庫
四、另外, SQLite 在解析CREATE TABLE 語句時,會忽略 CREATE TABLE 語句中跟在字段名後面的數據類型信息,以下面語句會忽略 name字段的類型信息:數組
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))緩存
SQLite能夠解析大部分標準SQL語句,如:app
查詢語句:select * from 表名 where 條件子句 group by 分組字句 having ... order by 排序子句dom
如:select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分頁SQL與mysql相似,下面SQL語句獲取5條記錄,跳過前面3條記錄
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入語句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘傳智’,3)
更新語句:update 表名 set 字段名=值 where 條件子句。如:update person set name=‘傳智‘ where id=10
刪除語句:delete from 表名 where 條件子句。如:delete from person where id=10
1.建立Android工程
Project name: db
BuildTarget:Android2.2
Application name: 數據庫應用
Package name: com.jbridge.db
Create Activity: DBActivity
Min SDK Version:八、
2. Person實體
package com.jbridge.domain; import android.R.string; public class Person { private Integer id; private String name; private Short age; public Person(String name, Short age) { this.name = name; this.age = age; } public Person(Integer id, String name, Short age) { super(); this.id = id; this.name = name; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Short getAge() { return age; } public void setAge(Short age) { this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } }
3.編寫DataBaseOpenHelper類
DataBaseOpenHelper繼承自SQLiteOpenHelper類。咱們須要建立數據表,必須重寫onCreate(更新時重寫onUpgrade方法)方法,在這個方法中建立數據表。
package com.jbridge.service; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseOpenHelper extends SQLiteOpenHelper { // 類沒有實例化,是不能用做父類構造器的參數,必須聲明爲靜態 private static String dbname = "zyj"; private static int version = 1; public DataBaseOpenHelper(Context context) { // 第一個參數是應用的上下文 // 第二個參數是應用的數據庫名字 // 第三個參數CursorFactory指定在執行查詢時得到一個遊標實例的工廠類,設置爲null,表明使用系統默認的工廠類 // 第四個參數是數據庫版本,必須是大於0的int(即非負數) super(context, dbname, null, version); // TODO Auto-generated constructor stub } public DataBaseOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), age INTEGER)"); } // onUpgrade()方法在數據庫版本每次發生變化時都會把用戶手機上的數據庫表刪除,而後再從新建立。 // 通常在實際項目中是不能這樣作的,正確的作法是在更新數據庫表結構時,還要考慮用戶存放於數據庫中的數據不會丟失,從版本幾更新到版本幾。 @Override public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) { db.execSQL("DROP TABLE IF EXISTS person"); onCreate(db); } }
4.編寫PersonService類
PersonService類主要實現對業務邏輯和數據庫的操做
package com.jbridge.service; import java.util.ArrayList; import java.util.Currency; import java.util.List; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.jbridge.domain.Person; public class PersonService { private DataBaseOpenHelper dbOpenHelper; // private Context context; public PersonService(Context context) { // this.context = context; dbOpenHelper = new DataBaseOpenHelper(context); } public void save(Person person) { SQLiteDatabase database = dbOpenHelper.getWritableDatabase(); database.beginTransaction(); database.execSQL("insert into person(name,age)values(?,?)", new Object[] { person.getName(), person.getAge() }); // database.close();能夠不關閉數據庫,他裏面會緩存一個數據庫對象,若是之後還要用就直接用這個緩存的數據庫對象。但經過 // context.openOrCreateDatabase(arg0, arg1, arg2)打開的數據庫必須得關閉 database.setTransactionSuccessful(); database.endTransaction(); } public void update(Person person) { SQLiteDatabase database = dbOpenHelper.getWritableDatabase(); database.execSQL( "update person set name=?,age=? where personid=?", new Object[] { person.getName(), person.getAge(), person.getId() }); } public Person find(Integer id) { SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); Cursor cursor = database.rawQuery( "select * from person where personid=?", new String[] { String.valueOf(id) }); if (cursor.moveToNext()) { return new Person(cursor.getInt(0), cursor.getString(1), cursor.getShort(2)); } return null; } public void delete(Integer... ids) { if (ids.length > 0) { StringBuffer sb = new StringBuffer(); for (Integer id : ids) { sb.append('?').append(','); } sb.deleteCharAt(sb.length() - 1); SQLiteDatabase database = dbOpenHelper.getWritableDatabase(); database.execSQL( "delete from person where personid in(" + sb.toString() + ")", ids); } } public List<Person> getScrollData(int startResult, int maxResult) { List<Person> persons = new ArrayList<Person>(); SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); Cursor cursor = database.rawQuery( "select * from person limit ?,?", new String[] { String.valueOf(startResult), String.valueOf(maxResult) }); while (cursor.moveToNext()) { persons.add(new Person(cursor.getInt(0), cursor.getString(1), cursor.getShort(2))); } return persons; } // 獲取分頁數據,提供給SimpleCursorAdapter使用。 public Cursor getRawScrollData(int startResult, int maxResult) { List<Person> persons = new ArrayList<Person>(); SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); return database.rawQuery( "select personid as _id ,name,age from person limit ?,?", new String[] { String.valueOf(startResult), String.valueOf(maxResult) }); } public long getCount() { SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); Cursor cursor = database.rawQuery("select count(*) from person", null); if (cursor.moveToNext()) { return cursor.getLong(0); } return 0; } }
下面是使用 insert()、delete()、update()和query()方法實現的業務類
package com.jbridge.service; import java.util.ArrayList; import java.util.Currency; import java.util.List; import android.R.string; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.jbridge.domain.Person; public class OtherPersonService { private DataBaseOpenHelper dbOpenHelper; // private Context context; public OtherPersonService(Context context) { // this.context = context; dbOpenHelper = new DataBaseOpenHelper(context); } public void save(Person person) { SQLiteDatabase database = dbOpenHelper.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put("name", person.getName()); contentValues.put("age", person.getAge()); database.insert("person", null, contentValues); } public void update(Person person) { SQLiteDatabase database = dbOpenHelper.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put("name", person.getName()); contentValues.put("age", person.getAge()); database.update("person", null, "personid=?", new String[] { String.valueOf(person.getId()) }); } public Person find(Integer id) { SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); Cursor cursor = database.query("person", new String[] { "personid", "name", "age" }, "personid=?", new String[] { String.valueOf(id) }, null, null, null); if (cursor.moveToNext()) { return new Person(cursor.getInt(0), cursor.getString(1), cursor.getShort(2)); } return null; } public void delete(Integer... ids) { if (ids.length > 0) { StringBuffer sb = new StringBuffer(); String[] strIds = new String[ids.length]; // for (Integer id : ids) { // sb.append('?').append(','); // } for (int i = 0; i < strIds.length; i++) { sb.append('?').append(','); strIds[i] = String.valueOf(ids[i]); } sb.deleteCharAt(sb.length() - 1); SQLiteDatabase database = dbOpenHelper.getWritableDatabase(); database.delete("person", "personid in(" + sb.toString() + ")", strIds); } } public List<Person> getScrollData(int startResult, int maxResult) { List<Person> persons = new ArrayList<Person>(); SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); Cursor cursor = database.query("person", new String[] { "personid", "name", "age" }, null, null, null, null, "personid desc", startResult + "," + maxResult); while (cursor.moveToNext()) { persons.add(new Person(cursor.getInt(0), cursor.getString(1), cursor.getShort(2))); } return persons; } public long getCount() { SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); Cursor cursor = database.query("person", new String[] { "count(*)" }, null, null, null, null, null); if (cursor.moveToNext()) { return cursor.getLong(0); } return 0; } }
5.編寫測試類
編寫一個針對PersonService的測試類,測試PersonService類中的各個方法是否正確
package com.jbridge.db; import java.util.List; import com.jbridge.domain.Person; import com.jbridge.service.OtherPersonService; import com.jbridge.service.PersonService; import android.test.AndroidTestCase; import android.util.Log; public class PersonServiceTest extends AndroidTestCase { private static String TAG = "PersonServiceTest"; // OtherPersonService personService = new // OtherPersonService(this.getContext()); // //不能夠這麼寫,由於Android把context環境變量是在PersonServiceTest實例化後給他的 public void testSave() throws Exception { PersonService personService = new PersonService(this.getContext()); // personService.save(new Person("老豬", (short) 11)); for (int i = 0; i < 10; i++) { personService.save(new Person("你" + i, (short) (i + 10))); } } public void testFind() throws Exception { PersonService personService = new PersonService(this.getContext()); Person person = personService.find(1); Log.i(TAG, person.toString()); } public void testUpdate() throws Exception { PersonService personService = new PersonService(this.getContext()); Person person = personService.find(1); person.setName("lv"); personService.update(person); } public void testDelete() throws Exception { PersonService personService = new PersonService(this.getContext()); personService.delete(1, 2, 3); } public void testGetCount() throws Exception { PersonService personService = new PersonService(this.getContext()); Log.i(TAG, String.valueOf(personService.getCount())); } public void testGetScrollData() throws Exception { PersonService personService = new PersonService(this.getContext()); List<Person> persons = personService.getScrollData(0, 3); for (Person person : persons) { Log.i(TAG, person.toString()); } } }