我该如何分割很长,单SQLiteOpenHelper为serveral的班,每个表很长、我该、serveral、SQLiteOpenHelper

2023-09-12 10:10:39 作者:谁把我当备胎我让他爆胎

我知道这已经被问了几次才,但在所有这些问题既不是OP的,也没有谁回答的人,提供了明确的例子。

所以,我想在这里问的是,如果有一个这样的类

 公共类MyDatabaseDB {

    //数据库常量
    公共静态最后弦乐DB_NAME =mydatabase.db;
    公共静态最终诠释DB_VERSION = 1;

    //清单表常数
    公共静态最后弦乐LIST_TABLE =清单;

    公共静态最后弦乐LIST_ID =_id;
    公共静态最终诠释LIST_ID_COL = 0;

    公共静态最后弦乐LIST_NAME =LIST_NAME;
    公共静态最终诠释LIST_NAME_COL = 1;

    //任务表常数
    公共静态最后弦乐TASK_TABLE =任务;

    公共静态最后弦乐TASK_ID =_id;
    公共静态最终诠释TASK_ID_COL = 0;

    公共静态最后弦乐TASK_LIST_ID =list_id;
    公共静态最终诠释TASK_LIST_ID_COL = 1;

    公共静态最后弦乐TASK_NAME =TASK_NAME;
    公共静态最终诠释TASK_NAME_COL = 2;

    //创建和删除TABLE语句
    公共静态最后弦乐CREATE_LIST_TABLE =
            CREATE TABLE+ LIST_TABLE +(+
            LIST_ID +INTEGER PRIMARY KEY AUTOINCREMENT,+
            LIST_NAME +TEXT唯一的);

    公共静态最后弦乐CREATE_TASK_TABLE =
            CREATE TABLE+ TASK_TABLE +(+
            TASK_ID +INTEGER PRIMARY KEY AUTOINCREMENT,+
            TASK_LIST_ID +INTEGER,+
            TASK_NAME +TEXT+
           );

    公共静态最后弦乐DROP_LIST_TABLE =
            DROP TABLE IF EXISTS+ LIST_TABLE;

    公共静态最后弦乐DROP_TASK_TABLE =
            DROP TABLE IF EXISTS+ TASK_TABLE;

    私有静态类DBHelper扩展SQLiteOpenHelper {

        公共DBHelper(上下文的背景下,字符串名称,
                CursorFactory工厂,INT版){
            超(背景下,名称,厂家,版本);
        }

        @覆盖
        公共无效的onCreate(SQLiteDatabase DB){
            //创建表
            db.execSQL(CREATE_LIST_TABLE);
            db.execSQL(CREATE_TASK_TABLE);

            //插入列表
            db.execSQL(INSERT INTO列表值(1,'爱好'));
            db.execSQL(INSERT INTO列表值(2,'运动'));

            //插入示例任务
            db.execSQL(INSERT INTO任务VALUES(1,1,弹吉他'));
            db.execSQL(INSERT INTO任务VALUES(2,1,玩视频游戏'));
        }

        @覆盖
        公共无效onUpgrade(SQLiteDatabase分贝,
                INT oldVersion,诠释静态网页){

            Log.d(任务列表,从版本升级数据库
                    + oldVersion +到+静态网页);


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

    //数据库对象和数据库辅助对象
    私人SQLiteDatabase分贝;
    私人DBHelper dbHelper;

    //构造
    公共MyDatabaseDB(上下文的背景下){
        dbHelper =新DBHelper(背景下,DB_NAME,空,DB_VERSION);
    }

    //私有方法
    私人无效openReadableDB(){
        DB = dbHelper.getReadableDatabase();
    }

    私人无效openWriteableDB(){
        DB = dbHelper.getWritableDatabase();
    }

    私人无效closeDB(){
        如果(DB!= NULL)
            db.close();
    }

    //公共方法

    众长insertTask(工作任务){
        ContentValues​​ CV =新ContentValues​​();
        cv.put(TASK_LIST_ID,task.getListId());
        cv.put(TASK_NAME,task.getName());

        this.openWriteableDB();
        长ROWID = db.insert(TASK_TABLE,空,CV);
        this.closeDB();

        返回ROWID;
    }

    公众诠释updateTask(工作任务){
        ContentValues​​ CV =新ContentValues​​();
        cv.put(TASK_LIST_ID,task.getListId());
        cv.put(TASK_NAME,task.getName());

        字符串,其中= TASK_ID +=?;
        的String [] whereArgs = {将String.valueOf(task.getId())};

        this.openWriteableDB();
        INT rowCount等= db.update(TASK_TABLE,CV,在这里,whereArgs);
        this.closeDB();

        返回rowCount等;
    }

    公众诠释DeleteTask活动(长ID){
        字符串,其中= TASK_ID +=?;
        的String [] whereArgs = {将String.valueOf(ID)};

        this.openWriteableDB();
        INT rowCount等= db.delete(TASK_TABLE,其中,whereArgs);
        this.closeDB();

        返回rowCount等;
    }
}
 

这是我班的一个非常简化版本,内置使用一些code,我发现上线。在这个例子中我只显示了我的两个表code:列表和任务,而只是一些SQL方法任务表:insertTask,updateTask和DeleteTask活动

尽管上述作品中的code,我不认为这会是不错的所有code的假设都在同一个类十张桌子。于是,我就拆所有这些code分为几类,一为每个表。事情是这样的:

 公共类MyDatabaseDB {

    //数据库常量
    公共静态最后弦乐DB_NAME =mydatabase.db;
    公共静态最终诠释DB_VERSION = 1;


    私有静态类DBHelper扩展SQLiteOpenHelper {

        公共DBHelper(上下文的背景下,字符串名称,
                CursorFactory工厂,INT版){
            超(背景下,名称,厂家,版本);
        }

        @覆盖
        公共无效的onCreate(SQLiteDatabase DB){
            //创建表
            db.execSQL(ListDAL.CREATE_LIST_TABLE);
            db.execSQL(TaskDAL.CREATE_TASK_TABLE);

            //插入列表
            db.execSQL(INSERT INTO列表值(1,'爱好'));
            db.execSQL(INSERT INTO列表值(2,'运动'));

            //插入示例任务
            db.execSQL(INSERT INTO任务VALUES(1,1,弹吉他'));
            db.execSQL(INSERT INTO任务VALUES(2,1,玩视频游戏'));
        }

        @覆盖
        公共无效onUpgrade(SQLiteDatabase分贝,
                INT oldVersion,诠释静态网页){

            Log.d(任务列表,从版本升级数据库
                    + oldVersion +到+静态网页);


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

    //数据库对象和数据库辅助对象
    私人SQLiteDatabase分贝;
    私人DBHelper dbHelper;

    //构造
    公共MyDatabaseDB(上下文的背景下){
        dbHelper =新DBHelper(背景下,DB_NAME,空,DB_VERSION);
    }

    //私有方法
    私人无效openReadableDB(){
        DB = dbHelper.getReadableDatabase();
    }

    私人无效openWriteableDB(){
        DB = dbHelper.getWritableDatabase();
    }

    私人无效closeDB(){
        如果(DB!= NULL)
            db.close();
    }

}
 

这些是两个新的类,在把code与某一特定的表我:

在ListDAL没有太多code

 公共类ListDAL {

   //清单表常数
    公共静态最后弦乐LIST_TABLE =清单;

    公共静态最后弦乐LIST_ID =_id;
    公共静态最终诠释LIST_ID_COL = 0;

    公共静态最后弦乐LIST_NAME =LIST_NAME;
    公共静态最终诠释LIST_NAME_COL = 1;

    //创建和删除TABLE语句
    公共静态最后弦乐CREATE_LIST_TABLE =
            CREATE TABLE+ LIST_TABLE +(+
            LIST_ID +INTEGER PRIMARY KEY AUTOINCREMENT,+
            LIST_NAME +TEXT唯一的);

    公共静态最后弦乐DROP_LIST_TABLE =
            DROP TABLE IF EXISTS+ LIST_TABLE;


}
 
我的2018双十一清单

该TaskDAL类是包含大部分的code中的一个,它是在这个类中,我有问题,特别是在 insertTask,updateTask 和 DeleteTask活动用这样的方法调用的 this.openWriteableDB(),this.openWriteableDB()或类似电话的 db.insert(TASK_TABLE,空,CV)。

由于这些方法都不再里面TaskDAL,我不能让他们接触。 我尝试过一些参考这些方法代替所使用的这或分贝,但没有奏效。

 公共类TaskDAL {
    //任务表常数
    公共静态最后弦乐TASK_TABLE =任务;

    公共静态最后弦乐TASK_ID =_id;
    公共静态最终诠释TASK_ID_COL = 0;

    公共静态最后弦乐TASK_LIST_ID =list_id;
    公共静态最终诠释TASK_LIST_ID_COL = 1;

    公共静态最后弦乐TASK_NAME =TASK_NAME;
    公共静态最终诠释TASK_NAME_COL = 2;

    //创建和删除TABLE语句
    公共静态最后弦乐CREATE_TASK_TABLE =
            CREATE TABLE+ TASK_TABLE +(+
            TASK_ID +INTEGER PRIMARY KEY AUTOINCREMENT,+
            TASK_LIST_ID +INTEGER,+
            TASK_NAME +TEXT+
           );
    公共静态最后弦乐DROP_TASK_TABLE =
            DROP TABLE IF EXISTS+ TASK_TABLE;

     //公共方法

    众长insertTask(工作任务){
        ContentValues​​ CV =新ContentValues​​();
        cv.put(TASK_LIST_ID,task.getListId());
        cv.put(TASK_NAME,task.getName());

        this.openWriteableDB();
        长ROWID = db.insert(TASK_TABLE,空,CV);
        this.closeDB();

        返回ROWID;
    }

    公众诠释updateTask(工作任务){
        ContentValues​​ CV =新ContentValues​​();
        cv.put(TASK_LIST_ID,task.getListId());
        cv.put(TASK_NAME,task.getName());

        字符串,其中= TASK_ID +=?;
        的String [] whereArgs = {将String.valueOf(task.getId())};

        this.openWriteableDB();
        INT rowCount等= db.update(TASK_TABLE,CV,在这里,whereArgs);
        this.closeDB();

        返回rowCount等;
    }

    公众诠释DeleteTask活动(长ID){
        字符串,其中= TASK_ID +=?;
        的String [] whereArgs = {将String.valueOf(ID)};

        this.openWriteableDB();
        INT rowCount等= db.delete(TASK_TABLE,其中,whereArgs);
        this.closeDB();

        返回rowCount等;
    }
}
 

那么,有什么你曾经尝试过这样类似的东西? 如果我设法正确分离数据库code分为几类,我将仍然能够连接表??

一如往常的任何帮助将非常AP preciated。

P.S。请不要关闭这个问题,如果你觉得我做错了什么,请告诉我,我会尽力改正它

解决方案   

你认为你可以就如何做到这一点的一些提示

这有没有什么做与Android,甚至没有多少做与Java。分解长的编程结构(例如,在Java类)转换成​​更小的结构有标准的技术,被称为设计模式,具有特定语言的实现。

例如,你可以用组合模式:

定义一个接口 - 我称之为 TableHelper 在这里 - 有的onCreate()的OnUpdate()匹配那些方法 SQLiteOpenHelper

定义N个班,每个表中的一个,该实施 TableHelper 接口,并提供了创建和升级逻辑,该表(以及任何其他的业务逻辑您要对这些类)

让你的 SQLiteOpenHelper 定义 TableHelper [] 包含的实例你的 TableHelper 类,并将其委托的onCreate() onUpgrade()那些 TableHelper 通过遍历数组实例

I know this has been asked a couple of times before, but in all those questions neither the OP's nor the people who answered, provided clear examples.

So what I'm trying to ask here is if having a class like this

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

This is a very reduced version of my class , built using some code I found on-line. In this example I'm only showing the code for two of my tables : List and Task, and just some of the sql methods for the Task table : insertTask,updateTask, and deleteTask.

Even though the code shown above works, I don't think it would be nice to have all the code for let's say ten tables all in the same class. So I tried to split all these code into several classes , one for each table. Something like this:

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

}

These are the two new classes, the I created to put the code related to a specific table :

The ListDAL doesn't have much code

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;


}

The TaskDAL class is the one that contains most of the code, and it is in this class that I have problems, specifically in the insertTask,updateTask and deleteTask with calls like this.openWriteableDB(),this.openWriteableDB() or calls like db.insert(TASK_TABLE, null, cv).

Since these methods are no longer inside TaskDAL, I can't get access to them. I tried passing some references to these methods to be used in place of this or db, but it didn't work

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

So, have any of you ever tried to so something similar?? If I managed to correctly separate the DB code into several classes, would I be still able to JOIN tables??

As always any help will be much appreciated.

P.S. Please do not close this question, if you think I did something wrong please tell me and I'll try to correct it

解决方案

do you think you could give some hints on how to do it

This has nothing much to do with Android, and even not all that much to do with Java. Decomposing long programming structures (e.g., classes in Java) into smaller structures has standard techniques, called design patterns, with language-specific implementations.

For example, you could go with the composite pattern:

Define an interface -- I'll call it TableHelper here -- that has onCreate() and onUpdate() methods that match those on SQLiteOpenHelper

Define N classes, one per table, that implement the TableHelper interface and provide the create and upgrade logic for that table (along with whatever other business logic you want to have on those classes)

Have your SQLiteOpenHelper define a TableHelper[] containing instances of your TableHelper classes, and have it delegate onCreate() and onUpgrade() to those TableHelper instances by iterating over the array