SQLiteDatabase 增删改查(CRUD)详细操作
文章目录
- 1. 初始化数据库
- 2. 插入数据 (Create)
- 方法一:使用 ContentValues + insert()
- 方法二:直接执行SQL
- 3. 查询数据 (Read)
- 方法一:使用 query() 方法
- 方法二:使用 rawQuery() 执行原始SQL
- 4. 更新数据 (Update)
- 方法一:使用 ContentValues + update()
- 方法二:直接执行SQL
- 5. 删除数据 (Delete)
- 方法一:使用 delete() 方法
- 方法二:直接执行SQL
- 6. 事务处理
- 7. 关闭数据库
- 8. 最佳实践
- 完整示例
- 动态SQLite帮助类实现
- 使用示例
- 特点

在 Android 中使用 SQLiteDatabase 进行增删改查操作是开发中的核心技能之一。下面我将详细说明如何使用 SQLiteDatabase 进行 CRUD 操作。
1. 初始化数据库
首先需要获取数据库实例:
// 创建或打开数据库
DatabaseHelper dbHelper = new DatabaseHelper(context);
SQLiteDatabase db = dbHelper.getWritableDatabase();// 如果只需要读取数据,可以使用
// SQLiteDatabase db = dbHelper.getReadableDatabase();
2. 插入数据 (Create)
方法一:使用 ContentValues + insert()
ContentValues values = new ContentValues();
values.put("name", "张三");
values.put("age", 25);
values.put("email", "zhangsan@example.com");// 插入数据,返回新行的ID,如果插入失败返回-1
long newRowId = db.insert("users", // 表名null, // 当values为空时,指定可以为null的列名values // 要插入的数据
);if(newRowId == -1) {// 插入失败处理
} else {// 插入成功,newRowId是新记录的主键值
}
方法二:直接执行SQL
String sql = "INSERT INTO users (name, age, email) VALUES ('张三', 25, 'zhangsan@example.com')";
db.execSQL(sql);
3. 查询数据 (Read)
方法一:使用 query() 方法
// 查询所有列
Cursor cursor = db.query("users", // 表名null, // 要查询的列名数组,null表示所有列null, // WHERE子句,null表示无null, // WHERE子句的参数null, // GROUP BY子句null, // HAVING子句"age DESC" // ORDER BY子句
);// 带条件的查询
String[] columns = {"name", "age"};
String selection = "age > ?";
String[] selectionArgs = {"20"};
String orderBy = "name ASC";Cursor cursor = db.query("users",columns,selection,selectionArgs,null,null,orderBy
);// 遍历Cursor
while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));int age = cursor.getInt(cursor.getColumnIndexOrThrow("age"));// 处理数据...
}// 记得关闭Cursor
cursor.close();
方法二:使用 rawQuery() 执行原始SQL
String sql = "SELECT * FROM users WHERE age > ?";
Cursor cursor = db.rawQuery(sql, new String[]{"20"});// 处理Cursor...
cursor.close();
4. 更新数据 (Update)
方法一:使用 ContentValues + update()
ContentValues values = new ContentValues();
values.put("age", 26);
values.put("email", "new_email@example.com");// 更新条件
String whereClause = "id = ?";
String[] whereArgs = {"1"};// 更新数据,返回受影响的行数
int count = db.update("users", // 表名values, // 新值whereClause, // WHERE子句whereArgs // WHERE子句的参数
);
方法二:直接执行SQL
String sql = "UPDATE users SET age = 26, email = 'new_email@example.com' WHERE id = 1";
db.execSQL(sql);
5. 删除数据 (Delete)
方法一:使用 delete() 方法
// 删除条件
String whereClause = "id = ?";
String[] whereArgs = {"1"};// 删除数据,返回被删除的行数
int count = db.delete("users", // 表名whereClause, // WHERE子句whereArgs // WHERE子句的参数
);
方法二:直接执行SQL
String sql = "DELETE FROM users WHERE id = 1";
db.execSQL(sql);
6. 事务处理
对于批量操作,使用事务可以提高性能并保证数据一致性:
db.beginTransaction();
try {// 执行多个数据库操作for (int i = 0; i < 100; i++) {ContentValues values = new ContentValues();values.put("name", "User " + i);values.put("age", i % 50);db.insert("users", null, values);}// 标记事务为成功db.setTransactionSuccessful();
} catch (Exception e) {// 处理异常
} finally {// 结束事务db.endTransaction();
}
7. 关闭数据库
在不再需要数据库连接时,应该关闭它:
db.close();
dbHelper.close();
8. 最佳实践
- 始终关闭Cursor和数据库连接:避免内存泄漏
- 使用事务处理批量操作:提高性能
- 避免在主线程执行耗时操作:数据库操作应在子线程中进行
- 使用参数化查询:防止SQL注入
- 考虑使用Room:Android官方推荐的SQLite ORM库
完整示例
public class UserDao {private DatabaseHelper dbHelper;public UserDao(Context context) {dbHelper = new DatabaseHelper(context);}// 添加用户public long addUser(User user) {SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put("name", user.getName());values.put("age", user.getAge());values.put("email", user.getEmail());long id = db.insert("users", null, values);db.close();return id;}// 获取所有用户public List<User> getAllUsers() {List<User> userList = new ArrayList<>();SQLiteDatabase db = dbHelper.getReadableDatabase();Cursor cursor = db.query("users", null, null, null, null, null, "name ASC");while (cursor.moveToNext()) {User user = new User();user.setId(cursor.getInt(cursor.getColumnIndexOrThrow("id")));user.setName(cursor.getString(cursor.getColumnIndexOrThrow("name")));user.setAge(cursor.getInt(cursor.getColumnIndexOrThrow("age")));user.setEmail(cursor.getString(cursor.getColumnIndexOrThrow("email")));userList.add(user);}cursor.close();db.close();return userList;}// 更新用户public int updateUser(User user) {SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put("name", user.getName());values.put("age", user.getAge());values.put("email", user.getEmail());int count = db.update("users",values,"id = ?",new String[]{String.valueOf(user.getId())});db.close();return count;}// 删除用户public int deleteUser(int userId) {SQLiteDatabase db = dbHelper.getWritableDatabase();int count = db.delete("users","id = ?",new String[]{String.valueOf(userId)});db.close();return count;}// 关闭数据库帮助类public void close() {dbHelper.close();}
}
以上就是在 Android 中使用 SQLiteDatabase 进行增删改查的详细操作。随着 Android 的发展,Google 推荐使用 Room 持久化库来替代直接使用 SQLiteDatabase,它提供了更简洁的 API 和编译时 SQL 检查。
动态SQLite帮助类实现
以下是一个改进版的SQLite帮助类,不固定表和列结构,支持动态创建表和执行CRUD操作:
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class DynamicDBHelper extends SQLiteOpenHelper {private static final String TAG = "DynamicDBHelper";private static final String DATABASE_NAME = "dynamic_db";private static final int DATABASE_VERSION = 1;private static DynamicDBHelper instance;private SQLiteDatabase db;// 表结构缓存: key=表名, value=列定义map(列名->类型)private Map<String, Map<String, String>> tableSchemas = new HashMap<>();// 单例模式public static synchronized DynamicDBHelper getInstance(Context context) {if (instance == null) {instance = new DynamicDBHelper(context.getApplicationContext());}return instance;}private DynamicDBHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);db = getWritableDatabase();}@Overridepublic void onCreate(SQLiteDatabase db) {// 不在这里创建固定表,通过外部调用createTable方法动态创建}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 可以根据版本号进行表结构迁移// 实际项目中需要更复杂的升级逻辑for (String tableName : tableSchemas.keySet()) {db.execSQL("DROP TABLE IF EXISTS " + tableName);}tableSchemas.clear();}/*** 动态创建表* @param tableName 表名* @param columns 列定义map(列名 -> 数据类型,如 "TEXT", "INTEGER"等)* @param primaryKey 主键列名(可选)*/public void createTable(String tableName, Map<String, String> columns, String primaryKey) {if (tableExists(tableName)) {Log.w(TAG, "Table " + tableName + " already exists");return;}StringBuilder sql = new StringBuilder("CREATE TABLE " + tableName + " (");// 添加列定义for (Map.Entry<String, String> entry : columns.entrySet()) {String columnName = entry.getKey();String columnType = entry.getValue();sql.append(columnName).append(" ").append(columnType).append(", ");}// 添加主键if (primaryKey != null && !primaryKey.isEmpty()) {sql.append("PRIMARY KEY (").append(primaryKey).append(")");} else {// 移除最后的逗号和空格sql.delete(sql.length() - 2, sql.length());}sql.append(")");db.execSQL(sql.toString());tableSchemas.put(tableName, new HashMap<>(columns));Log.d(TAG, "Table created: " + tableName);}/*** 检查表是否存在*/public boolean tableExists(String tableName) {Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name=?",new String[]{tableName});boolean exists = cursor.getCount() > 0;cursor.close();return exists;}/*** 插入数据* @param tableName 表名* @param values 数据键值对* @return 新插入行的ID*/public long insert(String tableName, ContentValues values) {validateTable(tableName);return db.insert(tableName, null, values);}/*** 批量插入数据* @param tableName 表名* @param valuesList 数据键值对列表* @return 成功插入的数量*/public int bulkInsert(String tableName, List<ContentValues> valuesList) {validateTable(tableName);int count = 0;try {db.beginTransaction();for (ContentValues values : valuesList) {if (db.insert(tableName, null, values) != -1) {count++;}}db.setTransactionSuccessful();} finally {db.endTransaction();}return count;}/*** 查询数据* @param tableName 表名* @param columns 要查询的列* @param selection WHERE条件* @param selectionArgs WHERE条件参数* @param orderBy 排序* @return 查询结果的Cursor*/public Cursor query(String tableName, String[] columns, String selection,String[] selectionArgs, String orderBy) {validateTable(tableName);return db.query(tableName, columns, selection, selectionArgs,null, null, orderBy);}/*** 查询所有数据* @param tableName 表名* @return 包含所有行的Cursor*/public Cursor queryAll(String tableName) {return query(tableName, null, null, null, null);}/*** 更新数据* @param tableName 表名* @param values 要更新的值* @param selection WHERE条件* @param selectionArgs WHERE条件参数* @return 受影响的行数*/public int update(String tableName, ContentValues values, String selection,String[] selectionArgs) {validateTable(tableName);return db.update(tableName, values, selection, selectionArgs);}/*** 删除数据* @param tableName 表名* @param selection WHERE条件* @param selectionArgs WHERE条件参数* @return 受影响的行数*/public int delete(String tableName, String selection, String[] selectionArgs) {validateTable(tableName);return db.delete(tableName, selection, selectionArgs);}/*** 删除表中所有数据* @param tableName 表名* @return 受影响的行数*/public int deleteAll(String tableName) {return delete(tableName, null, null);}/*** 删除表* @param tableName 表名*/public void dropTable(String tableName) {if (tableExists(tableName)) {db.execSQL("DROP TABLE " + tableName);tableSchemas.remove(tableName);Log.d(TAG, "Table dropped: " + tableName);}}/*** 添加列* @param tableName 表名* @param columnName 列名* @param columnType 列类型*/public void addColumn(String tableName, String columnName, String columnType) {validateTable(tableName);if (!tableSchemas.get(tableName).containsKey(columnName)) {db.execSQL("ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + columnType);tableSchemas.get(tableName).put(columnName, columnType);Log.d(TAG, "Column " + columnName + " added to table " + tableName);} else {Log.w(TAG, "Column " + columnName + " already exists in table " + tableName);}}/*** 执行原始SQL查询* @param sql SQL语句* @param selectionArgs 参数* @return 结果Cursor*/public Cursor rawQuery(String sql, String[] selectionArgs) {return db.rawQuery(sql, selectionArgs);}/*** 执行原始SQL语句* @param sql SQL语句*/public void execSQL(String sql) {db.execSQL(sql);}/*** 关闭数据库连接*/public void closeDB() {if (db != null && db.isOpen()) {db.close();}}/*** 验证表是否存在*/private void validateTable(String tableName) {if (!tableSchemas.containsKey(tableName)) {throw new IllegalArgumentException("Table " + tableName + " does not exist");}}/*** 获取表的列信息* @param tableName 表名* @return 列名到类型的映射*/public Map<String, String> getTableColumns(String tableName) {validateTable(tableName);return new HashMap<>(tableSchemas.get(tableName));}
}
使用示例
// 初始化
DynamicDBHelper dbHelper = DynamicDBHelper.getInstance(context);// 创建表
Map<String, String> columns = new HashMap<>();
columns.put("id", "INTEGER");
columns.put("name", "TEXT");
columns.put("age", "INTEGER");
columns.put("email", "TEXT");
dbHelper.createTable("users", columns, "id");// 插入数据
ContentValues values = new ContentValues();
values.put("name", "张三");
values.put("age", 25);
values.put("email", "zhangsan@example.com");
long id = dbHelper.insert("users", values);// 查询数据
Cursor cursor = dbHelper.query("users", null, "age > ?", new String[]{"20"}, "name ASC");
while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndex("name"));int age = cursor.getInt(cursor.getColumnIndex("age"));// 处理数据...
}
cursor.close();// 更新数据
ContentValues updateValues = new ContentValues();
updateValues.put("age", 26);
dbHelper.update("users", updateValues, "name = ?", new String[]{"张三"});// 删除数据
dbHelper.delete("users", "age < ?", new String[]{"18"});// 添加新列
dbHelper.addColumn("users", "address", "TEXT");// 删除表
dbHelper.dropTable("users");
特点
- 动态表结构:不固定表和列,可以在运行时创建任意结构的表
- 完整的CRUD操作:提供插入、查询、更新、删除等完整操作
- 批量操作支持:支持批量插入数据
- 表结构缓存:缓存表结构信息,避免频繁查询系统表
- 类型安全:确保操作的表和列存在
- 事务支持:批量操作使用事务保证数据一致性
- 原始SQL支持:可以直接执行原始SQL语句
这个实现可以根据需要进一步扩展,比如添加索引支持、更复杂的表结构变更等功能。