深入解析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`异常。
推荐阅读
1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ...
[详细]
蜡笔小新 2024-12-27 19:32:17
本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ...
[详细]
蜡笔小新 2024-12-28 10:36:30
本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ...
[详细]
蜡笔小新 2024-12-28 10:30:14
Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ...
[详细]
蜡笔小新 2024-12-28 08:54:34
Java 中 Writer flush()方法,示例 ...
[详细]
蜡笔小新 2024-12-28 06:41:52
本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ...
[详细]
蜡笔小新 2024-12-28 04:42:15
本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ...
[详细]
蜡笔小新 2024-12-27 18:20:43
本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ...
[详细]
蜡笔小新 2024-12-27 17:40:42
本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ...
[详细]
蜡笔小新 2024-12-27 16:11:49
本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ...
[详细]
蜡笔小新 2024-12-27 16:01:25
本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ...
[详细]
蜡笔小新 2024-12-27 15:06:12
本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ...
[详细]
蜡笔小新 2024-12-27 15:04:09
本文介绍如何使用 Python 将一个字符串按照指定的行和元素分隔符进行两次拆分,最终将字符串转换为矩阵形式。通过两种不同的方法实现这一功能:一种是使用循环与 split() 方法,另一种是利用列表推导式。 ...
[详细]
蜡笔小新 2024-12-28 12:15:45
本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ...
[详细]
蜡笔小新 2024-12-28 11:30:01
1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ...
[详细]
蜡笔小新 2024-12-27 18:36:54