簡體   English   中英

永遠不會調用SQLiteHelper的onCreate()方法

[英]onCreate() method of SQLiteHelper is never called

我正在使用SQLite在android中創建數據庫。

我編寫了代碼,以在onCreate()方法中創建一個名為products的表。

然后,當我調用add()方法向表中添加一些值時,出現一個錯誤,即沒有這樣的表稱為products

這是我的SQLiteHelper類:

public class MySQLiteHelper extends SQLiteOpenHelper {

    //variable declarations and some code
    ...

    @Override
    public void onCreate(SQLiteDatabase db) {

        // SQL statement to create a products table
        String CREATE_PRODUCTS_TABLE = "CREATE TABLE "+TABLE_NAME+ " ( " +
                "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                "url TEXT, " +
                "title TEXT, " +
                "price INTEGER );";

        // create products table
        db.execSQL(CREATE_PRODUCTS_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

        // Create tables again
        onCreate(db);
    }


void add(String url, String title, String price) {


    this.url = url;
    this.title = title;
    this.price = price;

    // 1. get reference to writable DB
    SQLiteDatabase db = this.getWritableDatabase();

    // 2. create ContentValues to add key "column"/value
    ContentValues values = new ContentValues();
    values.put(KEY_URL, url);
    values.put(KEY_TITLE, title);
    values.put(KEY_PRICE, price);

    // 3. insert
    db.insert(TABLE_NAME, // table
            null, //nullColumnHack
            values); // key/value -> keys = column names/ values = column values

    // 4. close
    db.close();
}

我從一個類似的問題中了解到,onCreate()不是構造函數,僅當數據庫不存在時才調用它,但是在我的情況下也不存在數據庫,那么為什么不調用它呢?

我還了解到,我們需要調用getWritableDatabase()getReadableDatabase()

但是我不確定在我的代碼中在哪里進行這樣的調用。

我試圖將onCreate()中的“表創建代碼” add()方法中。 對於第一次運行,我什么也沒得到,但是從下一次開始,我一直收到“表已存在”的錯誤。

現在,在我調用add()方法插入一些值之前,如何確保只正確創建一次表。 有什么幫助嗎?

編輯:

我的Logcat讀取:

03-07 00:59:22.684    2107-2147/com.example.nikhil.amazon1 W/EGL_emulation﹕ eglSurfaceAttrib not implemented
03-07 00:59:22.684    2107-2147/com.example.nikhil.amazon1 W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa5683060, error=EGL_SUCCESS
03-07 00:59:24.922    2107-2120/com.example.nikhil.amazon1 I/art﹕ Background sticky concurrent mark sweep GC freed 1464(89KB) AllocSpace objects, 7(2MB) LOS objects, 7% free, 9MB/9MB, paused 75.596ms total 203.616ms
03-07 00:59:25.338    2107-2413/com.example.nikhil.amazon1 E/SQLiteLog﹕ (1) no such table: products
03-07 00:59:25.339    2107-2413/com.example.nikhil.amazon1 E/SQLiteDatabase﹕ Error inserting price=   24,599.00 title=Google Nexus 5 D821 (16GB, Black) url=http://www.amazon.in/Google-Nexus-D821-16GB-Black/dp/B00GC1J55C/ref=sr_1_1?s=electronics&ie=UTF8&qid=1421161258&sr=1-1&keywords=Google
    android.database.sqlite.SQLiteException: no such table: products (code 1): , while compiling: INSERT INTO products(price,title,url) VALUES (?,?,?)
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
            at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
            at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
            at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
            at com.example.nikhil.amazon1.MySQLiteHelper.add(MySQLiteHelper.java:86)
            at com.example.nikhil.amazon1.FirstParsing$1.run(FirstParsing.java:71)
            at java.lang.Thread.run(Thread.java:818)

我的問題完全類似於:1) Android SQLiteOpenHelper:未調用onCreate()方法。 為什么?

2) SQLiteOpenHelper無法調用onCreate嗎?

3) 不調用SQLiteOpenHelper“ onCreate”嗎? (該數據庫不存在)

但是我發現很難理解它並將其應用於我的代碼。

這可能有助於未來的發展

MySQLiteHelper-定義數據庫,表等

public class MySQLiteHelper extends SQLiteOpenHelper {

    private static final String FILE_NAME = "application.db";
    private static final int DB_VERSION = 1;
    private final String TAG = MySQLiteHelper.class.getCanonicalName();
    private static SQLiteDatabase database = null;

    public MySQLiteHelper(Context context) {
        super(context, FILE_NAME, null, DB_VERSION);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        //version 1
        database.execSQL(ProductsTbl.CREATE_SQL);
        //can create new tables if necessary, make sure to increase database version

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        Log.i(TAG, "Upgrading from version " + oldVersion + " to version "
                                + newVersion);
        for (int i = oldVersion + 1; i <= newVersion; i++) {
            Log.i(TAG, "version is becoming current " + i);
            switch (i) {
                case 2:
                    db.execSQL(ProductsTbl.CREATE_SQL);
                    break;
            //add more cases for each additional table added

            }
        }
    }

    public static class ProductsTbl {
        public static final String TABLE_NAME = "products";
        public static final String ID = "_id";
        public static final String URL = "url";
        public static final String TITLE = "title";
        public static final String PRICE = "price";
        public static final String[] TABLE_COLUMNS = { ID, URL, TITLE, PRICE };
        public static final String CREATE_SQL = "create table " + TABLE_NAME
                                                                                        + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                                                                                        + URL + " TEXT,"
                                                                                        + TITLE + " TEXT,"
                                                                                        + PRICE + " INTEGER);";
    }

}

MySQLiteDatasource-定義訪問方法,插入,刪除等。

public class MySQLiteDatasource {

    //Database fields
    private SQLiteDatabase database;
    private MySQLiteHelper dbHelper;

    public MySQLiteDatasource(Context context) {
        dbHelper = new MySQLiteHelper(context);
    }

    public void open() throws SQLException {
        database = dbHelper.getWritableDatabase();
    }

    public void close() {
        dbHelper.close();
    }

    public void insertProduct(String url, String title, String price) {
        ContentValues values = new ContentValues();
        values.put(MySQLiteHelper.ProductsTbl.URL, url);
        values.put(MySQLiteHelper.ProductsTbl.TITLE, title);
        values.put(MySQLiteHelper.ProductsTbl.PRICE, price);

        try {
            database.insertOrThrow(MySQLiteHelper.ProductsTbl.TABLE_NAME, null, values);
        } catch (SQLiteConstraintException e) {
            //System.out.println(e);
            Log.e("SQLite Database", "Unable to INSERT into Database, possible duplicate topic already exists.");
        }
    }

}

這是在活動或類似活動中如何使用2個類的方法。

  public static void addProductToDB(String url, String title, String price) {
    MySQLiteDatasource datasource = new MySQLiteDatasource(this);
    datasource.open();
    datasource.insertProduct(url, title, price);
    datasource.close();
  }

您可能還需要研究定義一個Product對象,以保存以后從數據庫中獲取的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM