# SQLite数据库 ## 目录 - [SQLite基础](#sqlite基础) - [SQLite操作](#sqlite操作) - [SQLite性能优化](#sqlite性能优化) - [SQLite事务](#sqlite事务) - [SQLite索引](#sqlite索引) - [SQLite最佳实践](#sqlite最佳实践) - [面试常见问题](#面试常见问题) --- ## SQLite基础 ### SQLite 简介 ```java // SQLite:轻量级关系型数据库 // - 嵌入式数据库 // - 无需服务器 // - 支持 SQL 语法 // - 适合移动应用 ``` ### 创建数据库 ```java public class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "my_database.db"; private static final int DATABASE_VERSION = 1; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建表 db.execSQL("CREATE TABLE user (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT NOT NULL," + "email TEXT," + "age INTEGER" + ")"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 升级数据库 db.execSQL("DROP TABLE IF EXISTS user"); onCreate(db); } } ``` --- ## SQLite操作 ### 插入数据 ```java // 方式1:使用 execSQL db.execSQL("INSERT INTO user (name, email, age) VALUES (?, ?, ?)", new String[]{"John", "john@example.com", "25"}); // 方式2:使用 insert ContentValues values = new ContentValues(); values.put("name", "John"); values.put("email", "john@example.com"); values.put("age", 25); long id = db.insert("user", null, values); ``` ### 查询数据 ```java // 查询所有 Cursor cursor = db.query("user", null, null, null, null, null, null); // 条件查询 Cursor cursor = db.query("user", new String[]{"id", "name", "email"}, "age > ?", new String[]{"18"}, null, null, "name ASC"); // 使用 SQL Cursor cursor = db.rawQuery("SELECT * FROM user WHERE age > ?", new String[]{"18"}); // 遍历结果 while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); String email = cursor.getString(cursor.getColumnIndex("email")); } cursor.close(); ``` ### 更新数据 ```java // 方式1:使用 execSQL db.execSQL("UPDATE user SET name = ? WHERE id = ?", new String[]{"Jane", "1"}); // 方式2:使用 update ContentValues values = new ContentValues(); values.put("name", "Jane"); int count = db.update("user", values, "id = ?", new String[]{"1"}); ``` ### 删除数据 ```java // 方式1:使用 execSQL db.execSQL("DELETE FROM user WHERE id = ?", new String[]{"1"}); // 方式2:使用 delete int count = db.delete("user", "id = ?", new String[]{"1"}); ``` --- ## SQLite性能优化 ### 1. 使用索引 ```java // 创建索引 db.execSQL("CREATE INDEX idx_name ON user(name)"); ``` ### 2. 使用事务 ```java // 批量操作使用事务 db.beginTransaction(); try { for (int i = 0; i < 1000; i++) { db.insert("user", null, values); } db.setTransactionSuccessful(); } finally { db.endTransaction(); } ``` ### 3. 使用预编译语句 ```java // 使用 SQLiteStatement SQLiteStatement stmt = db.compileStatement( "INSERT INTO user (name, email) VALUES (?, ?)"); stmt.bindString(1, "John"); stmt.bindString(2, "john@example.com"); stmt.executeInsert(); stmt.close(); ``` ### 4. 避免 N+1 查询 ```java // ❌ 问题:N+1 查询 List users = getUsers(); for (User user : users) { List orders = getOrdersByUserId(user.getId()); // N 次查询 } // ✅ 解决:使用 JOIN SELECT u.*, o.* FROM user u LEFT JOIN order o ON u.id = o.user_id ``` --- ## SQLite事务 ### 事务使用 ```java // 开始事务 db.beginTransaction(); try { // 执行多个操作 db.insert("user", null, values1); db.insert("user", null, values2); db.insert("user", null, values3); // 标记事务成功 db.setTransactionSuccessful(); } finally { // 结束事务(如果未标记成功,会回滚) db.endTransaction(); } ``` ### 事务优势 ```java // 1. 原子性:要么全部成功,要么全部失败 // 2. 性能:批量操作性能更好 // 3. 一致性:保证数据一致性 ``` --- ## SQLite索引 ### 创建索引 ```java // 单列索引 db.execSQL("CREATE INDEX idx_name ON user(name)"); // 复合索引 db.execSQL("CREATE INDEX idx_name_age ON user(name, age)"); // 唯一索引 db.execSQL("CREATE UNIQUE INDEX idx_email ON user(email)"); ``` ### 索引使用 ```java // 索引会加速查询 // 但会增加写入开销和存储空间 // 适合创建索引的列: // 1. 经常用于 WHERE 条件的列 // 2. 经常用于 JOIN 的列 // 3. 经常用于 ORDER BY 的列 ``` --- ## SQLite最佳实践 ### 1. 使用事务 ```java // 批量操作使用事务 db.beginTransaction(); try { // 批量操作 db.setTransactionSuccessful(); } finally { db.endTransaction(); } ``` ### 2. 及时关闭 Cursor ```java // ✅ 正确 Cursor cursor = db.query(...); try { // 使用 cursor } finally { cursor.close(); } // ❌ 错误:忘记关闭 Cursor cursor = db.query(...); // 使用 cursor // 忘记关闭,可能导致内存泄漏 ``` ### 3. 使用预编译语句 ```java // 重复执行的 SQL 使用预编译语句 SQLiteStatement stmt = db.compileStatement("INSERT INTO user (name) VALUES (?)"); ``` ### 4. 数据库升级 ```java @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 根据版本号升级 if (oldVersion < 2) { // 升级到版本2 } if (oldVersion < 3) { // 升级到版本3 } } ``` --- ## 面试常见问题 ### Q1: SQLite 的特点? **答案:** - 轻量级关系型数据库 - 嵌入式数据库,无需服务器 - 支持 SQL 语法 - 适合移动应用 ### Q2: 如何优化 SQLite 性能? **答案:** 1. 使用索引 2. 使用事务 3. 使用预编译语句 4. 避免 N+1 查询 ### Q3: SQLite 事务的作用? **答案:** 1. 原子性:保证操作要么全部成功,要么全部失败 2. 性能:批量操作性能更好 3. 一致性:保证数据一致性 ### Q4: 什么时候创建索引? **答案:** - 经常用于 WHERE 条件的列 - 经常用于 JOIN 的列 - 经常用于 ORDER BY 的列 --- *最后更新:2024年*