深入解析Android中的SQLite数据库
作者:楼外蔷薇花开 | 来源:互联网 | 2024-11-26 21:57
SQLite是一种轻量级的关系型数据库管理系统,尽管体积小巧,却能支持高达2TB的数据库容量,每个数据库以单个文件形式存储。本文将详细介绍SQLite在Android开发中的应用,包括其数据存储机制、事务处理方式及数据类型的动态特性。
SQLite是一个广泛应用于移动设备上的关系型数据库引擎,它以其轻量级和高效能著称。尽管其体积小,但SQLite能够支持非常大的数据库,最高可达2TB。每个数据库文件都是独立存在的,这使得SQLite非常适合于嵌入式系统和移动应用。
### 数据存储机制
SQLite使用B-Tree数据结构来存储数据,这种结构不仅支持高效的查找,还允许快速的数据插入和删除。每个数据库文件都包含了所有的表格、索引以及视图等数据库对象。
### 事务处理
SQLite通过数据库级别的锁定机制来确保事务的独立性。这意味着,在任何给定时间,多个进程可以同时读取同一个数据库,但是只有单一进程可以进行写操作。当一个进程打算对数据库进行写入时,它必须首先获取一个独占锁。一旦这个锁被获取,其他的所有读写操作都将被阻塞,直到当前写操作完成。
### 动态数据类型
SQLite支持动态数据类型,这意味着在插入数据时,SQLite会自动检测数据类型,并根据目标列的数据类型进行可能的转换。例如,如果试图将一个字符串插入到一个整数类型的列中,SQLite会尝试将字符串转换为整数;如果转换失败,则保持原始数据类型。然而,对于定义为INTEGER PRIMARY KEY的列,任何非整数值的插入都会导致类型不匹配错误。
### 支持的数据类型
SQLite支持五种基本的数据类型:NULL(空值)、INTEGER(整型值)、REAL(浮点值)、TEXT(字符串文本)和BLOB(二进制大对象)。这些类型覆盖了大多数常见的数据需求。
### 示例代码
以下是在Android应用中使用SQLite的一个简单示例,展示了如何创建数据库、表,以及如何进行插入、查询、更新和删除操作:
```java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 打开或创建test.db数据库
SQLiteDatabase db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);
db.execSQL("DROP TABLE IF EXISTS person");
// 创建person表
db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)");
Person person = new Person();
person.name = "john";
person.age = 30;
// 插入数据
db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age});
person.name = "david";
person.age = 33;
ContentValues cv = new ContentValues();
cv.put("name", person.name);
cv.put("age", person.age);
// 插入ContentValues中的数据
db.insert("person", null, cv);
cv = new ContentValues();
cv.put("age", 35);
// 更新数据
db.update("person", cv, "name = ?", new String[]{"john"});
Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});
while (c.moveToNext()) {
int _id = c.getInt(c.getColumnIndex("_id"));
String name = c.getString(c.getColumnIndex("name"));
int age = c.getInt(c.getColumnIndex("age"));
Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);
}
c.close();
// 删除数据
db.delete("person", "age ", new String[]{"35"});
// 关闭当前数据库
db.close();
}
```
上述代码执行完毕后,将在`/data/data/[PACKAGE_NAME]/databases`目录下生成名为`test.db`的数据库文件。
### 数据库操作方法
除了通用的`executeSQL`方法外,SQLite还提供了专门用于插入、更新和删除记录的方法:
- `db.insert(String table, String nullColumnHack, ContentValues values)`:向指定表中插入新记录。
- `db.update(String table, ContentValues values, String whereClause, String[] whereArgs)`:更新表中满足特定条件的记录。
- `db.delete(String table, String whereClause, String[] whereArgs)`:删除表中满足特定条件的记录。
### 查询操作
查询操作相对复杂,SQLite提供了多种查询方法来应对不同的查询需求:
- `db.rawQuery(String sql, String[] selectionArgs)`:执行任意的SQL查询。
- `db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)`:提供详细的查询参数设置。
- `db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)`:增加分页参数。
- `db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)`:支持去重查询。
### Cursor对象
查询结果通常以`Cursor`对象的形式返回,`Cursor`提供了多种方法来遍历和访问查询结果集:
- `moveToFirst()`:移动到结果集的第一条记录。
- `moveToLast()`:移动到最后一条记录。
- `moveToNext()`:移动到下一条记录。
- `moveToPrevious()`:移动到前一条记录。
- `isFirst()`:判断是否位于第一条记录。
- `isLast()`:判断是否位于最后一条记录。
- `getCount()`:获取结果集中记录的总数。
- `getColumnIndex(String columnName)`:获取指定列的索引。
- `getString(int columnIndex)`:获取指定列的字符串值。
在完成数据库操作后,务必调用`SQLiteDatabase`的`close()`方法来释放资源,避免出现`SQLiteException`异常。
推荐阅读
-
本文介绍了在解决Hive表中复杂数据结构平铺化问题后,如何通过创建视图来准确计算广告日志的曝光PV,特别是针对用户对应多个标签的情况。同时,详细探讨了UDF的使用方法及其在实际项目中的应用。 ...
[详细]
蜡笔小新 2024-11-26 11:08:12
-
本文介绍了如何利用HTML和JavaScript实现从远程MP4、本地摄像头及本地上传的MP4文件中截取视频帧,并展示了具体的实现步骤和示例代码。 ...
[详细]
蜡笔小新 2024-11-15 00:19:42
-
-
.NetFramework中处理字符和字符串的主要有以下这么几个类:(1)、System.Char类一基础字符串处理类(2)、System.String类一处理不可变的字符串(一经 ...
[详细]
蜡笔小新 2024-11-26 21:04:40
-
本文探讨了 HTML 中 download 属性的应用场景及其在不同浏览器中的实现方式,通过示例代码展示了如何利用 JavaScript 实现文件下载功能。 ...
[详细]
蜡笔小新 2024-11-26 19:35:38
-
转自:http:blog.sina.com.cnsblog_67419c420100vmkt.html 1.为什么要使用blocks将一个blocks作为函数或者方法的参数传递,可 ...
[详细]
蜡笔小新 2024-11-26 17:08:39
-
本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ...
[详细]
蜡笔小新 2024-11-26 16:20:20
-
BeautifulSoup4 是一个功能强大的HTML和XML解析库,它能够帮助开发者轻松地从网页中提取信息。本文将介绍BeautifulSoup4的基本功能、安装方法、与其他解析工具的对比以及简单的使用示例。 ...
[详细]
蜡笔小新 2024-11-26 14:44:14
-
本文将详细介绍Java反射的基础知识,包括如何获取Class对象、反射的基本过程、构造器、字段和方法的反射操作,以及内省机制的应用。同时,通过实例代码加深对反射的理解,并探讨其在实际开发中的应用。 ...
[详细]
蜡笔小新 2024-11-26 13:39:35
-
本文详细解析了Java中流的概念,特别是OutputStream和InputStream的区别,并通过实际案例介绍了如何实现Java对象的序列化。文章不仅解释了流的基本概念,还探讨了序列化的重要性和具体实现步骤。 ...
[详细]
蜡笔小新 2024-11-26 12:15:58
-
本文详细介绍了iOS小部件(Widget)的开发流程,从环境搭建、证书配置到业务逻辑实现,提供了一系列实用的技术指导与代码示例。 ...
[详细]
蜡笔小新 2024-11-25 08:43:14
-
本文介绍了 MySQL 5.7 中主键(Primary Key)和自增(Auto-Increment)的概念,以及如何在 SQLyog 中设置这些属性。同时,还探讨了数据类型的分类和选择,以及列属性的设置方法。 ...
[详细]
蜡笔小新 2024-11-12 15:57:04
-
尽管已经查阅了相关说明,但关于Html.Partial和Html.RenderPartial在ASP.NET MVC3中的使用,我仍然感到困惑。 ...
[详细]
蜡笔小新 2024-11-26 17:38:37
-
本文介绍了如何使用Maven命令对Spring Boot项目中的子模块进行独立打包,包括依赖树的查看、项目的运行和打包等基本操作。 ...
[详细]
蜡笔小新 2024-11-26 14:40:02
-
在使用 Pytest 进行测试时,可能会遇到 FileNotFoundError 错误,提示无法找到指定的文件或目录。本文将探讨该错误的原因及解决方案。 ...
[详细]
蜡笔小新 2024-11-26 13:08:54
-
本文提供了一个SQL脚本,用于在Microsoft SQL Server中创建一个数据字典视图,该视图详细列出了表名、表描述、字段名称、字段描述、字段类型、字段大小、字段精度、是否可为空、默认值以及是否为标识或主键等信息。 ...
[详细]
蜡笔小新 2024-11-24 20:04:23
-