Android攻城狮数据存储之SQLite数据库简介
SQLite是用C语言编写的开源嵌入式数据库引擎。它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行。 SQLite:轻量级、性能不错,管理成本小。在管理、维护方面都非常出色,功能强大。 ——支持高达2TB大小的数据库 ——以单个文件的形式存在 ——以B-Tree的数据结构形式存储在磁盘 特点主要包括: 1.轻量级:一个动态库、单文件 2.独立性:没有依赖,无需安装 3.隔离性:全部在一个文件夹中 4.跨平台:支持众多操作系统 5.多语言接口:支持众多编程语言 6.安全性:事务(在下面细说) 关于事务处理的安全性问题: ---通过数据库的排它锁和共享锁来实现独立的事务处理 ---多个进程可以在同一时间内从同一个数据库读取数据,但只有一个可以写入数据(保证数据的一致性,但也牺牲了效率) 基本满足移动的、嵌入设备的开发。 -------------------- SQLite支持的数据类型: NULL、INTEGER、REAL、TEXT、BLOB。分别表示 空值、整型、浮点型、字符串型、二进制对象。 有意思的是,它既然支持多种编程语言,但有的语言是没有像REAl或者BLOB这样的数据类型,要怎么解决呢?那就是采用“弱引用”,也叫动态数据类型。 动态数据类型(弱引用): ---当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值转换成该列的类型,如果不能转换,则该值将作为本身的类型存储。 但最好不要使用不支持的类型。 ----------------------- 使用须知: ---由于资源占有少、性能良好和零管理成本,嵌入式数据库有了它的用武之地。例如Android、IOS。 ---没有可用于 SQLite 的网络服务器、只能通过网络共享,可能存在文件锁定(Windows)或者性能问题。 ---只提供数据库级的锁定。 ---没有用户账户的概念,而是根据文件系统确定所有数据库的权限。
在Android中如何使用SQlite,主要通过如下两个类: --SQLiteDatabase --SQLiteOpenHeplper
注意事项 1. 命名规范:数据库的名字最好有后缀".db",方便在第三方数据库工具上使用。 2. 主键必须以下划线开头,例如“_id”,原因在于适配器,例如像ListView的适配器只通过下划线去找主键。 3. 操作完之后,记得手动关闭游标Cursor和数据库。 ----------------------- --Cursor是Android查询数据后得的一个管理数据集合的类,正常情况下,如果查询得到的数据量较小时不会有内存的问题,而且虚拟机能够保证Cursor最终会被释放掉。 --然而,如果Cursor的数据量特别大,特别是如果里面有Blob信息的时候,应该保证Cursor占用的内存被及时地清理掉,而不是等待GC来处理。并且Android明显是倾向于编程者手动地将Cursor关闭,因为在源码中我们发现,如果等到垃圾回收器来回收,也就是如果不手动关闭,系统就会报错,会给用户以错误提示。
1 编程部分 2 // 打开或创建(如果有就打开,没有就创建,所以没有“覆盖”的问题)一个数据库 3 SQLiteDatabase db = openOrCreateDatabase("user.db",MODE_PRIVATE,null); 4 // 第二参数是权限,设为私有,也就是只有本程序才可访问。第三参数是游标,不需要。 5 String sql ="create table if not exists usertb (_id integer primary key autoincrement, name text not null, age integer not null, sex text not null)"; 6 db.execSQL(sql); 7 String sql2="insert into usertb (name,age,sex) values('张三','男',20)"; 8 db.execSQL(sql2); 9 db.execSQL("insert into usertb (name,age,sex) values('李四','男',23)"); 10 Cursor cursor = db.rawQuery("select * from usertb",null); // null表示不加条件 11 if (cursor!=null){ 12 while(cursor.moveToNext()){ 13 Log.i("info","_id"+cursor.getInt(cursor.getColumnIndex("_id")));// 先获得列的编号,再通过编号获得对应的值。 14 Log.i("info","name="+cursor.getString(cursor.getColumnIndex("name"))); 15 Log.i("info","sex="+cursor.getString(cursor.getColumnIndex("sex"))); 16 Log.i("info","age="+cursor.getInt(cursor.getColumnIndex("age"))); 17 } 18 cursor.close(); // 释放资源 19 } 20 db.close(); // 关闭数据,释放内存
1 public class MainActivity extends ActionBarActivity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.fragment_main); 7 SQLiteDatabase db = openOrCreateDatabase("stu.db", MODE_PRIVATE, null); 8 db.execSQL("create table if not exists stutb (_id integer primary key autoincrement, name text not null, sex text not null, age integer not null )"); 9 ContentValues values = new ContentValues(); 10 values.put("name", "zy"); 11 values.put("sex", "boy"); 12 values.put("age", 19); 13 //插入 14 long rowId = db.insert("stutb", null, values); 15 values.clear(); 16 values.put("name", "zlj"); 17 values.put("sex", "boy"); 18 values.put("age", 20); 19 db.insert("stutb", null, values); 20 values.clear(); 21 22 // -----更新,删除-------- 23 values.put("sex", "giral"); 24 db.update("stutb", values, "_id>?", new String[] { "1" });// 将全部ID>1的全部sex改成giral 25 db.delete("stutb", "name like?", new String[] { "%y%" });// 删除所有名字中带有y的人 26 Cursor cursor = db.query("stutb", null, "_id>?", new String[] { "0" }, 27 null, null, null); 28 if (cursor != null) { 29 String[] colums = cursor.getColumnNames(); 30 while (cursor.moveToNext()) { 31 32 for (String columnNames : colums) { 33 Log.i("info", cursor.getString(cursor 34 .getColumnIndex(columnNames))); 35 } 36 37 } 38 cursor.close(); 39 } 40 db.close(); 41 } 42 43 }
SQLiteOpenHelper -- SQLiteDatabase的帮助类,用于管理数据库的创建和版本更新。 -- 一般是建立一个类继承它,在构造方法中初始化一些变量,并重写onCreate()和onUpgrade()方法。 -- 方法说明 * onCreate(SQLiteDatabase db) 创建数据库和数据表的时候调用 * onUpgrade(SQliteDatabase db,int oldVersion,int newVersion) 版本更新时调用。是系统自动调用,不允许手动调用。 * getReadableDatabase() 创建或打开一个只读数据库 * getWritableDatabase() 创建或打开一个读写数据库 ------------------ getWritableDatabase()和getReadableDatabase()的相同点以及区别: 1. getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例,正常情况下获得的实例都可以对数据库进行读写操作。 2. getWritableDatabase取得的实例是以读写的方式打开数据库,如果打开的数据库磁盘满了,此时只能读不能写,此时调用了getWritableDatabase的实例,那么将会发生错误(异常)。 3. getReadableDatabase取得的实例是先调用getWritableDatabase以读写的方式打开数据库,如果数据库的磁盘满了,此时返回打开失败,继而用getReadableDatabase的实例以只读的方式去打开数据库。
SQLiteOpenHelper -- SQLiteDatabase的帮助类,用于管理数据库的创建和版本更新。 -- 一般是建立一个类继承它,在构造方法中初始化一些变量,并重写onCreate()和onUpgrade()方法。 -- 方法说明 * onCreate(SQLiteDatabase db) 创建数据库和数据表的时候调用 * onUpgrade(SQliteDatabase db,int oldVersion,int newVersion) 版本更新时调用。是系统自动调用,不允许手动调用。 * getReadableDatabase() 创建或打开一个只读数据库 * getWritableDatabase() 创建或打开一个读写数据库 ------------------ getWritableDatabase()和getReadableDatabase()的相同点以及区别: 1. getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例,正常情况下获得的实例都可以对数据库进行读写操作。 2. getWritableDatabase取得的实例是以读写的方式打开数据库,如果打开的数据库磁盘满了,此时只能读不能写,此时调用了getWritableDatabase的实例,那么将会发生错误(异常)。 3. getReadableDatabase取得的实例是先调用getWritableDatabase以读写的方式打开数据库,如果数据库的磁盘满了,此时返回打开失败,继而用getReadableDatabase的实例以只读的方式去打开数据库。
1 public class DBOpenHelper extends SQLiteOpenHelper { 2 3 public DBOpenHelper(Context context, String name) { 4 super(context, name, null,1); 5 // TODO Auto-generated constructor stub 6 } 7 8 // 首次创建数据库的时候调用,放建库,建表的操作 9 @Override 10 public void onCreate(SQLiteDatabase db) { 11 // TODO Auto-generated method stub 12 db.execSQL("create table if not exists stutb(_id integer primary key autoincrement, name text not null, sex text not null, age integer not null)"); 13 db.execSQL("insert into stutb(name,sex,age) values('Lucy','女',20)"); 14 } 15 16 // 当数据库的版本发生变化的时候,会自动执行 17 @Override 18 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 19 // TODO Auto-generated method stub 20 21 } 22 23 }