Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将一个长的、单个的SQLiteOpenHelper拆分为几个类,每个类对应一个表_Android_Sqlite_Android Sqlite_Sqliteopenhelper - Fatal编程技术网

Android 如何将一个长的、单个的SQLiteOpenHelper拆分为几个类,每个类对应一个表

Android 如何将一个长的、单个的SQLiteOpenHelper拆分为几个类,每个类对应一个表,android,sqlite,android-sqlite,sqliteopenhelper,Android,Sqlite,Android Sqlite,Sqliteopenhelper,我知道这已经被问过好几次了,但在所有这些问题中,无论是OP还是回答者都没有提供明确的例子 所以我想问的是,如果有这样一节课 public class MyDatabaseDB { // database constants public static final String DB_NAME = "mydatabase.db"; public static final int DB_VERSION = 1; // list table constants

我知道这已经被问过好几次了,但在所有这些问题中,无论是OP还是回答者都没有提供明确的例子

所以我想问的是,如果有这样一节课

public class MyDatabaseDB {

    // database constants
    public static final String DB_NAME = "mydatabase.db";
    public static final int    DB_VERSION = 1;

    // list table constants
    public static final String LIST_TABLE = "list";

    public static final String LIST_ID = "_id";
    public static final int    LIST_ID_COL = 0;

    public static final String LIST_NAME = "list_name";
    public static final int    LIST_NAME_COL = 1;

    // task table constants
    public static final String TASK_TABLE = "task";

    public static final String TASK_ID = "_id";
    public static final int    TASK_ID_COL = 0;

    public static final String TASK_LIST_ID = "list_id";
    public static final int    TASK_LIST_ID_COL = 1;

    public static final String TASK_NAME = "task_name";
    public static final int    TASK_NAME_COL = 2; 

    // CREATE and DROP TABLE statements
    public static final String CREATE_LIST_TABLE = 
            "CREATE TABLE " + LIST_TABLE + " (" + 
            LIST_ID   + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
            LIST_NAME + " TEXT    UNIQUE)";

    public static final String CREATE_TASK_TABLE = 
            "CREATE TABLE " + TASK_TABLE + " (" + 
            TASK_ID         + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
            TASK_LIST_ID    + " INTEGER, " + 
            TASK_NAME       + " TEXT " + 
           )";

    public static final String DROP_LIST_TABLE = 
            "DROP TABLE IF EXISTS " + LIST_TABLE;

    public static final String DROP_TASK_TABLE = 
            "DROP TABLE IF EXISTS " + TASK_TABLE;

    private static class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context, String name, 
                CursorFactory factory, int version) {
            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // create tables
            db.execSQL(CREATE_LIST_TABLE);
            db.execSQL(CREATE_TASK_TABLE);

            // insert lists
            db.execSQL("INSERT INTO list VALUES (1, 'Hobbies')");
            db.execSQL("INSERT INTO list VALUES (2, 'Sports')");

            // insert sample tasks
            db.execSQL("INSERT INTO task VALUES (1, 1, 'Play the guitar')");
            db.execSQL("INSERT INTO task VALUES (2, 1, 'Play video games')");
        }

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

            Log.d("Task list", "Upgrading db from version " 
                    + oldVersion + " to " + newVersion);


            db.execSQL(MyDatabaseDB.DROP_LIST_TABLE);
            db.execSQL(MyDatabaseDB.DROP_TASK_TABLE);
            onCreate(db);
        }
    }

    // database object and database helper object
    private SQLiteDatabase db;
    private DBHelper dbHelper;

    // constructor
    public MyDatabaseDB(Context context) {
        dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);
    }

    // private methods
    private void openReadableDB() {
        db = dbHelper.getReadableDatabase();
    }

    private void openWriteableDB() {
        db = dbHelper.getWritableDatabase();
    }

    private void closeDB() {
        if (db != null)
            db.close();
    }

    // public methods   

    public long insertTask(Task task) {
        ContentValues cv = new ContentValues();
        cv.put(TASK_LIST_ID, task.getListId());
        cv.put(TASK_NAME, task.getName());        

        this.openWriteableDB();
        long rowID = db.insert(TASK_TABLE, null, cv);
        this.closeDB();

        return rowID;
    }    

    public int updateTask(Task task) {
        ContentValues cv = new ContentValues();
        cv.put(TASK_LIST_ID, task.getListId());
        cv.put(TASK_NAME, task.getName());        

        String where = TASK_ID + "= ?";
        String[] whereArgs = { String.valueOf(task.getId()) };

        this.openWriteableDB();
        int rowCount = db.update(TASK_TABLE, cv, where, whereArgs);
        this.closeDB();

        return rowCount;
    }    

    public int deleteTask(long id) {
        String where = TASK_ID + "= ?";
        String[] whereArgs = { String.valueOf(id) };

        this.openWriteableDB();
        int rowCount = db.delete(TASK_TABLE, where, whereArgs);
        this.closeDB();

        return rowCount;
    }
}
这是我的类的一个非常精简的版本,使用我在网上找到的一些代码构建。在本例中,我只展示了我的两个表的代码:List和Task,以及任务表的一些sql方法:insertTask、updateTask和deleteTask

尽管上面显示的代码可以工作,但我认为将十个表的所有代码都放在同一个类中并不好。所以我尝试将所有这些代码分成几个类,每个表一个类。大概是这样的:

public class MyDatabaseDB {

    // database constants
    public static final String DB_NAME = "mydatabase.db";
    public static final int    DB_VERSION = 1;


    private static class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context, String name, 
                CursorFactory factory, int version) {
            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // create tables
            db.execSQL(ListDAL.CREATE_LIST_TABLE);
            db.execSQL(TaskDAL.CREATE_TASK_TABLE);

            // insert lists
            db.execSQL("INSERT INTO list VALUES (1, 'Hobbies')");
            db.execSQL("INSERT INTO list VALUES (2, 'Sports')");

            // insert sample tasks
            db.execSQL("INSERT INTO task VALUES (1, 1, 'Play the guitar')");
            db.execSQL("INSERT INTO task VALUES (2, 1, 'Play video games')");
        }

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

            Log.d("Task list", "Upgrading db from version " 
                    + oldVersion + " to " + newVersion);


            db.execSQL(ListDAL.DROP_LIST_TABLE);
            db.execSQL(TaskDAL.DROP_TASK_TABLE);
            onCreate(db);
        }
    }

    // database object and database helper object
    private SQLiteDatabase db;
    private DBHelper dbHelper;

    // constructor
    public MyDatabaseDB(Context context) {
        dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);
    }

    // private methods
    private void openReadableDB() {
        db = dbHelper.getReadableDatabase();
    }

    private void openWriteableDB() {
        db = dbHelper.getWritableDatabase();
    }

    private void closeDB() {
        if (db != null)
            db.close();
    }   

}
这是我创建的两个新类,用于放置与特定表相关的代码:

ListDAL没有太多的代码

public class ListDAL {

   // list table constants
    public static final String LIST_TABLE = "list";

    public static final String LIST_ID = "_id";
    public static final int    LIST_ID_COL = 0;

    public static final String LIST_NAME = "list_name";
    public static final int    LIST_NAME_COL = 1;

    // CREATE and DROP TABLE statements
    public static final String CREATE_LIST_TABLE = 
            "CREATE TABLE " + LIST_TABLE + " (" + 
            LIST_ID   + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
            LIST_NAME + " TEXT    UNIQUE)";

    public static final String DROP_LIST_TABLE = 
            "DROP TABLE IF EXISTS " + LIST_TABLE;


}
TaskDAL类是包含大部分代码的类,在这个类中我遇到了问题,特别是在insertTask、updateTaskdeleteTask中,调用了this.openWriteableDB()、this.openWriteableDB()db.insert(TASK_TABLE,null,cv)

由于这些方法不再在TaskDAL中,我无法访问它们。 我试图传递一些对这些方法的引用,以代替thisdb,但没有起作用

public class TaskDAL {
    // task table constants
    public static final String TASK_TABLE = "task";

    public static final String TASK_ID = "_id";
    public static final int    TASK_ID_COL = 0;

    public static final String TASK_LIST_ID = "list_id";
    public static final int    TASK_LIST_ID_COL = 1;

    public static final String TASK_NAME = "task_name";
    public static final int    TASK_NAME_COL = 2; 

    // CREATE and DROP TABLE statements
    public static final String CREATE_TASK_TABLE = 
            "CREATE TABLE " + TASK_TABLE + " (" + 
            TASK_ID         + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
            TASK_LIST_ID    + " INTEGER, " + 
            TASK_NAME       + " TEXT " + 
           )";
    public static final String DROP_TASK_TABLE = 
            "DROP TABLE IF EXISTS " + TASK_TABLE;       

     // public methods   

    public long insertTask(Task task) {
        ContentValues cv = new ContentValues();
        cv.put(TASK_LIST_ID, task.getListId());
        cv.put(TASK_NAME, task.getName());        

        this.openWriteableDB();
        long rowID = db.insert(TASK_TABLE, null, cv);
        this.closeDB();

        return rowID;
    }    

    public int updateTask(Task task) {
        ContentValues cv = new ContentValues();
        cv.put(TASK_LIST_ID, task.getListId());
        cv.put(TASK_NAME, task.getName());        

        String where = TASK_ID + "= ?";
        String[] whereArgs = { String.valueOf(task.getId()) };

        this.openWriteableDB();
        int rowCount = db.update(TASK_TABLE, cv, where, whereArgs);
        this.closeDB();

        return rowCount;
    }    

    public int deleteTask(long id) {
        String where = TASK_ID + "= ?";
        String[] whereArgs = { String.valueOf(id) };

        this.openWriteableDB();
        int rowCount = db.delete(TASK_TABLE, where, whereArgs);
        this.closeDB();

        return rowCount;
    }
}
你们有没有人试过做类似的事情?? 如果我能将DB代码正确地划分成几个类,我还能连接表吗

另外,请不要结束这个问题,如果你认为我做错了什么,请告诉我,我会努力纠正它

你觉得你能给点提示怎么做吗

这与Android没有多大关系,甚至与Java也没有多大关系。将长的编程结构(例如Java中的类)分解成更小的结构有标准的技术,称为设计模式,具有特定于语言的实现

例如,您可以选择:

  • 定义一个接口——我在这里称它为
    TableHelper
    ——它有
    onCreate()
    onUpdate()
    方法,这些方法与
    SQLiteOpenHelper

  • 定义N个类,每个表一个,这些类实现
    TableHelper
    接口,并为该表提供创建和升级逻辑(以及您希望在这些类上拥有的任何其他业务逻辑)


  • 让您的
    SQLiteOpenHelper
    定义一个
    TableHelper[]
    包含
    TableHelper
    类实例的
    TableHelper,并让它通过迭代数组将
    onCreate()
    onUpgrade()
    委托给那些
    TableHelper
    实例


使用内容提供程序,您可以将长SQLiteOpenHelper拆分为多个文件:每个表一个persistenceContract,一个小SQLiteOpenHelper,以及长而详细的ContentProvider

使用此解决方案,您需要编写更多代码。但它更具可读性,并且易于维护


Avantages:

  • 编写查询时易于命名表的列(例如:TaskPersistenceContract.TaskEntry.column\u TASK\u name)
  • 易于阅读和维护
  • 更少的打字错误
  • 使用游标和游标装入器逻辑
缺点:

  • 更冗长

让我们试试你的初始代码

1。为每个表创建一个PersistenceContract

ListenceContract:

public final class ListPersistenceContract {

    public static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID;
    public static final String CONTENT_LIST_TYPE = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + ListEntry.TABLE_NAME;
    public static final String CONTENT_LIST_ITEM_TYPE = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + ListEntry.TABLE_NAME;
    public static final String VND_ANDROID_CURSOR_ITEM_VND = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".";
    private static final String CONTENT_SCHEME = "content://";
    public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_SCHEME + CONTENT_AUTHORITY);
    private static final String VND_ANDROID_CURSOR_DIR_VND = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".";
    private static final String SEPARATOR = "/";

    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    private ListPersistenceContract() {}

    public static Uri getBaseListUri(String listId) {
        return Uri.parse(CONTENT_SCHEME + CONTENT_LIST_ITEM_TYPE + SEPARATOR + listId);
    }

    /* Inner class that defines the table contents */
    public static abstract class ListEntry implements BaseColumns {

        public static final String TABLE_NAME = "list";
        public static final String COLUMN_LIST_NAME = "list_name";

        public static final Uri CONTENT_LIST_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
        public static String[] LIST_COLUMNS = new String[]{
                ListPersistenceContract.ListEntry._ID,
                ListEntry.COLUMN_LIST_NAME};

        public static final String LIST_AND_TASK = "listandtask";

        public static Uri buildListUriWith(long id) {
            return ContentUris.withAppendedId(CONTENT_LIST_URI, id);
        }

        public static Uri buildListUriWith(String id) {
            Uri uri = CONTENT_LIST_URI.buildUpon().appendPath(id).build();
            return uri;
        }

        public static Uri buildListUri() {
            return CONTENT_LIST_URI.buildUpon().build();
        }

        public static Uri buildListAndTaskUri() {
            return BASE_CONTENT_URI.buildUpon().appendPath(ListEntry.LIST_AND_TASK).build();
        }

    }
}
public class TaskPersistenceContract {

    public static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID;
    public static final String CONTENT_TASK_TYPE = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + TaskEntry.TABLE_NAME;
    public static final String CONTENT_TASK_ITEM_TYPE = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + TaskEntry.TABLE_NAME;
    public static final String VND_ANDROID_CURSOR_ITEM_VND = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".";
    private static final String CONTENT_SCHEME = "content://";
    public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_SCHEME + CONTENT_AUTHORITY);
    private static final String VND_ANDROID_CURSOR_DIR_VND = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".";
    private static final String SEPARATOR = "/";

    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    private TaskPersistenceContract() {}

    public static Uri getBaseTaskUri(String taskId) {
        return Uri.parse(CONTENT_SCHEME + CONTENT_TASK_ITEM_TYPE + SEPARATOR + taskId);
    }

    /* Inner class that defines the table contents */
    public static abstract class TaskEntry implements BaseColumns {

        public static final String TABLE_NAME = "task";
        public static final String COLUMN_TASK_LIST_ID = "list_id";
        public static final String COLUMN_TASK_NAME = "task_name";


        public static final Uri CONTENT_TASK_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
        public static String[] TASK_COLUMNS = new String[]{
                TaskPersistenceContract.TaskEntry._ID,
                TaskPersistenceContract.TaskEntry.COLUMN_TASK_LIST_ID,
                TaskPersistenceContract.TaskEntry.COLUMN_TASK_NAME};

        public static Uri buildTaskUriWith(long id) {
            return ContentUris.withAppendedId(CONTENT_TASK_URI, id);
        }

        public static Uri buildTaskUriWith(String id) {
            Uri uri = CONTENT_TASK_URI.buildUpon().appendPath(id).build();
            return uri;
        }

        public static Uri buildTaskUri() {
            return CONTENT_TASK_URI.buildUpon().build();
        }

    }
}
任务持久性合同:

public final class ListPersistenceContract {

    public static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID;
    public static final String CONTENT_LIST_TYPE = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + ListEntry.TABLE_NAME;
    public static final String CONTENT_LIST_ITEM_TYPE = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + ListEntry.TABLE_NAME;
    public static final String VND_ANDROID_CURSOR_ITEM_VND = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".";
    private static final String CONTENT_SCHEME = "content://";
    public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_SCHEME + CONTENT_AUTHORITY);
    private static final String VND_ANDROID_CURSOR_DIR_VND = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".";
    private static final String SEPARATOR = "/";

    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    private ListPersistenceContract() {}

    public static Uri getBaseListUri(String listId) {
        return Uri.parse(CONTENT_SCHEME + CONTENT_LIST_ITEM_TYPE + SEPARATOR + listId);
    }

    /* Inner class that defines the table contents */
    public static abstract class ListEntry implements BaseColumns {

        public static final String TABLE_NAME = "list";
        public static final String COLUMN_LIST_NAME = "list_name";

        public static final Uri CONTENT_LIST_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
        public static String[] LIST_COLUMNS = new String[]{
                ListPersistenceContract.ListEntry._ID,
                ListEntry.COLUMN_LIST_NAME};

        public static final String LIST_AND_TASK = "listandtask";

        public static Uri buildListUriWith(long id) {
            return ContentUris.withAppendedId(CONTENT_LIST_URI, id);
        }

        public static Uri buildListUriWith(String id) {
            Uri uri = CONTENT_LIST_URI.buildUpon().appendPath(id).build();
            return uri;
        }

        public static Uri buildListUri() {
            return CONTENT_LIST_URI.buildUpon().build();
        }

        public static Uri buildListAndTaskUri() {
            return BASE_CONTENT_URI.buildUpon().appendPath(ListEntry.LIST_AND_TASK).build();
        }

    }
}
public class TaskPersistenceContract {

    public static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID;
    public static final String CONTENT_TASK_TYPE = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + TaskEntry.TABLE_NAME;
    public static final String CONTENT_TASK_ITEM_TYPE = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + TaskEntry.TABLE_NAME;
    public static final String VND_ANDROID_CURSOR_ITEM_VND = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".";
    private static final String CONTENT_SCHEME = "content://";
    public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_SCHEME + CONTENT_AUTHORITY);
    private static final String VND_ANDROID_CURSOR_DIR_VND = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".";
    private static final String SEPARATOR = "/";

    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    private TaskPersistenceContract() {}

    public static Uri getBaseTaskUri(String taskId) {
        return Uri.parse(CONTENT_SCHEME + CONTENT_TASK_ITEM_TYPE + SEPARATOR + taskId);
    }

    /* Inner class that defines the table contents */
    public static abstract class TaskEntry implements BaseColumns {

        public static final String TABLE_NAME = "task";
        public static final String COLUMN_TASK_LIST_ID = "list_id";
        public static final String COLUMN_TASK_NAME = "task_name";


        public static final Uri CONTENT_TASK_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
        public static String[] TASK_COLUMNS = new String[]{
                TaskPersistenceContract.TaskEntry._ID,
                TaskPersistenceContract.TaskEntry.COLUMN_TASK_LIST_ID,
                TaskPersistenceContract.TaskEntry.COLUMN_TASK_NAME};

        public static Uri buildTaskUriWith(long id) {
            return ContentUris.withAppendedId(CONTENT_TASK_URI, id);
        }

        public static Uri buildTaskUriWith(String id) {
            Uri uri = CONTENT_TASK_URI.buildUpon().appendPath(id).build();
            return uri;
        }

        public static Uri buildTaskUri() {
            return CONTENT_TASK_URI.buildUpon().build();
        }

    }
}
2。创建DbHelper

public class LocalDbHelper {

    public static final int DB_VERSION = 1;
    public static final String DB_NAME = "mydatabase.db";
    private static final String TEXT_TYPE = " TEXT";
    private static final String INTEGER_TYPE = " INTEGER";
    private static final String PRIMARY_KEY = " PRIMARY KEY";
    private static final String AUTOINCREMENT = " AUTOINCREMENT";
    private static final String UNIQUE = " UNIQUE";
    private static final String CREATE_TABLE = "CREATE TABLE ";
    private static final String DROP_TABLE_IF_EXISTS = "DROP TABLE IF EXISTS ";
    private static final String OPEN_PARENTHESIS = " (";
    private static final String CLOSE_PARENTHESIS = " )";
    private static final String COMMA_SEP = ",";

    private static final String CREATE_LIST_TABLE =
            CREATE_TABLE + ListPersistenceContract.ListEntry.TABLE_NAME + OPEN_PARENTHESIS +
                    ListPersistenceContract.ListEntry._ID + INTEGER_TYPE + PRIMARY_KEY + AUTOINCREMENT + COMMA_SEP +
                    ListPersistenceContract.ListEntry.COLUMN_LIST_NAME + TEXT_TYPE + UNIQUE +
                    CLOSE_PARENTHESIS;

    private static final String CREATE_TASK_TABLE =
            CREATE_TABLE + TaskPersistenceContract.TaskEntry.TABLE_NAME + OPEN_PARENTHESIS +
                    TaskPersistenceContract.TaskEntry._ID + INTEGER_TYPE + PRIMARY_KEY + AUTOINCREMENT + COMMA_SEP +
                    TaskPersistenceContract.TaskEntry.COLUMN_TASK_LIST_ID + INTEGER_TYPE + COMMA_SEP +
                    TaskPersistenceContract.TaskEntry.COLUMN_TASK_NAME + TEXT_TYPE +
                    CLOSE_PARENTHESIS;

    private static final String DROP_LIST_TABLE =
            DROP_TABLE_IF_EXISTS + ListPersistenceContract.ListEntry.TABLE_NAME;

    private static final String DROP_TASK_TABLE =
            DROP_TABLE_IF_EXISTS + TaskPersistenceContract.TaskEntry.TABLE_NAME;

    public LocalDbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    public void onCreate(SQLiteDatabase db) {
        // create tables
        db.execSQL(CREATE_LIST_TABLE);
        db.execSQL(CREATE_TASK_TABLE);

        // insert lists
        db.execSQL("INSERT INTO " + ListPersistenceContract.ListEntry.TABLE_NAME + " VALUES (1, 'Hobbies')");
        db.execSQL("INSERT INTO " + ListPersistenceContract.ListEntry.TABLE_NAME + " VALUES (2, 'Sports')");

        // insert sample tasks
        db.execSQL("INSERT INTO " + TaskPersistenceContract.TaskEntry.TABLE_NAME + " VALUES (1, 1, 'Play the guitar')");
        db.execSQL("INSERT INTO " + TaskPersistenceContract.TaskEntry.TABLE_NAME + " VALUES (2, 1, 'Play video games')");
    }

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d("Task list", "Upgrading db from version "
                + oldVersion + " to " + newVersion);


        db.execSQL(LocalDbHelper.DROP_LIST_TABLE);
        db.execSQL(LocalDbHelper.DROP_TASK_TABLE);
        onCreate(db);
    }

    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Not required as at version 1
    }
}
3。使用查询、插入、更新和删除操作创建ContentProvider

(在本例中,我为查询添加了一个表联接。您可以使用相同的逻辑进行插入、更新和删除操作。)


SQLiteOpenHelper
管理数据库,因此您应该只有一个数据库。没有任何东西可以阻止你创建其他类。我知道,但是你认为你可以给出一些关于如何创建的提示吗。@eddy你使用内容提供商吗?在我的应用程序中,我这样分解代码:一个DBHelper、多个PersistentContrat和一个ContentProvider。它显然更具可读性。如果您愿意,我可以提供一个代码示例want@Fr是的,请:)@eddy完成了!我对这个问题很感兴趣,但我没有使用代理。您是否认为可以对SQLiteOpenHelper定义TableHelper[]@Axel的最后一部分进行更详细的解释:拥有一个
static
数据成员,类型为
TableHelper[]
。使用
静态
初始值设定项块用
TableHelper
实现的实例填充该数组。可能有比使用依赖注入(如Dagger)更干净的方法,但我对DI的经验有限。虽然与
SQLiteOpenHelper
无关,但显示了一个静态
ArrayList
和初始值设定项块。@Commonware如果我实现了如您所述的内容,我仍然能够连接表吗???@eddy:
JOIN
是您对查询执行的操作
SQLiteOpenHelper
与查询无关,只是在一定程度上它设置了您进行查询所针对的表。查询代码放在哪里取决于您自己。@commonware我明白了,那么我稍后会尝试一下,看看会出现什么。非常感谢你