SQLite数据库

  • 示例工程名 : SQLite

创建一个SQLiteDatabase 实例:

  • 第一种方法 :创建工具类 DatabaseHelper extends SQLiteOpenHelper
  • onCreate()仅在数据库文件不存在需要创建时调用,否则不调用。
  • onUpgrade() 数据库升级时调用 (也即要创建的版本高于当前版本,就会调用这个函数)
  • 改进构造函数,若程序仅仅使用一个数据库,则可以将构造函数里面原本的四个参数在super()中默认三个,
DatabaseHelper dbh = new DatabaseHelper(this, "info.db", null, 1);
SQLiteDatabase sdb = dbh.getWritableDatabase();
  • 第二种方法:SQLiteDatabase.openDatabase();
SQLiteDatabase sld = SQLiteDatabase.openDatabase("/data/data/com.example.sqlite/mydb",  null,SQLiteDatabase.OPEN_READWRITE|SQLiteDatabase.CREATE_IF_NECESSARY);
  • SQLiteDatabase的构造方法是私有化的。
  • 使用哪种方法
  • If you do not need SQLiteOpenHelper, the you do not need to call getWritableDatabase either.

使用SQLiteDatabase实例对数据库进行增删改查操作

  • 数据类型 。
  • NULl 空值
  • INTEGER 有符号整数
  • REAL 浮点数
  • TEXT 文本字符串
  • BLOB 数据块
  • SQLite也支持SQL标准类型 ,VACHER、 CHAR、 BIGINT
创建表
  • 一般将这个功能放在继承了SQLiteOpenHelper的工具类的onCreate()函数中
  • 使用SQL语句
db.execSQL("CREATE TABLE if not exists MyMusicTable (_id INTEGER PRIMARY KEY AUTOINCREMENT, musicName TEXT, author TEXT , musicPath TEXT , pictPath TEXT)");
  • 以上创建的表的名字就是 MyMusicTable
  • SQLiteDatabase.insert
插入数据
  • 使用SQL语句
    SQLiteDatabase.execSQL(“insert into MyMusicTable(musicName,author,musicPath,pictPath) values(‘曾经的你’,’许巍’,’地址1’,’地址2’),(‘绅士’,’轻则多’,’地址3’,’地址4’),(‘董卓瑶’,’地址5’,’地址6’)”);
  • 以上代码插入了三条数据
  • INSERT INTO 语句用于向表格中插入新的行,
  • INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,….)
  • SQLiteDatabase
删除数据
  • 使用SQL语句
SQLiteDatabase.execSQL("DELETE FROM MyMusicTable WHERE musicName = '绅士'");
  • delete 用于删除表中的行
  • DELETE FROM 表名称 WHERE 列名称 = 值
  • DELETE FROM 表名称 WHERE 列名称1 = 值1 AND 列名称2 = 值2
  • DELETE FROM 表名称 WHERE 列名称1 = 值1 OR 列名称2 = 值2
  • 为了仅仅删除行而不删除表以保留完整的结构,可以使用 DELETE FROM table_name
  • SQLiteDatabase.delete
SQLiteDatabase.delete("MyMusicTable", "musicName=? or author=?", new String[]{"绅士","许巍"});
  • 第一个参数为表名 , 第二个参数为WHERE条件内容,使用占位符? , 使用参数三来填充占位符
  • 返回值为被删除的行数
更改数据
  • 使用SQL语句
SQLiteDatabase.execSQL("UPDATE MyMusicTable SET musicPath = '地址56' WHERE musicName = '绅士'");
  • UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
  • UPDATE 表名称 SET 列名称1 = 新值1 , 列名称2 = 新值2 WHERE 列名称1 = 值1 AND 列名称2 = 值2

-SQLiteDatabase.update

SQLiteDatabase.update("MyMusicTable", cv, "musicPath=? or pictPath=?", new String[]{"地址-1171417365","地址2-110"});

- 第一个参数为表名,第二个参数为一个ContentValues对象,相当于SET条件的内容,第三个参数为WHERE条件内容,使用占位符,使用参数四来填充占位符。
- 返回值为被更改的行数
查询数据
  • 使用SQL语句(查询就不能再用execSQL函数了,因为这个函数没有返回值,而查询是必定有返回结果的)
Cursor cursor = sdb.rawQuery("SELECT musicName,author,pictPath FROM MyMusicTable", null);
while (cursor.moveToNext()) {
    //这个索引就是列的索引,如果你是select整个表(*) ,那么列序则为_id、musicName、author、musicPath、pictPath , 其中索引2就为author
    //如果你是SELECT musicName,author,piatPath FROM MyMusicTable , 那么列序为musicName,author,pictPath , 其中索引2就为pictPath
    String pictPath = cursor.getString(2);
    Log.e("select", pictPath);
}
  • SELECT 列名称 FROM 表名称
  • SELECT 列名称1,列名称2,列名称3 FROM 表名称 WHERE 列名称1 = 值1 OR 列名称2 = 值2
  • SQLiteDatabase.query
Cursor cursor = sdb.query("MyMusicTable", new String[]{"_id","musicPath","pictPath"}, "musicName=? and author=?", new String[]{"绅士","许巍"} , null, null, null, null);
while (cursor.moveToNext()) {
    String musicPath = cursor.getString(1);
    Log.e("select", musicPath);
}
  • query , 第一个参数为表名,第二个参数为需要查询的列, 第三个参数和第四个参数构成WHERE条件内容,后者为占位符提供内容。
  • 和使用rawQuery函数类似,返回值还是Cursor
使用完后调用SQLiteDatabase.close() 释放句柄

直接借用程序上下文来操作数据库(比如在Activity的onCreate()中)

  • this.deleteDatabase(String name); 删除指定数据库
  • this.getDatabasePath(String name); 得到指定数据库的路径

事务

  • 事务存在的必要性:例如,银行转账,一个人钱减少了,必定要另一个人的钱增加。通过事务来达到“要么完全执行,要么完全不执行”的效果 , 以防止特殊原因(例如网络中断)引起的数据不完整。类似原子操作。
SQLiteDatabase.beginTransaction()
//你想执行的事务
// 设置事务执行成功,若在endTransaction()执行时setTransactionSuccessful()没有执行过,也即事务执行失败,就会回滚。
SQLiteDatabase.setTransactionSuccessful()
SQLiteDatabase.endTransaction()
  • 当你要插入大量的数据时 ,使用事务可以明显提高效率。看以下测试结果:
  • 当插入1000行数据时,普通插入耗费2714ms , 使用事务插入耗费96ms
  • 当插入5000行数据时,普通插入耗费13644ms, 使用事务插入耗费381ms
  • 为什么使用事务会提高效率?看以下两种说法。
  • SQLite缺省为每个操作启动一个事务,那么n次操作就会开启n个事务,“事务开启+SQL执行+事务关闭”自然耗费大量的事件。(我要问:直接使用事务就仅会开启一个事务吗?)
  • SQLite本质上来讲是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而n次sql语句的执行则会触发n次打开关闭数据库文件的操作。如果使用事务,那么SQLite将把全部要执行的SQL语句先缓存在内存中,然后等到commit的时候一次性的写入数据库。(我要问:在getWritableDatabase()之后数据库文件不是一直打开的吗?直到调用了SQLiteDatabase.close()?)