Android context provider DB更新

實際測試
new MyDBHlper時,會自動判斷,帶入的 version是不是跟之前的一樣,如果不一樣,就會先執行 MyDBHlper的onUpgrade
 

執行順序為

MyContentProvider: onCreate: 
MyDBHlper: onUpgrade: oldVersion:1newVersion:2
MyDBHlper: onCreate:

复制代码
public class MyContentProvider extends ContentProvider {
  @Override
  public boolean onCreate() {
      Log.d(Tag, "onCreate: ");
      // MyDBHlper dbHper = new MyDBHlper(getContext(), DBname, null, 1);
      //FIXME:test version change
      MyDBHlper dbHper = new MyDBHlper(getContext(), DBname, null, 2);
      MyDB = dbHper.getWritableDatabase();
      return true;
  }
}

public class MyDBHlper extends SQLiteOpenHelper {
  @Override
  public void onCreate(SQLiteDatabase db) {
      Log.d(Tag, "onCreate: ");
      db.execSQL(crTBsql);
      db.execSQL(initDBDate);
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      Log.d(Tag, "onUpgrade: oldVersion:" + oldVersion + "newVersion:" + newVersion);
      db.execSQL("DROP TABLE IF EXISTS " + TBname);
      onCreate(db);
  }
}
复制代码

 

***************************************************************************************************

 

轉載自http://mrraybox.blogspot.tw/2017/01/android-sqlite-onupgrade.html

 

本篇主要是示範:
1. 說明onUpgrade何時會啟用。
2. 示範如何使用onUpgrade。
3. 觀察onUpgrade使用後的前後差異。

相信開始接觸SQLite的大家都知道SQLiteOpenHelper中有一個方法叫onUpgrade,但是這個方法是做什麼用的呢?首先我們知道onCreate是在Android載入時,找不到對應的資料庫資料,就會觸發的一個方法。而onUpgrade呢,則是在資料庫的結構有所改變時,才會觸發的一個方法。

舉例來說,假如我在一月時,寫了一個App給其他人使用,在二月時,因改版需求,所以需要新增或刪減資料表的欄位。但是此時,那些使用我們所寫的App的用戶們,在這段期間已經儲存許多資料了。為了保存用戶舊的資料,此時我們就需要運用到onUpgrade來修改我們資料表的結構。

首先這裡示範我們一開始所寫的App。首先Layout部分的配置。
File Name:activity_main.xml

复制代码
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/btn_new"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="新增" />

            <Button
                android:id="@+id/btn_delete"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="刪除" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:orientation="horizontal" >

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="ID"
                android:id="@+id/edt1"
                android:layout_weight="1" />

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="Row1"
                android:id="@+id/edt2"
                android:layout_weight="1" />

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="Row2"
                android:id="@+id/edt3"
                android:layout_weight="1" />

            <Button
                android:id="@+id/btn_alter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="修改" />


        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="txt"
            android:id="@+id/txt"/>

    </LinearLayout>

</ScrollView>
复制代码

File Name:MainActivity

复制代码
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btnNew, btnDel, btnAlt;
    private EditText edtID, edtRow1, edtRow2;
    private TextView txt;

    private MyHelper helper;
    private SQLiteDatabase db;
    private Cursor c;

    private String result;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnNew = (Button) this.findViewById(R.id.btn_new);
        btnDel = (Button) this.findViewById(R.id.btn_delete); 
        btnAlt = (Button) this.findViewById(R.id.btn_alter);
        edtID = (EditText) this.findViewById(R.id.edt1);
        edtRow1 = (EditText) this.findViewById(R.id.edt2);
        edtRow2 = (EditText) this.findViewById(R.id.edt3);
        txt = (TextView) this.findViewById(R.id.txt);

        btnNew.setOnClickListener(this);
        btnDel.setOnClickListener(this);
        btnAlt.setOnClickListener(this);

        helper = new MyHelper(this, "dbname", null, 1);
        db = helper.getWritableDatabase();

        queryDB();
    }

    private void queryDB() {
        c = db.query("tablename", null, null, null, null, null, null);

        result="";
        for(int i=0; i<c.getColumnCount();i++){
            result+=c.getColumnName(i)+", ";
        }
        result+="\n";

        while (c.moveToNext()) {
            result += c.getString(c.getColumnIndex("_id")) + ", "+
                    c.getString(c.getColumnIndex("row1")) + ", "+
                    c.getString(c.getColumnIndex("row2")) +"\n";
        }
        txt.setText(result);
    }


    @Override
    public void onClick(View view) {
        String id = edtID.getText().toString();
        ContentValues values = new ContentValues();
        switch (view.getId()){
            case R.id.btn_new:
                values.put("row1", "Row1");
                values.put("row2", "Row2");
                db.insert("tablename", null, values);
                queryDB();
                break;
            case R.id.btn_delete:
                db.delete("tablename", "_id="+id,null);
                queryDB();
                break;
            case R.id.btn_alter:
                String row1 = edtRow1.getText().toString();
                String row2 = edtRow2.getText().toString();
                values.put("row1", row1);
                values.put("row2", row2);
                db.update("tablename", values, "_id=" + id, null);
                queryDB();
                break;
        }
    }

    @Override
    public void finish() {
        c.close();
        db.close();
        super.finish();
    }
}    
复制代码

File Name:MyHelper

复制代码
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyHelper extends SQLiteOpenHelper {

    private String createTab;
    private String tableName = "tablename";

    public MyHelper(Context context, String db_name, SQLiteDatabase.CursorFactory factory, int db_version) {
        super(context, db_name, factory, db_version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        createTab = "create table "+ tableName +" (_id integer primary key AUTOINCREMENT, row1 text, row2 text)";
        db.execSQL(createTab);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
复制代码

在用戶新增完資料後,就會變成下面這樣。

接著是我們改版後的程式碼。 
File Name:MainActivity
复制代码
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btnNew, btnDel, btnAlt;
    private EditText edtID, edtRow1, edtRow2;
    private TextView txt;

    private MyHelper helper;
    private SQLiteDatabase db;
    private Cursor c;

    private String result;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnNew = (Button) this.findViewById(R.id.btn_new);
        btnDel = (Button) this.findViewById(R.id.btn_delete);
        btnAlt = (Button) this.findViewById(R.id.btn_alter);
        edtID = (EditText) this.findViewById(R.id.edt1);
        edtRow1 = (EditText) this.findViewById(R.id.edt2);
        edtRow2 = (EditText) this.findViewById(R.id.edt3);
        txt = (TextView) this.findViewById(R.id.txt);

        btnNew.setOnClickListener(this);
        btnDel.setOnClickListener(this);
        btnAlt.setOnClickListener(this);

        helper = new MyHelper(this, "dbname", null, 2);
        db = helper.getWritableDatabase();

        queryDB();
    }

    private void queryDB() {
        c = db.query("tablename", null, null, null, null, null, null);

        result="";
        for(int i=0; i<c.getColumnCount();i++){
            result+=c.getColumnName(i)+", ";
        }
        result+="\n";

        while (c.moveToNext()) {
            result += c.getString(c.getColumnIndex("_id")) + ", "+
                    c.getString(c.getColumnIndex("row1")) + ", "+
                    c.getString(c.getColumnIndex("row2")) +"\n";
        }
        txt.setText(result);
    }


    @Override
    public void onClick(View view) {
        String id = edtID.getText().toString();
        ContentValues values = new ContentValues();
        switch (view.getId()){
            case R.id.btn_new:
                values.put("row1", "Row1");
                values.put("row2", "Row2");
                db.insert("tablename", null, values);
                queryDB();
                break;
            case R.id.btn_delete:
                db.delete("tablename", "_id="+id,null);
                queryDB();
                break;
            case R.id.btn_alter:
                String row1 = edtRow1.getText().toString();
                String row2 = edtRow2.getText().toString();
                values.put("row1", row1);
                values.put("row2", row2);
                db.update("tablename", values, "_id=" + id, null);
                queryDB();
                break;
        }
    }

    @Override
    public void finish() {
        c.close();
        db.close();
        super.finish();
    }
}
复制代码

File Name:MyHelper

复制代码
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyHelper extends SQLiteOpenHelper {

    private String createTab;
    private String tableName = "tablename";

    public MyHelper(Context context, String db_name, SQLiteDatabase.CursorFactory factory, int db_version) {
        super(context, db_name, factory, db_version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        createTab = "create table "+ tableName +
                " (_id integer primary key AUTOINCREMENT, row1 text, row2 text, row3 text)";
        db.execSQL(createTab);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if(oldVersion == 1 && newVersion == 2){
            //Adding a row3
            String sql = "alter table "+ tableName +" add row3 text";
            db.execSQL(sql);
        }
    }
}
复制代码

實作後,則會變成下面這樣。有發現差異在哪嗎?


改版後的App不但保存了用戶的舊資料,同時還新增了一個row3的欄位,是不是很方便的一個功能呀!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android ProviderAndroid 系统提供的一种数据存储方式,它提供了可供其他应用程序访问的公共数据集合。使用 Provider 可以实现数据共享,使得不同的应用程序可以访问和修改同一数据集合,从而实现数据的共享和协作。 在 Android 中,Provider 通常用于存储和共享应用程序的数据,比如联系人、短信、音乐、视频等。开发者可以通过 ContentResolver 类来访问 Provider 中的数据。 使用 Provider 的步骤如下: 1. 创建数据表结构:定义 Provider 中所需的数据表结构; 2. 创建 ContentProvider 子类:实现 Provider 中的 CRUD(增删改查)操作; 3. 在 AndroidManifest.xml 文件中注册 ContentProvider:声明 Provider 的信息; 4. 在应用程序中使用 ContentResolver 访问 Provider 中的数据。 接下来是一个简单的示例,演示如何创建一个 Provider 并向其中插入一条数据: 1. 首先,定义 Provider 中需要使用的数据表结构,比如: ``` public class MyProvider extends SQLiteOpenHelper { // 声明数据库名和版本号 public static final String DB_NAME = "my_provider.db"; public static final int DB_VERSION = 1; // 声明数据表名和字段名 public static final String TABLE_NAME = "users"; public static final String COLUMN_ID = "id"; public static final String COLUMN_NAME = "name"; // 构造函数 public MyProvider(Context context) { super(context, DB_NAME, null, DB_VERSION); } // 创建数据表 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME + " TEXT NOT NULL" + ");"); } // 升级数据表 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } } ``` 2. 然后,创建一个 ContentProvider 子类,继承自 ContentProvider,并实现 CRUD 操作,比如: ``` public class MyContentProvider extends ContentProvider { // 声明 Provider 的唯一标识 public static final String AUTHORITY = "com.example.myprovider"; // 声明 UriMatcher 对象 private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int USERS = 1; private static final int USER_ID = 2; // 声明 MyProvider 对象 private MyProvider mProvider; // 初始化 UriMatcher static { sUriMatcher.addURI(AUTHORITY, MyProvider.TABLE_NAME, USERS); sUriMatcher.addURI(AUTHORITY, MyProvider.TABLE_NAME + "/#", USER_ID); } // 获取 ContentProvider 所使用的数据源 @Override public boolean onCreate() { mProvider = new MyProvider(getContext()); return true; } // 查询数据 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = mProvider.getReadableDatabase(); Cursor cursor = null; switch (sUriMatcher.match(uri)) { case USERS: cursor = db.query(MyProvider.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); break; case USER_ID: String id = uri.getLastPathSegment(); cursor = db.query(MyProvider.TABLE_NAME, projection, MyProvider.COLUMN_ID + "=?", new String[]{id}, null, null, sortOrder); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } // 插入数据 @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = mProvider.getWritableDatabase(); long id = db.insert(MyProvider.TABLE_NAME, null, values); if (id > 0) { Uri itemUri = ContentUris.withAppendedId(uri, id); getContext().getContentResolver().notifyChange(uri, null); return itemUri; } else { throw new SQLException("Failed to insert row into " + uri); } } // 更新数据 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = mProvider.getWritableDatabase(); int count = 0; switch (sUriMatcher.match(uri)) { case USERS: count = db.update(MyProvider.TABLE_NAME, values, selection, selectionArgs); break; case USER_ID: String id = uri.getLastPathSegment(); count = db.update(MyProvider.TABLE_NAME, values, MyProvider.COLUMN_ID + "=?", new String[]{id}); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } // 删除数据 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = mProvider.getWritableDatabase(); int count = 0; switch (sUriMatcher.match(uri)) { case USERS: count = db.delete(MyProvider.TABLE_NAME, selection, selectionArgs); break; case USER_ID: String id = uri.getLastPathSegment(); count = db.delete(MyProvider.TABLE_NAME, MyProvider.COLUMN_ID + "=?", new String[]{id}); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } // 获取 MIME 类型 @Override public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case USERS: return "vnd.android.cursor.dir/" + AUTHORITY + "." + MyProvider.TABLE_NAME; case USER_ID: return "vnd.android.cursor.item/" + AUTHORITY + "." + MyProvider.TABLE_NAME; default: throw new IllegalArgumentException("Unknown URI: " + uri); } } } ``` 3. 在 AndroidManifest.xml 文件中注册 ContentProvider,比如: ``` <provider android:name=".MyContentProvider" android:authorities="com.example.myprovider" android:exported="false" /> ``` 4. 在应用程序中使用 ContentResolver 访问 Provider 中的数据,比如: ``` // 查询用户列表 Cursor cursor = getContentResolver().query(Uri.parse("content://com.example.myprovider/users"), null, null, null, null); while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex(MyProvider.COLUMN_ID)); String name = cursor.getString(cursor.getColumnIndex(MyProvider.COLUMN_NAME)); Log.d(TAG, "id=" + id + ", name=" + name); } // 插入一条用户数据 ContentValues values = new ContentValues(); values.put(MyProvider.COLUMN_NAME, "Alice"); Uri uri = getContentResolver().insert(Uri.parse("content://com.example.myprovider/users"), values); Log.d(TAG, "insert uri: " + uri); // 更新用户数据 values.put(MyProvider.COLUMN_NAME, "Bob"); int count = getContentResolver().update(Uri.parse("content://com.example.myprovider/users/1"), values, null, null); Log.d(TAG, "update count: " + count); // 删除用户数据 count = getContentResolver().delete(Uri.parse("content://com.example.myprovider/users/1"), null, null); Log.d(TAG, "delete count: " + count); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值