Google为Andriod的较大的数据处理提供了SQLite,他在数据存储、管理、维护等各方面都相当出色,功能也非常的强大。
袖珍型的SQLite可以支持高达2TB大小的数据库,每个数据库都是以单个文件的形式存在,这些数据都是以B-Tree的数据结构形式存储在磁盘上。
在事务处理方面,SQLite通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。在某个进程或线程想数据库执行写操作之前,必须获得独占锁。在获得独占锁之后,其他的读或写操作将不会再发生。
SQLite采用动态数据类型,当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值转换成该列的类型,如果不能转换,则该值将作为本身的类型存储,SQLite称这为“弱类型”。但有一个特例,如果是INTEGER PRIMARY KEY,则其他类型不会被转换,会报一个“datatype missmatch”的错误。
概括来讲,SQLite支持NULL、INTEGER、REAL、TEXT和BLOB数据类型,分别代表空值、整型值、浮点值、字符串文本、二进制对象。
SQLite还包括以下特点:
1、SQLite3支持 NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型虽然只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。
2、SQLite最大的特点是你可以保存任何类型的数据到任何字段中,无论这列声明的数据类型是什么。例如:可以在Integer字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。
3、但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段中保存除整数以外的数据时,将会产生错误。
4、另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段的类型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
PersonSqliteOpenHelper类
public class PersonSqliteOpenHelper extends SQLiteOpenHelper { /** * 数据库的构造方法 * 数据库查询的结果集,为null则使用默认的结果集 * 数据库的版本,从1开始,小于1则抛异常 * @param context */ public PersonSqliteOpenHelper(Context context) { super(context, "person.db", null, 1); } /** * 数据库在第一次被创建时调用,表结构,初始化 * 数据类型的长度是无用的,只是给程序员看的 * @param sqLiteDatabase 数据库 */ @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { sqLiteDatabase.execSQL("create table person (id integer primary key autoincrement, name varchar(20), number varchar(20))"); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } }
PersonDao类
Person类public class PersonDao { private PersonSqliteOpenHelper helper; public PersonDao(Context context) { helper = new PersonSqliteOpenHelper(context); } public void add(String name, String number){ SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("insert into person (name,number) values (?,?)", new Object[]{name,number}); db.close(); } public boolean find(String name){ SQLiteDatabase db = helper.getWritableDatabase(); Cursor cursor = db.rawQuery("select * from person where name=?", new String[]{name}); boolean result = cursor.moveToNext(); cursor.close(); db.close(); return result; } public void update(String name, String newnumber){ SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("update person set number=? where name=?", new Object[]{newnumber, name}); db.close(); } public void delete(String name){ SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("delete from person where name=?",new String[]{name}); db.close(); } public List<Person> findAll(){ SQLiteDatabase db = helper.getReadableDatabase(); List<Person> persons = new ArrayList<Person>(); Cursor cursor = db.rawQuery("select name,id,number from person ",null); while (cursor.moveToNext()){ int id = cursor.getInt(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); String number = cursor.getString(cursor.getColumnIndex("number")); Person p = new Person(id,name,number); persons.add(p); } cursor.close(); db.close(); return persons; } }
public class Person { private int id; private String name; private String number; public Person() { } public Person(int id, String name, String number) { this.id = id; this.name = name; this.number = number; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", number='" + number + '\'' + '}'; } }ApplicationTest类
public class ApplicationTest extends ApplicationTestCase<Application> { public ApplicationTest() { super(Application.class); } public void testDBHelp() throws Exception{ PersonSqliteOpenHelper perSQL = new PersonSqliteOpenHelper(getContext()); perSQL.getWritableDatabase(); } public void testAdd() throws Exception{ PersonDao dao = new PersonDao(getContext()); dao.add("小明", "18500003039"); } public void testFind(){ PersonDao dao = new PersonDao(getContext()); boolean result = dao.find("小明"); assertEquals(true, result); } public void testUpdate(){ PersonDao dao = new PersonDao(getContext()); dao.add("大帅", "13100001423"); } public void testDelete(){ PersonDao dao = new PersonDao(getContext()); dao.delete("小明"); } public void testFindAll(){ PersonDao dao = new PersonDao(getContext()); List<Person> persons = dao.findAll(); for (Person p:persons){ System.out.println(p.toString()); } } }
使用Android自带API
public class PersonDao2 { private PersonSqliteOpenHelper helper; public PersonDao2(Context context) { helper = new PersonSqliteOpenHelper(context); } public long add(String name, String number){ SQLiteDatabase db = helper.getWritableDatabase(); //db.execSQL("insert into person (name,number) values (?,?)", new Object[]{name,number}); ContentValues values = new ContentValues(); values.put("name",name); values.put("number", number); long result = db.insert("person",null,values); db.close(); return result; } public boolean find(String name){ SQLiteDatabase db = helper.getWritableDatabase(); //Cursor cursor = db.rawQuery("select * from person where name=?", new String[]{name}); Cursor cursor = db.query("person",null,"name=?",new String[]{name},null,null,null); boolean result = cursor.moveToNext(); cursor.close(); db.close(); return result; } public int update(String name, String newnumber){ SQLiteDatabase db = helper.getWritableDatabase(); //db.execSQL("update person set number=? where name=?", new Object[]{newnumber, name}); ContentValues values = new ContentValues(); values.put("number", newnumber); int result = db.update("person",values,"name=?",new String[]{name}); db.close(); return result; } public int delete(String name){ SQLiteDatabase db = helper.getWritableDatabase(); //db.execSQL("delete from person where name=?", new String[]{name}); int result = db.delete("person","name=?",new String[]{name}); db.close(); return result; } public List<Person> findAll(){ SQLiteDatabase db = helper.getReadableDatabase(); List<Person> persons = new ArrayList<Person>(); //Cursor cursor = db.rawQuery("select name,id,number from person ",null); Cursor cursor = db.query("person",new String[]{"name","id","number"},null,null,null,null,null); while (cursor.moveToNext()){ int id = cursor.getInt(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); String number = cursor.getString(cursor.getColumnIndex("number")); Person p = new Person(id,name,number); persons.add(p); } cursor.close(); db.close(); return persons; } }
SQLite修改数据库结构,先修改数据库版本号,然后再重写onUpgrade方法,执行需要的操作,注意,此方法只在版本号增加后首次运行时执行。
@Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { Log.i(TAG,"databases is modified"); sqLiteDatabase.execSQL("alter table person add account varchar(20)"); }SQLite的事务处理
public void testTransaction(){ SQLiteDatabase db = helper.getReadableDatabase(); db.beginTransaction(); try { db.execSQL("update person set account=account-1000 where name=?", new Object[]{"杨小明"}); db.execSQL("update person set account=account+1000 where name=?", new Object[]{"范大帅"}); db.setTransactionSuccessful(); }catch (Exception e){ }finally { db.endTransaction(); db.close(); } }先插入两条数据,初始化金额,再执行事务处理的方法,得到如下结果:
8:14:36.456 13235-13248/? I/TAGG﹕ Person{id=19, name='杨小明', number='18500003039', account=5000} 08-16 18:14:36.456 13235-13248/? I/TAGG﹕ Person{id=20, name='范大帅', number='13300001423', account=2000} 08-16 18:15:23.371 13435-13448/com.haier.sqlitedatabase I/TAGG﹕ Person{id=19, name='杨小明', number='18500003039', account=4000} 08-16 18:15:23.371 13435-13448/com.haier.sqlitedatabase I/TAGG﹕ Person{id=20, name='范大帅', number='13300001423', account=3000}