Android 基础之SQLite的使用

在Android平台上,集成了一个嵌入式关系型数据库——SQLite。 SQLite3支持 NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)等五种数据类型; 虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。

SQLite数据库的特点:

(1)Android通过 SQLite 数据库引擎来实现结构化数据的存储。在一个数据库应用程序中,任何类都可以通过名字对已经创建的数据库进行访问,但是在应用程序之外就不可以。
(2)SQLite 数据库是一种用C语言编写的嵌入式数据库,它是一个轻量级的数据库,最初为嵌入式设计的。它是在一些基础简单的语句处理上要比oracle / mysql快很多,而且其对内存的要求很低,在内存中只需要几百KB的存储空间。这是Android中采用 SQLite 数据库的主要原因。
(3)SQLite 支持事务处理功能。Transaction
(4)SQLite 处理速度比MySQL等著名的开源数据库系统更快。它没有服务器进程。
(5)SQLite 通过文件保存数据库,该文件是跨平台的,可以自由复制。一个文件就是一个数据库。数据库名即文件名。
(6)JDBC会消耗太多系统资源,所以JDBC对于手机并不合适,因此Android提供了新的API来使用 SQLite 数据库。
(7)SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。

Android对SQLite的操作

Android中提供了很多操作SQLite类和方法。
下面将详讲解两个常用类的使用,以及如何保证数据一致性

SQLiteDatabase类

SQLiteDatabase等同于JDBC中Connection和Statement的结合体。SQLiteDatabase既
代表与数据库的连接,又只能用于执行sql语句操作。

####操作 SQLite 数据库的步骤:(关键)

1 创建 SQLiteDatabase 对象,它代表与数据库的连接;
2 创建数据库中的表(执行CREATE);
3 调用SQLiteDatabase 对象执行数据库操作(执行DML);
4 查询后的结果集Cursor进行处理。

  1. 打开数据库方法

    1. 根据路径打开数据库

      1
      public static SQLiteDatabase openDatabase (String path, SQLiteDatabase.CursorFactory factory, int flags)

      参数介绍:
      -- 参数① path : path 要打开 或者 需要创建的 数据库文件的路径;
      -- 参数② factory : 当打开的数据库执行查询语句的时候 会创建一个Cursor对象, 这时会调用Cursor工厂类 factory, 可以填写null默认值;
      -- 参数③ flag :
      OPEN_READWRITE 打开一个读写数据库, 如果磁盘满了, 之前写入的也作废;
      READ_OPENONLY 打开只读数据库, 这时读取数据库的可靠方法;
      CREATE_IF_NECESSARY 打开数据库, 如果数据库不存在, 就创建这个数据库;
      NO_LOCALIZED_CALLATORS 打开数据库 不根据本地语言顺序进行排序, 使用这种模式创建数据库, 排序器不会被创建, 使用这个数据库 和 创建这个数据库的时候必须都使用这个标识, 如果这个标识被使用了, 那么setLocal()方法将不会起到任何作用;

    2. 根据文件打开或则创建数据库

      1
      public static SQLiteDatabase openOrCreateDatabase (File file, SQLiteDatabase.CursorFactory factory)
    3. 根据路径打开或创建数据库

      1
      public static SQLiteDatabase openOrCreateDatabase (String path, SQLiteDatabase.CursorFactory factory)
  2. 操作数据库

    1. 执行SQL语句动态参数

      1
      public void execSQL (String sql, Object[] bindArgs)

      参数介绍 :
      -- 参数① sql: 要执行的SQL语句, 只能执行一条, 多条语句用分号隔开不管用, 参数使用 “?” 占位符代替;
      -- 参数② bingArgs: 替换上面SQL语句中的 “?” 占位符, 按照数组中的顺序依次替换;

    2. 执行固定SQL语句

      1
      public void execSQL (String sql)
    3. 插入数据

      1
      public long insert (String table, String nullColumnHack, ContentValues values)

      -- 参数① table : 数据库中的表名, 要插入数据的表;
      -- 参数② nullColumnHack : 该参数是可选的, 数据库表中不允许插入一行空的数据, 插入数据至少有一列不为null才能插入, 如果后面的values是null, 并且不知道列的名称, 那么插入操作会失败, 为了避免这种情况, 就出现了本参数, 为了防止 values为null的情况;
      -- 参数③ values : 相当于一个Map集合,键 是列名,值 是对应列名要插入的数据;
      插入原则 : 不管 第三个 ContentValues参数 是否为null, 执行insert()方法都会添加一条记录, 如果values参数为null, 会添加一个除主键之外其它字段都为null的记录;
      实例:

      1
      2
      3
      4
      5
      6
      //创建表数据, 键 为 列名, 值 为 对应的表数据
      ContentValues values = new ContentValues();
      values.put("name", "乔帮主");
      values.put("age", 54);
      //向表中插入数据, 如果values为null, 就会添加一个
      long rowsNum = db.insert("apple_info", "name", values);

      上面代码转成SQL语句 :

      1
      insert into apple_info (name, age) values ('乔帮主', 54)
    4. 更新数据

      1
      public int update (String table, ContentValues values, String whereClause, String[] whereArgs)

      -- 参数① table : 数据库表名称;
      -- 参数② values : 该值类似Map集合, 键 是 列名, 值 是 要更新的数据, 这个值可以为null, 如果为null 这些数据会被清空;
      -- 参数③ whereClause: where选择语句, 选择那些行进行数据的更新, 如果该参数为 null, 就会修改所有行;
      -- 参数④ whereArgs : where选择语句的参数, 逐个替换 whereClause 中的占位符;
      实例:

      1
      2
      3
      4
      5
      //创建表数据, 键 为 列名, 值 为 对应的表数据
      ContentValues values = new ContentValues();
      values.put("name", "乔帮主");
      values.put("age", 54);
      int result = db.update("apple_info", values, "name=?", new String[]{"乔帮主"});

      上面代码转成SQL语句 :

      1
      update apple_info set name='乔帮主', age=56 where name='乔帮主'
    5. 删除数据

      1
      public int delete (String table, String whereClause, String[] whereArgs)

      参数介绍 :
      -- 参数① table : 要操作的数据库表名;
      -- 参数② whereClause : where选择语句, 选择哪些行要被删除, 如果为null, 就删除所有行;
      -- 参数③ whereArgs : where语句的参数, 逐个替换where语句中的 “?” 占位符;
      实例:

      1
      int result = db.delete("apple_info", "name=?", new String[]{"乔帮主"});

      上面代码转成SQL语句 :

      1
      delete apple_info where name='乔帮主'
    6. 查询

      1
      public Cursor query (boolean distinct, String table, String[] columns,String selection, String[] selectionArgs,String groupBy, String having,String orderBy, String limit,CancellationSignal cancellationSignal)

      参数介绍 :
      -- 参数① distinct : 是否去重复, true 去重复;
      -- 参数② table : 要查询的表名;
      -- 参数③ columns : 要查询的列名, 如果为null, 就会查询所有的列;
      -- 参数④ whereClause : 条件查询子句, 在这里可以使用占位符 “?”;
      -- 参数⑤ whereArgs : whereClause查询子句中的传入的参数值, 逐个替换 “?” 占位符;
      -- 参数⑥ groupBy : 控制分组, 如果为null 将不会分组;
      -- 参数⑦ having : 对分组进行过滤;
      -- 参数⑧ orderBy : 对记录进行排序;
      -- 参数⑨ limite : 用于分页, 如果为null, 就认为不进行分页查询;
      -- 参数⑩ cancellationSignal : 进程中取消操作的信号, 如果操作被取消, 当查询命令执行时会抛出 OperationCanceledException 异常;
      实例:

      1
      2
      Cursor cursor = db.query(true, "apple_info",new String[]{"_id, name, age"},"name like ?", new String[]{"乔%"},null, null,"_id desc", "5, 10");
      cursor.close();

      上面代码转成SQL语句需要使用rawQuery方法,要实现以上所有的功能需要自己写一个SQL语句:

      1
      public Cursor rawQuery (String sql, String[] selectionArgs)

      参数解析 :
      -- 参数① sql : 要执行的SQL语句, 可以使用 “?” 作为占位符;
      -- 参数② selectionArgs : sql语句中的参数, 按照次序依次替换占位符 “?”;

Cursor对象的操作

当执行的是select语句,返回一个Cursor对象。Cursor类似于JDBC中的ResultSet结果集,内置移动游标等方法:

方法名 简述
move(int offset) 按偏移量来移动
moveToFirst() 将记录指针移动到第一行
moveToLast () 将记录指针移动到最后一行
moveToNext () 将记录指针移动到下一行
moveToPosition(int position) 将记录指针移动到指定的一行
moveToPrevious() 将记录指针移动到上一行
getCount() 返回Cursor的行数
getColumnName(int index) 根据列的索引返回其相应的列名称
getColumnIndex(String name) 根据列的名字返回其相应的索引
getColumnNames() 返回一个保存有所有列名称的字符串数组
getColumnCount() 返回列的总数
close() 关闭游标结果集,释放资源
getType() 获取字段的数据类型。分别有0、1、2、3、4这几个结果。

数据库事务Database Transaction

在数据库开发中,事务处理是非常重要的。
首先Android数据库操作(特别是写操作)是非常慢的,将所有操作打包成一个事务能大大提高处理速度。
其次是保证数据的一致性,一个事务中的所有操作可以看作一个原子操作,成功或者失败。如果全部成功,则事务提交完成;而事务内部如果有失败操作,整个事务操作会回滚,从而保证数据的一致性。
Android中事务的调用:

1
2
3
4
5
6
7
8
9
10
11
try {
db.beginTransaction();
//在这里执行多个数据库操作
//执行过程中可能会抛出异常
db.setTransactionSuccessful();
//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作
} catch (Exception e){
} finally {
//当所有操作执行完成后结束一个事务
db.endTransaction();
}

注意:

一定要调用db.setTransactionSuccessful();事务才会成功提交完成
事务是可以嵌套的

SQLiteOpenHelper类

SQLiteOpenHelper是系统提供的一个管理数据库表创建和版本管理(尤其是版本更新)的抽象类,我们必须通过继承SQLiteOpenHelper来实现自己的工具类。

封装DBHelper类