欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android使用SQLiteDatabase增刪改查(CRUD)的操作教程

 更新時間:2025年04月23日 08:56:00   作者:百錦再@新空間代碼工作室  
在 Android 中使用 SQLiteDatabase 進(jìn)行增刪改查操作是開發(fā)中的核心技能之一,下面我將詳細(xì)說明如何使用 SQLiteDatabase 進(jìn)行 CRUD 操作,需要的朋友可以參考下

1. 初始化數(shù)據(jù)庫

首先需要獲取數(shù)據(jù)庫實(shí)例:

// 創(chuàng)建或打開數(shù)據(jù)庫
DatabaseHelper dbHelper = new DatabaseHelper(context);
SQLiteDatabase db = dbHelper.getWritableDatabase();

// 如果只需要讀取數(shù)據(jù),可以使用
// SQLiteDatabase db = dbHelper.getReadableDatabase();

2. 插入數(shù)據(jù) (Create)

方法一:使用 ContentValues + insert()

ContentValues values = new ContentValues();
values.put("name", "張三");
values.put("age", 25);
values.put("email", "zhangsan@example.com");

// 插入數(shù)據(jù),返回新行的ID,如果插入失敗返回-1
long newRowId = db.insert(
    "users",       // 表名
    null,          // 當(dāng)values為空時,指定可以為null的列名
    values         // 要插入的數(shù)據(jù)
);

if(newRowId == -1) {
    // 插入失敗處理
} else {
    // 插入成功,newRowId是新記錄的主鍵值
}

方法二:直接執(zhí)行SQL

String sql = "INSERT INTO users (name, age, email) VALUES ('張三', 25, 'zhangsan@example.com')";
db.execSQL(sql);

3. 查詢數(shù)據(jù) (Read)

方法一:使用 query() 方法

// 查詢所有列
Cursor cursor = db.query(
    "users",      // 表名
    null,         // 要查詢的列名數(shù)組,null表示所有列
    null,         // WHERE子句,null表示無
    null,         // WHERE子句的參數(shù)
    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"));
    // 處理數(shù)據(jù)...
}

// 記得關(guān)閉Cursor
cursor.close();

方法二:使用 rawQuery() 執(zhí)行原始SQL

String sql = "SELECT * FROM users WHERE age > ?";
Cursor cursor = db.rawQuery(sql, new String[]{"20"});

// 處理Cursor...
cursor.close();

4. 更新數(shù)據(jù) (Update)

方法一:使用 ContentValues + update()

ContentValues values = new ContentValues();
values.put("age", 26);
values.put("email", "new_email@example.com");

// 更新條件
String whereClause = "id = ?";
String[] whereArgs = {"1"};

// 更新數(shù)據(jù),返回受影響的行數(shù)
int count = db.update(
    "users",      // 表名
    values,       // 新值
    whereClause,  // WHERE子句
    whereArgs     // WHERE子句的參數(shù)
);

方法二:直接執(zhí)行SQL

String sql = "UPDATE users SET age = 26, email = 'new_email@example.com' WHERE id = 1";
db.execSQL(sql);

5. 刪除數(shù)據(jù) (Delete)

方法一:使用 delete() 方法

// 刪除條件
String whereClause = "id = ?";
String[] whereArgs = {"1"};

// 刪除數(shù)據(jù),返回被刪除的行數(shù)
int count = db.delete(
    "users",      // 表名
    whereClause,  // WHERE子句
    whereArgs     // WHERE子句的參數(shù)
);

方法二:直接執(zhí)行SQL

String sql = "DELETE FROM users WHERE id = 1";
db.execSQL(sql);

6. 事務(wù)處理

對于批量操作,使用事務(wù)可以提高性能并保證數(shù)據(jù)一致性:

db.beginTransaction();
try {
    // 執(zhí)行多個數(shù)據(jù)庫操作
    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);
    }
    
    // 標(biāo)記事務(wù)為成功
    db.setTransactionSuccessful();
} catch (Exception e) {
    // 處理異常
} finally {
    // 結(jié)束事務(wù)
    db.endTransaction();
}

7. 關(guān)閉數(shù)據(jù)庫

在不再需要數(shù)據(jù)庫連接時,應(yīng)該關(guān)閉它:

db.close();
dbHelper.close();

8. 最佳實(shí)踐

  1. 始終關(guān)閉Cursor和數(shù)據(jù)庫連接:避免內(nèi)存泄漏
  2. 使用事務(wù)處理批量操作:提高性能
  3. 避免在主線程執(zhí)行耗時操作:數(shù)據(jù)庫操作應(yīng)在子線程中進(jìn)行
  4. 使用參數(shù)化查詢:防止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;
    }
    
    // 關(guān)閉數(shù)據(jù)庫幫助類
    public void close() {
        dbHelper.close();
    }
}

以上就是在 Android 中使用 SQLiteDatabase 進(jìn)行增刪改查的詳細(xì)操作。隨著 Android 的發(fā)展,Google 推薦使用 Room 持久化庫來替代直接使用 SQLiteDatabase,它提供了更簡潔的 API 和編譯時 SQL 檢查。

動態(tài)SQLite幫助類實(shí)現(xiàn)

以下是一個改進(jìn)版的SQLite幫助類,不固定表和列結(jié)構(gòu),支持動態(tài)創(chuàng)建表和執(zhí)行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;

    // 表結(jié)構(gòu)緩存: 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) {
        // 不在這里創(chuàng)建固定表,通過外部調(diào)用createTable方法動態(tài)創(chuàng)建
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 可以根據(jù)版本號進(jìn)行表結(jié)構(gòu)遷移
        // 實(shí)際項(xiàng)目中需要更復(fù)雜的升級邏輯
        for (String tableName : tableSchemas.keySet()) {
            db.execSQL("DROP TABLE IF EXISTS " + tableName);
        }
        tableSchemas.clear();
    }

    /**
     * 動態(tài)創(chuàng)建表
     * @param tableName 表名
     * @param columns 列定義map(列名 -> 數(shù)據(jù)類型,如 "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;
    }

    /**
     * 插入數(shù)據(jù)
     * @param tableName 表名
     * @param values 數(shù)據(jù)鍵值對
     * @return 新插入行的ID
     */
    public long insert(String tableName, ContentValues values) {
        validateTable(tableName);
        return db.insert(tableName, null, values);
    }

    /**
     * 批量插入數(shù)據(jù)
     * @param tableName 表名
     * @param valuesList 數(shù)據(jù)鍵值對列表
     * @return 成功插入的數(shù)量
     */
    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;
    }

    /**
     * 查詢數(shù)據(jù)
     * @param tableName 表名
     * @param columns 要查詢的列
     * @param selection WHERE條件
     * @param selectionArgs WHERE條件參數(shù)
     * @param orderBy 排序
     * @return 查詢結(jié)果的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);
    }

    /**
     * 查詢所有數(shù)據(jù)
     * @param tableName 表名
     * @return 包含所有行的Cursor
     */
    public Cursor queryAll(String tableName) {
        return query(tableName, null, null, null, null);
    }

    /**
     * 更新數(shù)據(jù)
     * @param tableName 表名
     * @param values 要更新的值
     * @param selection WHERE條件
     * @param selectionArgs WHERE條件參數(shù)
     * @return 受影響的行數(shù)
     */
    public int update(String tableName, ContentValues values, String selection,
                     String[] selectionArgs) {
        validateTable(tableName);
        return db.update(tableName, values, selection, selectionArgs);
    }

    /**
     * 刪除數(shù)據(jù)
     * @param tableName 表名
     * @param selection WHERE條件
     * @param selectionArgs WHERE條件參數(shù)
     * @return 受影響的行數(shù)
     */
    public int delete(String tableName, String selection, String[] selectionArgs) {
        validateTable(tableName);
        return db.delete(tableName, selection, selectionArgs);
    }

    /**
     * 刪除表中所有數(shù)據(jù)
     * @param tableName 表名
     * @return 受影響的行數(shù)
     */
    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);
        }
    }

    /**
     * 執(zhí)行原始SQL查詢
     * @param sql SQL語句
     * @param selectionArgs 參數(shù)
     * @return 結(jié)果Cursor
     */
    public Cursor rawQuery(String sql, String[] selectionArgs) {
        return db.rawQuery(sql, selectionArgs);
    }

    /**
     * 執(zhí)行原始SQL語句
     * @param sql SQL語句
     */
    public void execSQL(String sql) {
        db.execSQL(sql);
    }

    /**
     * 關(guān)閉數(shù)據(jù)庫連接
     */
    public void closeDB() {
        if (db != null && db.isOpen()) {
            db.close();
        }
    }

    /**
     * 驗(yàn)證表是否存在
     */
    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);

// 創(chuàng)建表
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");

// 插入數(shù)據(jù)
ContentValues values = new ContentValues();
values.put("name", "張三");
values.put("age", 25);
values.put("email", "zhangsan@example.com");
long id = dbHelper.insert("users", values);

// 查詢數(shù)據(jù)
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"));
    // 處理數(shù)據(jù)...
}
cursor.close();

// 更新數(shù)據(jù)
ContentValues updateValues = new ContentValues();
updateValues.put("age", 26);
dbHelper.update("users", updateValues, "name = ?", new String[]{"張三"});

// 刪除數(shù)據(jù)
dbHelper.delete("users", "age < ?", new String[]{"18"});

// 添加新列
dbHelper.addColumn("users", "address", "TEXT");

// 刪除表
dbHelper.dropTable("users");

特點(diǎn)

  1. 動態(tài)表結(jié)構(gòu):不固定表和列,可以在運(yùn)行時創(chuàng)建任意結(jié)構(gòu)的表
  2. 完整的CRUD操作:提供插入、查詢、更新、刪除等完整操作
  3. 批量操作支持:支持批量插入數(shù)據(jù)
  4. 表結(jié)構(gòu)緩存:緩存表結(jié)構(gòu)信息,避免頻繁查詢系統(tǒng)表
  5. 類型安全:確保操作的表和列存在
  6. 事務(wù)支持:批量操作使用事務(wù)保證數(shù)據(jù)一致性
  7. 原始SQL支持:可以直接執(zhí)行原始SQL語句

這個實(shí)現(xiàn)可以根據(jù)需要進(jìn)一步擴(kuò)展,比如添加索引支持、更復(fù)雜的表結(jié)構(gòu)變更等功能。

以上就是Android使用SQLiteDatabase增刪改查(CRUD)的操作教程的詳細(xì)內(nèi)容,更多關(guān)于Android SQLiteDatabase增刪改查的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android WiFi熱點(diǎn)開發(fā)的示例代碼

    Android WiFi熱點(diǎn)開發(fā)的示例代碼

    這篇文章主要介紹了Android WiFi熱點(diǎn)開發(fā)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Android GuideView實(shí)現(xiàn)首次登陸引導(dǎo)

    Android GuideView實(shí)現(xiàn)首次登陸引導(dǎo)

    這篇文章主要為大家詳細(xì)介紹了Android GuideView實(shí)現(xiàn)首次登陸引導(dǎo),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • 代碼從windows下visual studio到andriod平臺遷移實(shí)現(xiàn)步驟

    代碼從windows下visual studio到andriod平臺遷移實(shí)現(xiàn)步驟

    這篇文章主要介紹了代碼從windows下visual studio到andriod平臺遷移的修改記錄的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Android開發(fā)之WebView組件的使用解析

    Android開發(fā)之WebView組件的使用解析

    WebView 類是 WebKit 模塊 Java 層的視圖類, 所有需要使用 Web 瀏覽功能的Android應(yīng)用程序都要創(chuàng)建該視圖對象顯示和處理請求的網(wǎng)絡(luò)資源,接下來將詳細(xì)介紹,需要了解的朋友可以參考下
    2012-12-12
  • 深入理解Android手勢識別

    深入理解Android手勢識別

    這篇文章主要幫助大家深入理解Android手勢識別,創(chuàng)建手勢偵聽對象,設(shè)置手勢識別,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Android 10 啟動分析之init語法詳解

    Android 10 啟動分析之init語法詳解

    這篇文章主要為大家介紹了Android 10 啟動分析之init語法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • android讀寫cookie的方法示例

    android讀寫cookie的方法示例

    這篇文章主要介紹了android讀寫cookie的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Android實(shí)現(xiàn)USB掃碼槍獲取掃描內(nèi)容

    Android實(shí)現(xiàn)USB掃碼槍獲取掃描內(nèi)容

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)USB掃碼槍獲取掃描內(nèi)容,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • ViewPager的setOnPageChangeListener方法詳解

    ViewPager的setOnPageChangeListener方法詳解

    這篇文章主要介紹了ViewPager的setOnPageChangeListener方法詳解,非常不錯,具有參考解決借鑒價值,需要的朋友可以參考下
    2016-12-12
  • Android  Activity生命周期和堆棧管理的詳解

    Android Activity生命周期和堆棧管理的詳解

    這篇文章主要介紹了Android Activity生命周期和堆棧管理的詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07

最新評論