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

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语句

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

http://www.xdnf.cn/news/1018.html

相关文章:

  • 企业微信私域运营,基于http协议实现SCRM+AI完整解决方案
  • autohue.js - 基于 JavaScript 开发的图片背景色提取开源库,能让图片和背景融为一体
  • gbase8s触发器使用
  • CentOS创建swap内存
  • 锂电池4.2V升压24V推荐哪些升压芯片?高效率国产SL4013输入耐压2.7V-25V
  • 黑马点评redis改 part 4
  • List findIntersection getUnion
  • 分别配置Github,Gitee的SSH链接
  • 扩散模型(Diffusion Models)
  • Linux-信号
  • 媒体关注:联易融聚焦AI+业务,重塑供应链金融生态
  • 【k8s】PV,PVC的回收策略——return、recycle、delete
  • 开源模型应用落地-Podcastfy-从文本到声音的智能跃迁-Docker(二)
  • CSS预处理器对比:Sass、Less与Stylus如何选择
  • 如何改电脑网络ip地址完整教程
  • Python常用的第三方模块之数据分析【pdfplumber库、Numpy库、Pandas库、Matplotlib库】
  • Docker 部署 Redis 缓存服务
  • 路由器转发规则设置方法步骤,内网服务器端口怎么让异地连接访问的实现
  • 一键配置多用户VNC远程桌面:自动化脚本详解
  • linux下使用wireshark捕捉snmp报文
  • 开源状态机引擎,在实战中可以放心使用
  • 15.QT-容器类控件|Group Box|Tab Widget|垂直布局|水平布局|网格布局|表单布局|Spacer(C++)
  • Idea 配置 Git
  • Uniapp:swiper(滑块视图容器)
  • 如何将Qt程序打包成应用程序?
  • 流程执行松散,如何强化规范?
  • 【Linux内核设计与实现】第三章——进程管理01
  • 信奥中的数学
  • 构建企业级知识图谱:JanusGraph与Gremlin实战指南
  • C++入门小馆: 深入string类(二)