java - 静态数据库连接SQLite

标签 java android sqlite android-sqlite

我想请任何人帮我修改我的数据库连接代码。我现在拥有的是它是我的方法类之一的一部分,每次我调用它时它都会建立一个连接(我知道它的效率非常低)。但是当我尝试将连接部分从方法中移出时,它会破坏代码。我只是想知道是否可以在某个地方创建一个静态类,以便我也可以在其他方法中重用它。

非常感谢您提前提供的任何帮助,非常感谢。

方法代码如下:

    public void getListDetail(){

   //listDetailData.clear();

    ShoppingListDatabase databaseConnection = new ShoppingListDatabase(this);
    final SQLiteDatabase db = databaseConnection.open();
    final ArrayList<ShoppingItem> lists = ShoppingListItemTable.selectAllItems(db, selectedID);
    databaseConnection.close();

    //create a list adapter and set adapter
    ShoppingListItemAdapter adapter = new ShoppingListItemAdapter(this, R.layout.activity_item_detail_list, lists);
    ListView_ListDetail = findViewById(R.id.ListView_ListDetail);
    ListView_ListDetail.setAdapter(adapter);
    adapter.notifyDataSetChanged();
   // ((ArrayAdapter<String>)ListView_ListDetail.getAdapter()).notifyDataSetChanged();
}

数据库类:

package com.puyakul.prin.psychic_shopping;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.ContactsContract;
import android.util.Log;

public class ShoppingListDatabase {

    private static final String TAG = "ShoppingListDatabase";
    private static final String DATABASE_NAME = "ShoppingListDatabase";
    private static final int DATABASE_VERSION = 3;

    private SQLiteDatabase mDb;
    private DatabaseHelper mDbHealper;
    private final Context mCtx;

    public ShoppingListDatabase(Context ctx){
        this.mCtx = ctx;
    }

    /**
     * DatabaseHelper class.
     *
     * Database helper class to manage connections with the database.
     */
    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context){
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "DatabaseHelper onCreate");
            db.execSQL(ShoppingListItemTable.CREATE_STATEMENT);
            db.execSQL(ShoppingListTable.CREATE_STATEMENT);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.d(TAG, "DatabaseHelper onUpgrade");
            db.execSQL("DROP TABLE IF EXISTS " + ShoppingListItemTable.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + ShoppingListTable.TABLE_NAME);
            onCreate(db); //this will recreate the database as if it were new
        }
    }

    public SQLiteDatabase open(){
        mDbHealper = new DatabaseHelper(mCtx);
        mDb = mDbHealper.getReadableDatabase();
        return mDb;
    }

    public void close(){
        mDb = null;
    }

}

我尝试在 onCreate 中声明变量,以便我可以与类中的其他方法一起使用,如下所示

    //================DATABASE CONNECTION=====================//
    private ShoppingListDatabase databaseConnection;
    private SQLiteDatabase db  = databaseConnection.open();


    private String selectedList;
    private int selectedID;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        setContentView(R.layout.activity_main_lists_detail);

      ShoppingListDatabase databaseConnection = new ShoppingListDatabase(this);
      SQLiteDatabase db = databaseConnection.open();
      lists = ShoppingListItemTable.selectAllItems(db, selectedID); 

这就是错误

 Process: com.puyakul.prin.psychic_shopping, PID: 5635
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.puyakul.prin.psychic_shopping/com.puyakul.prin.psychic_shopping.MainListsDetail}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.puyakul.prin.psychic_shopping.ShoppingListDatabase.open()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2548)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.puyakul.prin.psychic_shopping.ShoppingListDatabase.open()' on a null object reference
        at com.puyakul.prin.psychic_shopping.MainListsDetail.<init>(MainListsDetail.java:46)
        at java.lang.Class.newInstance(Native Method)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1078)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2538)

最佳答案

打开和关闭连接可能效率低下/成本高昂,因此也许引入/使用以下内容:-

public SQLiteDatabase open(){
    if (mDb == null) {
        mDbHealper = new DatabaseHelper(mCtx);
        mDb = mDbHealper.getReadableDatabase();
    }
    return mDb;
}

或者:-

public synchronized SQLiteDatabase open(){
    if (mDb == null) {
        mDbHealper = new DatabaseHelper(mCtx);
        mDb = mDbHealper.getReadableDatabase();
    }
    return mDb;
}

并且永远不要调用关闭,除非主要 Activity 正在被销毁。然后您将检索一个连接。

<小时/>

以下是一些基于您的 ShoppingListDatabase 类的使用示例。

首先是一个修改后的类,其中包含一些额外的方法(addShoppingListgetAllShoppingListsAsCursorlogDBTables)以及一个非常简单的购物列表 表:-

public class ShoppingListDatabase {

    private static final String TAG = "ShoppingListDatabase";
    private static final String DATABASE_NAME = "ShoppingListDatabase";
    private static final int DATABASE_VERSION = 3;

    private static final String TBNAME = "shoppinglist";
    public static final String COL_SHOPPINGLIST_NAME = "shoppinglist_name";

    private SQLiteDatabase mDb;
    private DatabaseHelper mDbHealper;
    private final Context mCtx;

    public ShoppingListDatabase(Context ctx){
        this.mCtx = ctx;
    }

    /**
     * DatabaseHelper class.
     *
     * Database helper class to manage connections with the database.
     */
    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context){
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "DatabaseHelper onCreate");
            //db.execSQL(ShoppingListItemTable.CREATE_STATEMENT);
            //db.execSQL(ShoppingListTable.CREATE_STATEMENT);
            String crtsql = "CREATE TABLE If NOT EXISTS " + TBNAME + "(" +
                    COL_SHOPPINGLIST_NAME + " TEXT " +
                    ")";
            db.execSQL(crtsql);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.d(TAG, "DatabaseHelper onUpgrade");

            //db.execSQL("DROP TABLE IF EXISTS " + ShoppingListItemTable.TABLE_NAME);
            //db.execSQL("DROP TABLE IF EXISTS " + ShoppingListTable.TABLE_NAME);
            onCreate(db); //this will recreate the database as if it were new
        }
    }

    public synchronized SQLiteDatabase open(){
        if (mDb == null) {
            mDbHealper = new DatabaseHelper(mCtx);
            mDb = mDbHealper.getReadableDatabase();
        }
        return mDb;
    }

    public void close(){
        mDb = null;
    }

    public long addShoppingList(String name) {
        ContentValues cv = new ContentValues();
        cv.put(COL_SHOPPINGLIST_NAME,name);
        return mDb.insert(TBNAME,null,cv);
    }

    public Cursor getAllShoppingListAsCursor() {
        return mDb.query(TBNAME,
                null,
                null,
                null,
                null,null,
                null
        );
    }

    public void logDBTables() {
        Cursor csr = mDb.query("sqlite_master",null,null,null,null,null,null);
        while (csr.moveToNext()) {
            Log.d(TAG,"Item " +
                    csr.getString(csr.getColumnIndex("name")) +
                    " was created using " +
                    csr.getString(csr.getColumnIndex("sql"))
            );
        }
    }
}

这是来自 Activity 的代码(以各种方式使用数据库连接):-

public class MainActivity extends AppCompatActivity {

    ShoppingListDatabase mSL;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSL = new ShoppingListDatabase(this);
        mSL.open();

        SO50312618();
        SO50312618_other();
        Cursor csr = mSL.getAllShoppingListAsCursor();
        while(csr.moveToNext()) {
            Log.d("SL INFO","Shopping List " + String.valueOf(csr.getPosition() + 1) +
                    " is " +
                    csr.getString(csr.getColumnIndex(ShoppingListDatabase.COL_SHOPPINGLIST_NAME))
            );
        }
    }

    private void SO50312618() {
        ShoppingListDatabase databaseConnection = new ShoppingListDatabase(this);
        SQLiteDatabase db = databaseConnection.open();
        databaseConnection.logDBTables();
    }

    private void SO50312618_other() {
        mSL.addShoppingList("List001");
        mSL.addShoppingList("List002");
    }
}

结果是:-

05-13 05:36:24.290 4245-4245/soanswers.soanswers D/ShoppingListDatabase: Item android_metadata was created using CREATE TABLE android_metadata (locale TEXT)
    Item shoppinglist was created using CREATE TABLE shoppinglist(shoppinglist_name TEXT )
05-13 05:36:24.302 4245-4245/soanswers.soanswers D/SL INFO: Shopping List 1 is List001
    Shopping List 2 is List002
  • 所有不同的用途都将使用同一个连接。

关于java - 静态数据库连接SQLite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50312618/

相关文章:

java - 如何在 Java 中执行等效的 cURL/mimetype 代码?

android - 无法在 Android(在 MarshMallow 及更高版本)设备中创建目录

python - 解码 NumPy int64 二进制表示

php - PDO PHP SQLite3 数据库连接一般错误14

java - 使用字符串和循环创建方法

java - android隐藏内部RelativeLayout防止 Activity 出现

java - 如何将多个 View 合并到一张位图中

android - 如何在 Android 服务中获取 ReactContext?

python - 在linux上与windows上不同的sqlite中存储空的python元组

Java远程数据同步