Android : DB 버전 업그레이드 및 새 테이블 추가
이미 앱에 대한 sqlite 테이블을 만들었지 만 이제 데이터베이스에 새 테이블을 추가하려고합니다.
같이 같이 DB 버전을 변경했습니다
private static final int DATABASE_VERSION = 2;
테이블을 만들기 위해 확장 추가
private static final String DATABASE_CREATE_color =
"CREATE TABLE IF NOT EXISTS files(color text, incident_id text)";
onCreate
그리고 onUpgrade
같이 :
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE_incident);
database.execSQL(DATABASE_CREATE_audio);
database.execSQL(DATABASE_CREATE_video);
database.execSQL(DATABASE_CREATE_image);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//drop table and add new tables when version 2 released.
db.execSQL(DATABASE_CREATE_color);
}
그러나 어떤 것이 새 테이블이 작성되지 않는지. 내가 뭘 잘못하고 있죠?
1. onCreate () 및 onUpgrade () 정보
onCreate(..)
앱이 새로 설치 될 때마다 호출됩니다. onUpgrade
앱이 업그레이드되고 시작되고 데이터베이스 버전 이 같지 않을 때마다 호출 됩니다.
2. DB 버전 증가
다음과 같은 생성자가 필요합니다.
MyOpenHelper(Context context) {
super(context, "dbname", null, 2); // 2 is the database version
}
중요 : 앱 버전 만 늘리는 것만 충분하지 않습니다 onUpgrade
!
3. 새로운 사용자를 잊지 마세요!
추가하는 것을 잊지 마세요
database.execSQL(DATABASE_CREATE_color);
onCreate () 메소드 새로 고침 앱에는 테이블이 없습니다.
4. 시간이 지남에 따라 여러 데이터베이스 변경을 처리하는 방법
연속적인 앱 업그레이드가있는 경우 (일부 데이터베이스 업그레이드가있는 경우)를 확인해야합니다 oldVersion
.
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
db.execSQL(DATABASE_CREATE_color);
// we want both updates, so no break statement here...
case 2:
db.execSQL(DATABASE_CREATE_someothertable);
}
}
이렇게하면 사용자가 버전 1에서 버전 3으로 업그레이드 할 때 두 업데이트가 모두 제공됩니다. 사용자가 버전 2에서 3으로 업그레이드하면 업데이트 3 만 업데이트됩니다. 결국 업데이트를 릴리스 할 때마다 사용자 기반을 100 % 업그레이드하여 업그레이드 할 수 없습니다. 거기에 설치 업데이트 또는 12를 건너 뛰기 :)
5. 개발 중 개정 번호 관리
그리고 마지막으로 ... 전화
adb uninstall <yourpackagename>
앱을 완전히 제거합니다. 다시 확장 될 때, onCreate
개발할 때 데이터베이스 버전을 성층권으로 계속 증가하는 히트 를 보장합니다 .
코드가 시청합니다. 내 제안은 데이터베이스가 이미 업그레이드되었다고 생각하는 것입니다. 버전 번호를 증가시킨 후 execSQL
호출을 추가하기 전에 프로젝트를 실행 한 경우 테스트 장치 / 에뮬레이터의 데이터베이스가 이미 버전 2에서 생각할 수 있습니다.
이를 확인하는 빠른 방법은 버전 번호를 3으로 변경하는 것입니다. 그 후에 업그레이드하는 경우 장치가 이미 업그레이드되었다고 생각합니다.
SQLiteOpenHelper의 onUpgrade
메소드를 사용할 수 있습니다 . onUpgrade 메소드에서 oldVersion을 매개 변수 하나로 가져옵니다.
에서 onUpgrade
사용 switch
와의 추가 case
의 데이터베이스의 현재 버전을 추적하기 위해 버전 번호를 사용합니다.
한 번에 1 씩 증가 하여 에서 oldVersion
까지 반복 한 다음 데이터베이스를 단계별로 업그레이드하는 것이 추론 좋습니다 . 데이터베이스 버전 1을 사용하는 오랜 시간 후에 앱을 데이터베이스 버전 7을 사용하는 버전으로 업그레이드하고 호환되지 않는 특정 변경 사항으로 앱이 중단되기 시작할 때 매우 유용합니다.newVersion
version
그런 다음 데이터베이스의 업데이트는 모든 가능한 경우를 단계적으로 수행합니다. 즉, 새 버전마다 수행 된 데이터베이스의 변경 사항을 통합하여 응용 프로그램이 중단되는 것을 방지합니다.
예를 들면 다음과 같습니다.
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
String sql = "ALTER TABLE " + TABLE_SECRET + " ADD COLUMN " + "name_of_column_to_be_added" + " INTEGER";
db.execSQL(sql);
break;
case 2:
String sql = "SOME_QUERY";
db.execSQL(sql);
break;
}
}
@jkschneider의 대답이 옳습니다. 그러나 더 나은 접근 방식이 있습니다.
링크 https://riggaroo.co.za/android-sqlite-database-use-onupgrade-correctly/에 설명 된대로 각 업데이트에 대해 SQL 파일에 필요한 변경 사항을 작성 하십시오.
from_1_to_2.sql
ALTER TABLE books ADD COLUMN book_rating INTEGER;
from_2_to_3.sql
ALTER TABLE books RENAME TO book_information;
from_3_to_4.sql
ALTER TABLE book_information ADD COLUMN calculated_pages_times_rating INTEGER;
UPDATE book_information SET calculated_pages_times_rating = (book_pages * book_rating) ;
이러한 .sql 파일은 데이터베이스 버전에 따라 onUpgrade () 메서드에서 실행됩니다.
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 4;
private static final String DATABASE_NAME = "database.db";
private static final String TAG = DatabaseHelper.class.getName();
private static DatabaseHelper mInstance = null;
private final Context context;
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
public static synchronized DatabaseHelper getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new DatabaseHelper(ctx.getApplicationContext());
}
return mInstance;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(BookEntry.SQL_CREATE_BOOK_ENTRY_TABLE);
// The rest of your create scripts go here.
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e(TAG, "Updating table from " + oldVersion + " to " + newVersion);
// You will not need to modify this unless you need to do some android specific things.
// When upgrading the database, all you need to do is add a file to the assets folder and name it:
// from_1_to_2.sql with the version that you are upgrading to as the last version.
try {
for (int i = oldVersion; i < newVersion; ++i) {
String migrationName = String.format("from_%d_to_%d.sql", i, (i + 1));
Log.d(TAG, "Looking for migration file: " + migrationName);
readAndExecuteSQLScript(db, context, migrationName);
}
} catch (Exception exception) {
Log.e(TAG, "Exception running upgrade script:", exception);
}
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private void readAndExecuteSQLScript(SQLiteDatabase db, Context ctx, String fileName) {
if (TextUtils.isEmpty(fileName)) {
Log.d(TAG, "SQL script file name is empty");
return;
}
Log.d(TAG, "Script found. Executing...");
AssetManager assetManager = ctx.getAssets();
BufferedReader reader = null;
try {
InputStream is = assetManager.open(fileName);
InputStreamReader isr = new InputStreamReader(is);
reader = new BufferedReader(isr);
executeSQLScript(db, reader);
} catch (IOException e) {
Log.e(TAG, "IOException:", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Log.e(TAG, "IOException:", e);
}
}
}
}
private void executeSQLScript(SQLiteDatabase db, BufferedReader reader) throws IOException {
String line;
StringBuilder statement = new StringBuilder();
while ((line = reader.readLine()) != null) {
statement.append(line);
statement.append("\n");
if (line.endsWith(";")) {
db.execSQL(statement.toString());
statement = new StringBuilder();
}
}
}
}
예제 프로젝트도 동일한 링크에서 제공됩니다 : https://github.com/riggaroo/AndroidDatabaseUpgrades
데이터베이스 버전 처리는 애플리케이션 개발에서 매우 중요한 부분입니다. 이미 AppDbHelper 확장 클래스가 있다고 가정합니다 SQLiteOpenHelper
. 확장 할 때 구현 onCreate
및 onUpgrade
방법 이 필요합니다 .
호출 시기
onCreate
및onUpgrade
메서드onCreate
앱이 새로 설치되면 호출됩니다.onUpgrade
앱이 업데이트되면 호출됩니다.
데이터베이스 버전 구성 클래스 메서드에서 버전을 관리합니다. 인터페이스 마이그레이션 구현을 작성하십시오. 예 : 첫 번째 버전 생성
MigrationV1
클래스의 경우 두 번째 버전 생성MigrationV1ToV2
(내 이름 지정 규칙)
public interface Migration {
void run(SQLiteDatabase db);//create tables, alter tables
}
마이그레이션 예 :
public class MigrationV1ToV2 implements Migration{
public void run(SQLiteDatabase db){
//create new tables
//alter existing tables(add column, add/remove constraint)
//etc.
}
}
- 마이그레이션 클래스 사용
onCreate
: onCreate
애플리케이션이 새로 설치 될 때 호출 되므로 모든 마이그레이션 (데이터베이스 버전 업데이트)도 실행해야합니다. 따라서 onCreate
다음과 같이 보일 것입니다.
public void onCreate(SQLiteDatabase db){
Migration mV1=new MigrationV1();
//put your first database schema in this class
mV1.run(db);
Migration mV1ToV2=new MigrationV1ToV2();
mV1ToV2.run(db);
//other migration if any
}
onUpgrade
:이 메서드는 응용 프로그램이 이미 설치되어 있고 새 응용 프로그램 버전으로 업데이트 된 경우 호출됩니다. 응용 프로그램에 데이터베이스 변경 사항이 포함되어 있으면 모든 데이터베이스 변경 사항을 새 마이그레이션 클래스에 넣고 데이터베이스 버전을 증가시킵니다.
예를 들어 사용자가 데이터베이스 버전 1이있는 애플리케이션을 설치했고 이제 데이터베이스 버전이 2로 업데이트되었다고 가정 해 보겠습니다 (모든 스키마 업데이트는에서 유지됨 MigrationV1ToV2
). 이제 응용 프로그램을 업그레이드 할 때 MigrationV1ToV2
다음과 같이 데이터베이스 스키마 변경 사항을 적용하여 데이터베이스를 업그레이드해야합니다 .
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
//means old version is 1
Migration migration = new MigrationV1ToV2();
migration.run(db);
}
if (oldVersion < 3) {
//means old version is 2
}
}
참고 :
onUpgrade
데이터베이스 스키마에 대한 모든 업그레이드 (에서 언급 됨 )는onCreate
참고 URL : https://stackoverflow.com/questions/8133597/android-upgrading-db-version-and-adding-new-table
'IT' 카테고리의 다른 글
Heroku bash 쉘에서 어떤 텍스트 편집기를 사용할 수 있습니까? (0) | 2020.07.23 |
---|---|
링크를 클릭하여 JavaScript로 양식을 출시하는 방법은 무엇입니까? (0) | 2020.07.23 |
파일 찾기 및 복사 (0) | 2020.07.23 |
Project-Swift.h를 Objective-C 클래스로 가져 오기… (0) | 2020.07.23 |
Visual Studio를 열 수 없습니다- '설정이 진행 중일 때 수 없습니다'오류 발생 (0) | 2020.07.23 |