首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android SQLite CRUD 僅新增有效:資料庫版本號未遞增與操作封裝建議

     編輯:程式設計疑難解答

核心問題

MyDBHelper 建構子傳遞 version = 1 固定不變,修改表結構 (如加欄位) 時 onUpgrade 不會被呼叫,導致實際表結構與代碼預期不符,更新/刪除/查詢 SQL 執行失敗卻被 catch 吞掉。

修正步驟

1. 每次修改 Schema 遞增版本號

public class MyDBHelper extends SQLiteOpenHelper {
    private static final int DB_VERSION = 2; // 修改表結構時 +1
    public MyDBHelper(Context context) {
        super(context, "mvdb.db", null, DB_VERSION);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
        if (oldV < 2) {
            db.execSQL("ALTER TABLE user ADD COLUMN birthday TEXT;");
        }
        // 後續版本繼續加 if (oldV < 3) ...
    }
}

2. 封裝資料庫操作類 (DAO 模式)

public class UserDao {
    private MyDBHelper helper;
    public UserDao(Context ctx) { helper = new MyDBHelper(ctx); }

    public long insert(String code, String name, String birth) {
        SQLiteDatabase db = helper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("ecode", code);
        cv.put("ename", name);
        cv.put("ebirth", birth);
        return db.insert("user", null, cv);
    }

    public int update(String code, String name, String birth) {
        SQLiteDatabase db = helper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("ename", name);
        cv.put("ebirth", birth);
        return db.update("user", cv, "ecode=?", new String[]{code});
    }

    public int delete(String code) {
        SQLiteDatabase db = helper.getWritableDatabase();
        return db.delete("user", "ecode=?", new String[]{code});
    }

    public List query(String keyword) {
        SQLiteDatabase db = helper.getReadableDatabase();
        String sql = "SELECT * FROM user WHERE ecode LIKE ? OR ename LIKE ? OR ebirth LIKE ?";
        String kw = "%" + keyword + "%";
        Cursor c = db.rawQuery(sql, new String[]{kw, kw, kw});
        List list = new ArrayList<>();
        while (c.moveToNext()) {
            list.add(new User(c.getString(0), c.getString(1), c.getString(2)));
        }
        c.close();
        return list;
    }
}

3. Activity 中使用

UserDao dao = new UserDao(this);
// 新增
dao.insert(code, name, birth);
// 更新
dao.update(code, name, birth);
// 刪除
dao.delete(code);
// 查詢
List list = dao.query(keyword);
// 綁定 ListView
ArrayAdapter adapter = new ArrayAdapter<>(this, 
    android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);

原代碼其他錯誤

  • insertData:db.execSQL("insert ... values(?,?)", new String[]{...}) 參數綁定錯誤,應用 ContentValues 或 db.insert。
  • update SQL:where code='...'' 多一個單引號,且欄位名應為 ecode。
  • query:Cursor 未關閉、ListAdapter 變數名衝突、ArrayAdapter 未設定給 ListView。

總結

資料庫版本號必須遞增觸發 onUpgrade,並將 CRUD 封裝為 DAO 類使用 ContentValues/insert/update/delete/query API,避免手拼 SQL 錯誤與資源洩漏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved