Analysis of Android SQLite Database Version Upgrade Principle

Keywords: Database SQL SQLite Android

Reprint the original address: http://www.cnblogs.com/liqw/p/4264925.html

Android uses the SQLite database to store data, so what about database version upgrade?

1. Software v1.0

Install v1.0, assuming v1.0 has only one account table, then go on Create inheriting from SQLiteOpenHelper instead of onUpgrade.

1. v1.0 (install v1.0 directly)

2. Software v2.0

There are two types of software installation:

1. v1.0 --> v2.0 do not go onCreate, onUpgrade

2. v2.0 (install v2.0 directly) go onCreate instead of onUpgrade

V1.0 version has only one account table. The software version has been upgraded to v2.0, but the v2.0 database needs to add a member table. So what? There are two situations: one is to install v1.0 and upgrade to v2.0, instead of inheriting the onCreate of SQLiteOpenHelper, to go directly to onUpgrade, then you need to add the member table code to onUpgrade, and it is useless to add to onCreate, because this situation does not go onCreate.... Another case is that the user has never installed the software, directly installing v2.0, then inherit the onCreate of SQLiteOpenHelper, not onUpgrade, so add the member table code to onCreate. What about this? This requires a reasonable upgrade of the database version.

3. Software v3.0

Assuming that v3.0 adds another news table, there are three cases:

1. v1.0 --> V3.0 do not go onCreate, onUpgrade

2. v2.0 --> v3.0 Do not go onCreate, onUpgrade

3. v3.0 (install v3.0 directly) go onCreate instead of onUpgrade

Where are the database add table statements written? The database has a version number expressed in DATABASE_VERSION

In fact, if you think about it, you know that either onCreate or onUpgrade is written, or you want to install app in all kinds of situations, you can add database tables. It's clever here:

1. v1.0 DATABASE_VERSION=1000 onCreate Add account

2. v2.0 DATABASE_VERSION=1001 onCreate Add account (v1.0 code unchanged) onUpgrade (DATABASE_VERSION>1000)

                                                   onUpgrade -- Add -- member 

3. v3.0 DATABASE_VERSION=1002 onCreate Add account (v1.0 code unchanged) onUpgrade (DATABASE_VERSION>1001)

                                                   onUpgrade -- Add -- member (v2.0 code unchanged)

                                                   onUpgrade -- Add -- news

This will solve the problem. The first version is onCreate, the other version is onUpgrade, and onUpgrade is executed in onCreate. How to judge whether or not to execute onUpgrade? So we have the concept of database version. DATABASE_VERSION saves the current database version. As long as the current database version is larger than the installed database version, it enters onUpgrade. At this time, it will keep the previous database version number safe. Comparing the installed version number of the database, different DATABASE_VERSIONs add the tables they need (upgrade the database across versions).

Here's a simple example:

(1), V1.0: DATABASE_VERSION = 1000 Add a favorite table

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mall.db"; 
    private static final int DATABASE_VERSION = 1000;

    private static DBHelper instance = null;


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

    public synchronized static DBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL.CREATE_TABLE_FAVORITE);

        // If it is not for the first version, perform database upgrade directly
        // Please do not change the value of FIRST_DATABASE_VERSION, which is the first database version size.
        final int FIRST_DATABASE_VERSION = 1000;
        onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Using for to upgrade databases across versions
        for (int i = oldVersion; i < newVersion; i++) {
            switch (i) {

            default:
                break;
            }
        }
    }
}

Among them, SQL.java is a table-building statement.

public class SQL {
    public static final String T_FAVORITE = "favorite";


    public static final String CREATE_TABLE_FAVORITE =
            "CREATE TABLE IF NOT EXISTS " + T_FAVORITE + "(" +
                    "id VARCHAR PRIMARY KEY, " +
                    "title VARCHAR, " +
                    "url VARCHAR, " +
                    "createDate VARCHAR " +
                    ")";
}

(2), V2.0: DATABASE_VERSION = 1001 Add a deleted field to the favorite table

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mall.db"; 
    private static final int DATABASE_VERSION = 1001;

    private static DBHelper instance = null;


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

    public synchronized static DBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL.CREATE_TABLE_FAVORITE);

        // If it is not for the first version, perform database upgrade directly
        // Please do not change the value of FIRST_DATABASE_VERSION, which is the first database version size.
        final int FIRST_DATABASE_VERSION = 1000;
        onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Using for to upgrade databases across versions
        for (int i = oldVersion; i < newVersion; i++) {
            switch (i) {
            case 1000:
                upgradeToVersion1001(db);
                break;
            default:
                break;
            }
        }
    }

    private void upgradeToVersion1001(SQLiteDatabase db){
        // Add a new field to the favorite table
        String sql1 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN deleted VARCHAR";
        db.execSQL(sql1);
    }
}

(3), V3.0: DATABASE_VERSION = 1002 Add message and type fields to the favorite table

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mall.db"; 
    private static final int DATABASE_VERSION = 1002;

    private static DBHelper instance = null;


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

    public synchronized static DBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL.CREATE_TABLE_FAVORITE);

        // If it is not for the first version, perform database upgrade directly
        // Please do not change the value of FIRST_DATABASE_VERSION, which is the first database version size.
        final int FIRST_DATABASE_VERSION = 1000;
        onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Using for to upgrade databases across versions
        for (int i = oldVersion; i < newVersion; i++) {
            switch (i) {
            case 1000:
                upgradeToVersion1001(db);
                break;
            case 1001:
                upgradeToVersion1002(db);
                break;

            default:
                break;
            }
        }
    }

    private void upgradeToVersion1001(SQLiteDatabase db){
        // Add a new field to the favorite table
        String sql1 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN deleted VARCHAR";
        db.execSQL(sql1);
    }
    private void upgradeToVersion1002(SQLiteDatabase db){
        // Two new fields are added to the favorite table. Adding new fields can only be one field and one field, while sqlite does not allow one statement to be added with more than one field.
        String sql1 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN message VARCHAR";
        String sql2 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN type VARCHAR";
        db.execSQL(sql1);
        db.execSQL(sql2);
    }
}

That's it. Whether v1.0 is upgraded to v3.0, or v2.0 is upgraded to 3.0, or V3.0 is installed directly, the structure of the V3.0 database after installation is the same. It's good to understand thoroughly. The sqlite database will definitely encounter these problems, so I'll write it in detail here, but still pay attention to it, that is onU. When upgrading pgrade, you must write it correctly and test it well. Otherwise, the database after installation will be troublesome.

Posted by rednaxel on Wed, 10 Jul 2019 13:08:22 -0700