当前位置: 首页 > news >正文

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. 最佳实践

  1. 始终关闭Cursor和数据库连接:避免内存泄漏
  2. 使用事务处理批量操作:提高性能
  3. 避免在主线程执行耗时操作:数据库操作应在子线程中进行
  4. 使用参数化查询:防止SQL注入
  5. 考虑使用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");

特点

  1. 动态表结构:不固定表和列,可以在运行时创建任意结构的表
  2. 完整的CRUD操作:提供插入、查询、更新、删除等完整操作
  3. 批量操作支持:支持批量插入数据
  4. 表结构缓存:缓存表结构信息,避免频繁查询系统表
  5. 类型安全:确保操作的表和列存在
  6. 事务支持:批量操作使用事务保证数据一致性
  7. 原始SQL支持:可以直接执行原始SQL语句

这个实现可以根据需要进一步扩展,比如添加索引支持、更复杂的表结构变更等功能。

相关文章:

  • Java函数生成实际应用案例:数据处理流水线
  • # 基于PyTorch的食品图像分类系统:从训练到部署全流程指南
  • 基于javaweb的SpringBoot校园失物招领系统设计与实现(源码+文档+部署讲解)
  • 鸿蒙NEXT开发权限工具类(申请授权相关)(ArkTs)
  • Python-27:游戏英雄升级潜力评估
  • 【TeamFlow】4.3.1 SI单位系统库(Units)
  • 《MySQL 核心技能:SQL 查询与数据库概述》
  • 达梦官方管理工具 SQLark 更新--不仅支持达梦、Oracle、MySQL,还新增 PostgreSQL 数据库!
  • android 发送onkey广播,Android 添加键值并上报从驱动到上层
  • PerfettoSQL
  • 【RAG】一篇文章介绍多模态RAG(MRAG)
  • 电商虚拟户分账系统:破解电商资金管理难题的密钥
  • 蓝牙耳机开发--提示音制作生成的方法
  • 深入探索RAG:用LlamaIndex为大语言模型扩展知识,实现智能检索增强生成
  • Win10 关闭自动更新、关闭自动更新并重启
  • Jetson Orin NX 16G 配置GO1强化学习运行环境
  • 深度学习中的“重参数化”总结
  • 互联网大厂Java面试:软件架构与大型网站架构设计的较量
  • 操作系统-用户级-内核级线程
  • IOT项目——物联网 GPS
  • 小米首次参加上海车展:没有雷军依旧人气爆棚,YU7上市时间未推迟
  • 重庆一幼儿园回应招聘硕士幼教:统一标准,江北区学前教育岗的硬性要求
  • 王毅将出席中国一中亚外长第六次会晤、金砖国家外长会晤和第十五次金砖国家安全事务高级代表会议
  • 神二十发射时间藏着两彩蛋:恰逢东方红一号发射55周年和第十个“中国航天日”
  • 世界读书日|阅读在上海
  • 从香料到文化,跟着陈晓卿寻味厦门