Android数据库的最佳做法

Did*_*era 4 database sqlite android

我的Android应用程序需要本地数据库.哪种方式最好?我使用哪个类子,子类,重新实现等.我在网上发现了太多信息,但我仍然不知道哪种是最佳做法.

Tse*_*eng 6

这是一个非常广泛的问题,取决于您的经验和使用水平.

但通常的做法是创建自己的ContentProvider抽象访问数据库.这样您就可以Uri用来执行select/update/delete/insert查询.

对于SQLite数据库本身,用于SQLiteOpenHelper抽象SQLite数据库的创建和升级.这将允许您升级数据库,而无需用户轻松丢失所有数据.

我可以在我的一个旧项目中附加一段代码,这些代码可以帮助您入门.但实施整个事情可能超出单个问题/答案的范围.

public class MyServiceProvider extends ContentProvider {
    private SQLiteDatabase db;

    @Override
    public boolean onCreate() {
        // Initialize the database and assign it to the private variable
        MyDatabaseHelper sqlHelper = new MyDatabaseHelper(getContext());
        db = sqlHelper.getReadableDatabase();

        return (db == null)?false:true;
    }

    @override
    Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        // handle the query here, form it, do your checks and then access the DB
        db.query(....);
    }
}

class MyDatabaseHelper extends SQLiteOpenHelper {
    private static final String LOG_TAG = "MyAppTag";
    private static final String DB_NAME = "Databasename";
    private static final String TABLE_NAME = "Tablename";
    private static final int DATABASE_VERSION = 2;
    public static MyServiceProvider.CONTENT_URI = Uri.parse("content://com.mycompany.myApp.MyAppService/myTableOrIdentifier");

    public MyDatabaseHelper(Context context){
        super(context, DB_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE IF NOT EXISTS ....";
        db.execSQL(sql);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Here you can perform updates when the database structure changes
        // Begin transaction
        db.beginTransaction();

        try {
            if(oldVersion<2){
                // Upgrade database structure from Version 1 to 2
                String alterTable = "ALTER ....";

                db.execSQL(alterTable);
                Log.i(LOG_TAG,"Successfully upgraded to Version 2");
            }
            // This allows you to upgrade from any version to the next most 
            // recent one in multiple steps as you don't know if the user has
            // skipped any of the previous updates
            if(oldVersion<3){
                // Upgrade database structure from Version 2 to 3
                String alterTable = "ALTER ....";

                db.execSQL(alterTable);
                Log.i(LOG_TAG,"Successfully upgraded to Version 3");
            }

            // Only when this code is executed, the changes will be applied 
            // to the database
            db.setTransactionSuccessful();
        } catch(Exception ex){
            ex.printStackTrace();
        } finally {
            // Ends transaction
            // If there was an error, the database won't be altered
            db.endTransaction();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用游标与数据库进行交互.

ContentResolver contentResolver = getContentResolver();
...
Cursor c = contentResolver.query(
        // The Uri results in content://com.mycompany.myApp.MyAppService/myTableOrIdentifier/someId
        Uri.withAppendedPath(MyServiceProvider.CONTENT_URI, someId),
        new String[] {
            // only get fields we need!
            "MyDbFieldIneed"
        },
        null, null, null);
Run Code Online (Sandbox Code Playgroud)

这将返回一个Cursor你可以迭代并获得结果.这也是Android中大多数事情的实现方式(即通过Uri和Cursor从地址簿中获取地址也是如此).

编辑: 我意识到链接很难看到代码亮点.这里是您需要的重要课程的链接.

编辑2: 此外,如果您使用多个表,UriMatcher也是一个重要的来源