Android使用SQLiteDatabase增删改查(CRUD)的操作教程
作者:百锦再@新空间代码工作室
在 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(); } @Override public void onCreate(SQLiteDatabase db) { // 不在这里创建固定表,通过外部调用createTable方法动态创建 } @Override public 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语句
这个实现可以根据需要进一步扩展,比如添加索引支持、更复杂的表结构变更等功能。
以上就是Android使用SQLiteDatabase增删改查(CRUD)的操作教程的详细内容,更多关于Android SQLiteDatabase增删改查的资料请关注脚本之家其它相关文章!