知識中心

Android 資料管理開發:SQLite 本地資料庫與報表生成全攻略

本文深入解析 Android SQLite 資料庫開發的核心技巧,包括表設計、CRUD 操作、索引最佳化、事務處理及批次操作,並詳細演示如何基於查詢結果生成動態報表(折線圖、CSV 匯出)。結合 Room 持久化庫的實踐要點,幫助開發者構建高效能、易維護的本地資料管理系統,適用於電商、社交、IoT 等多類應用場景。

知識中心 2026-04-17 穩格科技
文章正文知識中心

在 Android 應用開發中,本地資料管理是構建離線功能、提升使用者體驗的核心環節。SQLite 作為輕量級嵌入式資料庫,憑藉其零配置、事務支援和穩妥查詢能力,成為儲存結構化資料的可選方案。結合報表生成技術,開發者可實現資料視覺化、統計分析及匯出功能,滿足業務監控、使用者行為分析等場景需求。本文將系統講解 SQLite 資料庫的 CRUD 操作、效能最佳化策略,以及如何基於本地資料生成動態報表,助力開發者打造穩定、穩妥的資料驅動型應用。


一、SQLite 資料庫基礎與核心操作

1. SQLite 優勢與適用場景

  • 輕量級:資料庫檔案僅需一個 .db 檔案,無需單獨伺服器程序。

  • ACID 相容:支援事務(Transaction),有助於支援資料一致性。

  • 跨平臺:資料檔案可直接在 iOS、Web 等平臺複用。

  • 典型場景:使用者配置儲存、離線快取、本地日誌記錄、小型 CRM 系統。

2. 資料庫建立與表設計

  • 透過 SQLiteOpenHelper 管理生命週期:

    javapublic class DatabaseHelper extends SQLiteOpenHelper {    private static final String DB_NAME = "app_data.db";    private static final int DB_VERSION = 1;    public DatabaseHelper(Context context) {        super(context, DB_NAME, null, DB_VERSION);    }    @Override    public void onCreate(SQLiteDatabase db) {        // 建立使用者表        db.execSQL("CREATE TABLE users (" +                "id INTEGER PRIMARY KEY AUTOINCREMENT," +                "name TEXT NOT NULL," +                "email TEXT UNIQUE," +                "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        // 版本升級時遷移資料        db.execSQL("DROP TABLE IF EXISTS users");        onCreate(db);    }}

3. CRUD 操作實戰

插入資料(Insert)

javapublic long addUser(String name, String email) {    SQLiteDatabase db = getWritableDatabase();    ContentValues values = new ContentValues();    values.put("name", name);    values.put("email", email);    return db.insert("users", null, values); // 返回行 ID,失敗返回 -1}

查詢資料(Query)

javapublic List<User> getAllUsers() {    List<User> users = new ArrayList<>();    SQLiteDatabase db = getReadableDatabase();    Cursor cursor = db.query("users",             new String[]{"id", "name", "email"}, // 查詢列            null, null, null, null, "created_at DESC"); // 按時間降序    while (cursor.moveToNext()) {        long id = cursor.getLong(cursor.getColumnIndex("id"));        String name = cursor.getString(cursor.getColumnIndex("name"));        users.add(new User(id, name, email));    }    cursor.close();    return users;}

更新與刪除(Update/Delete)

java// 更新使用者郵箱public int updateUserEmail(long id, String newEmail) {    SQLiteDatabase db = getWritableDatabase();    ContentValues values = new ContentValues();    values.put("email", newEmail);    return db.update("users", values, "id=?", new String[]{String.valueOf(id)});}// 刪除使用者public int deleteUser(long id) {    SQLiteDatabase db = getWritableDatabase();    return db.delete("users", "id=?", new String[]{String.valueOf(id)});}

二、SQLite 效能最佳化策略

1. 索引最佳化

  • 為高頻查詢欄位新增索引:

    java@Overridepublic void onCreate(SQLiteDatabase db) {    db.execSQL("CREATE TABLE users (...)");    db.execSQL("CREATE INDEX idx_user_email ON users(email)"); // 加速郵箱查詢}
  • 避免過度索引:索引會佔用儲存空間並降低寫入效能,僅在 WHERE、JOIN 條件欄位上新增。

2. 批次操作與事務

  • 使用事務包裹批次插入:

    javapublic void batchInsertUsers(List<User> userList) {    SQLiteDatabase db = getWritableDatabase();    db.beginTransaction();    try {        for (User user : userList) {            ContentValues values = new ContentValues();            values.put("name", user.getName());            db.insert("users", null, values);        }        db.setTransactionSuccessful(); // 標記事務成功    } finally {        db.endTransaction(); // 提交或回滾    }}

3. 查詢最佳化技巧

  • 避免 SELECT *:僅查詢需要的列,減少 I/O 開銷。

  • 使用 LIMIT 分頁:大資料集查詢時限制返回行數。

  • 啟用 WAL 模式(Android 7.0+):

    java// 在 DatabaseHelper 的建構函式中啟用public DatabaseHelper(Context context) {    super(context, DB_NAME, null, DB_VERSION);    // 開啟 WAL 模式提升併發效能    SQLiteDatabase.releaseMemory(); // 可選:釋放快取}

三、基於 SQLite 的報表生成實現

1. 報表需求分析

  • 常見型別:銷售趨勢圖、使用者活躍度熱力圖、庫存檔點表。

  • 資料來源:SQLite 查詢結果 + 時間聚合(如按日/月統計)。

  • 輸出格式:RecyclerView 列表、MPAndroidChart 圖表、CSV/Excel 匯出。

2. 動態報表生成示例

步驟 1:聚合查詢資料

java// 查詢每日新增使用者數(按建立日期分組)public List<DailyUserCount> getDailyUserCounts() {    List<DailyUserCount> result = new ArrayList<>();    SQLiteDatabase db = getReadableDatabase();    String sql = "SELECT strftime('%Y-%m-%d', created_at) AS date, " +                 "COUNT(*) AS count FROM users GROUP BY date ORDER BY date";    Cursor cursor = db.rawQuery(sql, null);    while (cursor.moveToNext()) {        String date = cursor.getString(cursor.getColumnIndex("date"));        int count = cursor.getInt(cursor.getColumnIndex("count"));        result.add(new DailyUserCount(date, count));    }    cursor.close();    return result;}

步驟 2:使用 MPAndroidChart 繪製折線圖

java// 在 Activity/Fragment 中繫結資料List<DailyUserCount> dataList = dbHelper.getDailyUserCounts();List<Entry> entries = new ArrayList<>();for (int i = 0; i < dataList.size(); i++) {    entries.add(new Entry(i, dataList.get(i).getCount()));}LineDataSet dataSet = new LineDataSet(entries, "每日新增使用者");LineChart chart = findViewById(R.id.chart);chart.setData(new LineData(dataSet));chart.invalidate(); // 重新整理圖表

步驟 3:匯出 CSV 檔案

javapublic void exportUsersToCsv(Context context) {    List<User> users = dbHelper.getAllUsers();    StringBuilder csvContent = new StringBuilder("id,name,email,created_at\n");    for (User user : users) {        csvContent.append(user.getId()).append(",")                 .append(user.getName()).append(",")                 .append(user.getEmail()).append(",")                 .append(user.getCreatedAt()).append("\n");    }    // 儲存到應用目錄    File file = new File(context.getExternalFilesDir(null), "users_export.csv");    try (FileOutputStream fos = new FileOutputStream(file)) {        fos.write(csvContent.toString().getBytes());        Toast.makeText(context, "匯出成功: " + file.getAbsolutePath(), Toast.LENGTH_LONG).show();    } catch (IOException e) {        e.printStackTrace();    }}

四、高階場景與擴充套件

1. 多表關聯查詢

java// 查詢使用者及其訂單資訊(假設存在 orders 表)public List<UserWithOrders> getUsersWithOrders() {    List<UserWithOrders> result = new ArrayList<>();    SQLiteDatabase db = getReadableDatabase();    String sql = "SELECT u.id, u.name, o.order_id, o.amount " +                 "FROM users u LEFT JOIN orders o ON u.id = o.user_id";    Cursor cursor = db.rawQuery(sql, null);    // 按使用者 ID 分組處理(需在程式碼中實現邏輯)    // ...    return result;}

2. 使用 Room 持久化庫(推薦)

  • 優勢:編譯時 SQL 校驗、LiveData 支援、簡化樣板程式碼。

  • 示例程式碼:

    kotlin@Entitydata class User(    @PrimaryKey val id: Long,    val name: String,    val email: String)@Daointerface UserDao {    @Query("SELECT * FROM user")    fun getAll(): LiveData<List<User>>    @Insert    suspend fun insert(user: User)}@Database(entities = [User::class], version = 1)abstract class AppDatabase : RoomDatabase() {    abstract fun userDao(): UserDao}

提交專案需求

留下聯絡方式和需求簡述,便於我們判斷技術方向、交付範圍和溝通方式。

線上諮詢
電話諮詢
13910119357
微信諮詢
WhatsApp
穩格科技 WhatsApp 二維碼 掃碼或點選聯絡
回到頂部