有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何将我的SQLHelper设置为Singleton

我想知道我的SQLHelper是否可以从SQLiteOpenHelper扩展为Singleton类

我的问题是:

要使用类从SQLiteOpenHelper扩展而来的对象,我们需要在实例化类时传递一个“this”上下文。 事实上,我想在任何地方使用我的助手,而不必再次实例化它

如果有人给我举一个例子作为解决方案,那就太好了:)

谢谢大家!

这是我目前的课程,也是我作为单身汉想要上的课程:

public class SQLHelper extends SQLiteOpenHelper {

/*
 Attributs
*/

public SQLHelper(Context context){
    super(context, DATABASE_NAME, null, 23);
}

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_TABLE_CATEGORIES = "CREATE TABLE " + TABLE_CATEGORIES + "(" + CATEGORY_NAME + " TEXT," + CATEGORY_ID + " INTEGER, " + CATEGORY_ID_PARENT + " INTEGER," + CATEGORY_URL_IMAGE + " TEXT" + ")" ;
    String CREATE_TABLE_INFOS = "CREATE TABLE " + TABLE_INFOS + "(" + INFOS_AGE + " INTEGER," + INFOS_MAIL + " TEXT," + INFOS_DISPLAY_PRICE + " TEXT," + INFOS_TOKEN + " TEXT," + INFOS_REFRESH_TOKEN + " TEXT," + INFOS_TOKEN_EXPIRATION + " TEXT, " + INFOS_REFRESH_TOKEN_EXPIRATION + " TEXT, " + INFOS_APP_VERSION + " TEXT" + ")";
    String CREATE_TABLE_ITEMS = "CREATE TABLE " + TABLE_ITEMS + "(" + ITEM_ID + " INTEGER," + ITEM_NAME + " TEXT," + ITEM_CATEGORY_ID + " INTEGER," + ITEM_PRICE + " REAL" + ")";
    String CREATE_TABLE_SHOPPING_LIST = "CREATE TABLE " + TABLE_SHOPPING_LIST + "(" + SHOPPING_LIST_ID + " INTEGER," + SHOPPING_LIST_NAME + " TEXT," + SHOPPING_LIST_DATE_CREATION + " TEXT" + ")";
    String CREATE_TABLE_SHOPPING_LIST_ITEMS = "CREATE TABLE " + TABLE_SHOPPING_LIST_ITEMS + "(" + SHOPPING_LIST_ITEMS_LIST_ID + " INTEGER," + SHOPPING_LIST_ITEMS_ID + " INTEGER," + SHOPPING_LIST_ITEMS_NB_ITEMS + " INTEGER," + SHOPPING_LIST_ITEMS_CHECKED + " INTEGER" + ")";
    db.execSQL(CREATE_TABLE_CATEGORIES);
    db.execSQL(CREATE_TABLE_INFOS);
    db.execSQL(CREATE_TABLE_ITEMS);
    db.execSQL(CREATE_TABLE_SHOPPING_LIST);
    db.execSQL(CREATE_TABLE_SHOPPING_LIST_ITEMS);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_CATEGORIES);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_INFOS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOPPING_LIST);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOPPING_LIST_ITEMS);
    onCreate(db);
}
/*
 Methods
*/
}

共 (3) 个答案

  1. # 1 楼答案

    你可以这样做,但我认为这不是个好主意:

    private static DataBaseHelper instance;
    
    private DataBaseHelper() {
        super(App.getAppContext(), DB_NAME, null, 1);
        this.context = context;
    }   
    
    public static DataBaseHelper getInstance() {
        if (instance == null) {
            instance = new DataBaseHelper();
        }
        return instance;
    }
    
  2. # 2 楼答案

    不——你用一种迂回的方式回答了自己的问题。因为需要提供一个参数(在本例中是context)来创建SQLiteHelper,所以单例模式将不起作用,因为每次初始化对象时它都必须是不同的。只有当需要一个相同的对象来协调整个系统的功能时,单例才起作用,而不仅仅是当您只需要一个对象的副本时

    你能强迫代码只存在SQLiteHelper的一个副本吗?当然-看看下面:

    private static volatile Class mClass  null;
    
    public static Class getInstance(Context context){
        if(mClass == null){
            synchronized(Class.class){
                if(mClass == null){
                    mClass = new Class(context);
                }
            }
        }
        return mClass;
    }
    

    一开始你会觉得这是个好主意。它看起来是一种创建单例的合法方法(尽管根据高效Java有更好的方法,比如使用enum类型)。实际上,您将只得到一个初始化类的副本。问题是context在任何情况下都是错误的,除了第一种情况。你不必是单身人士方面的专家,就能意识到这只是个坏主意

  3. # 3 楼答案

    使用私有构造函数和getInstance方法

    public class SQLHelper extends SQLiteOpenHelper {
    
    private static SQLHelper sqlHelper = null;
    
    private SQLHelper(Context context){
        super(context, DATABASE_NAME, null, 23);
    }
    
    public static SQLHelper getInstance(){
    if(sqlHelper == null){
    sqlHelper = new SQLHelper(context);
    return sqlHelper;
    }
    return sqlHelper;
    }