31

私がフォローしているチュートリアルでは、onUpgrade -> 存在する場合はテーブルを削除してから、テーブルを再作成します。

これの目的は何ですか?

private static class DbHelper extends SQLiteOpenHelper{

    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
                KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                KEY_NAME + " TEXT NOT NULL, " +
                KEY_HOTNESS + " TEXT NOT NULL);"
        );  
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
        onCreate(db);
    }       
}
4

5 に答える 5

32

Android アプリケーションで最も一般的な方法は、データベースのアップグレードが必要なときにユーザーを「再ログイン」することです。また、ローカル データベースはサーバー側アプリケーションにあるものだけをミラーリングする必要があることを考えると、あるバージョンから別のバージョンへの移行を慎重に計画するよりも、データベースを削除して再作成し、サーバーから再設定する方がはるかに簡単です。

これは確かに最善の方法ではありませんが、より簡単です。

移行 (古いバージョンのデータベースから新しいバージョンへの変更) を実装する方法の例を作成するには

DbHelper クラスで、データベースがバージョン 1 であると定義したとします。アプリケーションの新しいバージョン (バージョン 2) では、テーブルの 1 つにさらにいくつかの列が必要です。

したがって、テーブルをアップグレードし、ALTER TABLE {tableName} ADD COLUMN COLNew {type}; を介して列を追加する必要があります。

このリンクを確認してください-> sqlite のテーブルに新しい列を挿入しますか?

そのため、onUpgrade()メソッドは次を追加してその変更を反映する必要があります。

 @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    switch(oldVersion){
        case 1:
            db.execSQL("ALTER TABLE " + DATABASE_TABLE + " ADD COLUMN " + NEW_COLUMN_NAME + TYPE);
    }
}  
于 2013-11-05T15:53:08.023 に答える
32

アップグレードするときは、データベースに列を追加するか、テーブルを追加する必要があることに同意します。onupgrade のサンプルのほとんどは、実際にはひどいものです。なぜなら、このデータをすべて削除してからテーブルを再作成しているからです。Adams Incremental Update Methodと呼んでいるこのブログ エントリを見つけました。また、ユーザーが各リリースでアプリをアップグレードしていない可能性がある状況にも対処します。

これは、テーブルを削除しない sqlite onupgrade に関する優れたブログです。

于 2013-11-07T13:17:02.317 に答える
3

作成するアプローチの種類と、データの重要性、テーブルの複雑さによって異なります。例: アプリが何度もアップグレードされ、テーブル構造が何度も変更された場合、db のすべてのバージョンの構造を変更するコードを記述するよりも、テーブルを削除して再作成する方が適切です。このアプローチでは、サーバー側にあるデータをバックアップできることを確認して、問題がないようにする必要があります。

私の経験から:将来さらに変更がある可能性があると判断できる場合は再作成する方が良いですが、そうでない場合はかなり複雑になります

于 2013-11-05T16:09:33.460 に答える
2

清々しいスタートです。メソッド onCreate には現在有効なデータベース構造があります。アプリをインストールするユーザーは、このメソッドを実行します。アップグレード中のユーザーの場合、メソッド onUpgrade が実行され、DROP TABLE IF EXIST はクリーンなスタートです。古いテーブルと新しいテーブルの構造が異なる場合に備えて、削除してから onCreate メソッドで再作成します。お役に立てれば!:)

于 2013-11-05T15:59:56.817 に答える
0

テーブル データを維持したい場合は、CSV ファイルにダンプし、テーブルの作成後に INSERT で戻すことができます。(データをサーバーにダンプする必要はありません) データをダンプするためのサンプル コードを次に示します。ファイル名をテーブル名に設定できます。カーソルは getAll ステートメントから作成されます

public boolean createCsvSaveToFile(Cursor cursor, String fileName) throws IOException {
    String csv = "";
    int colunmCount = cursor.getColumnCount();
    /* check if extarnal drive is readerble */
    if (!isExternalStorageWritable()) {
        fileError = "can not save to external storage";
        fileinfo = "Please mount your SD card";
        return false;
    } else {
        /* create the CSV */
        for (int i = 0; i < colunmCount; i++) {
            csv += QUOTES + cursor.getColumnName(i).toString() + QUOTES + INNER_DELIMITER;
        }
        csv = csv.replaceAll(",$", "");
        csv += LINE_END;
        if (cursor.moveToFirst()) {
            do {
                for (int i = 0; i < colunmCount; i++) {//GET COLUNM values
                    csv += QUOTES + cursor.getString(i) + QUOTES + INNER_DELIMITER;
                }
                csv = csv.replaceAll(",$", "");
                csv += LINE_END;
            } while (cursor.moveToNext());
        }
        /* save file */
        File file = getDataDir(fileName);
        FileOutputStream out = new FileOutputStream(file);
        out.write(csv.getBytes());
        out.flush();
        out.close();
        return true;
    }
}

これは、データを挿入するためのサンプル コードです。CSVファイル名がテーブル名と同じであると仮定

private void readFromFile(SQLiteDatabase database, File file) {
    boolean hasColunms = false;
    String tableName = file.getName().replaceAll(".csv$", "");
    String sql;
    String colunmNames = "";
    String colunmValues;
    try {
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;
        while ((line = br.readLine()) != null) {
            if (!hasColunms ) {
                /* get column names */
                line = line.replaceAll("\"", "");
                colunmNames = line;
                hasColunms = true;
            } else {
                line = line.replaceAll("\"", "'");
                colunmValues = line;
                sql = "INSERT INTO " + tableName + " (" + colunmNames + ") VALUES (" + colunmValues + ")";
                database.execSQL(sql);
            }
        }
        br.close();
    } catch (IOException e) {
        database.close();
        /* You may need to add proper error handling here
    }

多くのcsvファイルをループするには、次のコードを使用できます

public boolean csvTodatabase(SQLiteDatabase database) {
    FileStuff f = new FileStuff();
    File time;
    /* check if extarnal drive is readerble */
    if (!f.isExternalStorageReadable()) {
        f.fileError = "can not read external storage";
        f.fileinfo = "Please remount your SD card";
        return false;
    } else {
        /* get all files from extarnal drive data */
        ArrayList<File> files = new ArrayList<File>();
        File directory = new File(FileStuff.DATA_DIRECTORY);
        if (!directory.exists()) {
            return false;
        }
        File[] fList = directory.listFiles();
        for (File file : fList) {
            if (file.isFile()) {
                files.add(file);
            }
        }  
        for (File csvfile : files) {
            readFromFile(database, csvfile);
        }
        return true;
    }
}

注: readFromFile(データベース、csvfile); 前の関数です

于 2014-10-27T06:07:55.920 に答える