4

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

4

5 回答 5

7

这是一个相当广泛的问题,并且在一定程度上取决于您的经验和使用水平。

但是通常的做法是创建自己的ContentProvider,这将抽象对数据库的访问。这样您就可以使用Uri执行选择/更新/删除/插入查询。

对于 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();
        }
    }
}

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

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);

这将返回一个Cursor您可以遍历并获得结果的内容。这也是Android 中大多数事情的实现方式(即从通讯录中获取地址也可以通过Uri 和Cursor 工作)。

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

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

于 2013-08-18T18:23:43.083 回答
4

我想使用 SQLite 数据库的最好方法是使用 ContentProviders。当您搜索它时,您会发现 ContentProvider API 非常复杂。但是有一个非常好的库可以让这个过程变得非常简单。它被称为 ProviGen,您可以在下面的链接中找到有关它的详细信息。

https://github.com/TimotheeJeannin/ProviGen

这是非常容易使用。您只需创建一个 Contract 类,您将在其中使用注释指示数据库中需要哪些列,它将自动创建所有内容。我什至可以在一个数据库中创建多个表。

于 2013-08-18T18:23:50.683 回答
2

我想说最好的做法是使用一个框架,它将为你完成大部分工作。在使用数据库时,我个人更喜欢 ORM 映射,所以我建议尝试一些 ORM 框架。我知道的最好的是OrmLite。作者还在这里回答了关于 SO 的问题,这可能非常有用。

但是如果你不想使用它,你应该从阅读这些文章开始:

于 2013-08-18T18:37:33.123 回答
1

Which is the best manner for this?
你需要使用SQLite安卓自带的。每个 Android 应用程序都可以拥有自己的数据库。

which class sub I use, subclass, reimplement,
您需要扩展SQLiteOpenHelper类,该类确定您的数据库的名称是什么,它是如何升级/降级的,表的结构方式等等。它还定义了获取数据库引用的方法。

是的,很多资源都在那里,而不是大脑友好和优质的资源。以下是我喜欢的一些:
Lars Vogel 的 SQLite 和 CContentProvider
古斯汀教授的 Android 教程

至于您的问题的标题,Best practices for Android databases我只能说适用于 SQL 数据库的所有最佳实践都适用于此处,例如规范化等

于 2013-08-18T18:18:28.223 回答
1

SQLite 将是答案。

链接:http: //developer.android.com/reference/android/database/sqlite/package-summary.html

于 2013-08-18T18:05:40.030 回答