在assests文件夹中的现有sqlite数据库中插入数据,将其删除,检索数据

时间:2018-11-12 07:38:50

标签: java android sqlite android-studio

我创建了一个sqlite数据库并将其放置在我的android项目的资产文件夹中。现在,我要在此数据库上执行Insert,Delete,Retrieve操作。

我创建了一个新活动,在该活动中,我将输入一个人的详细信息,然后按保存按钮(checkout_btn),以将该信息保存到现有数据库中。

我不知道这段代码有什么问题。我没有任何错误,甚至没有数据插入到现有数据库中。

我还想根据此应用程序中用户功能提供的搜索框值从数据库添加检索数据(on button click)

这是我的代码:

 This class talk about my database which is already present in my assets folder in my project. In this database only i have to insert my data from a form.

**DBConstant.Java**

public abstract class DBConstant
{ //database file directory
public static String DATABASE_PATH = "/data/data/activity.test/databases";
//database file name
public static String DATABASE_FILE = "test.db";
//database version
public static int DATABASE_VERSION = 1;
}

**This is my DBOpenHelper.Java file**

**DBOpenHelper.Java**


public class DBOpenHelper extends SQLiteOpenHelper {

public DBOpenHelper(Context context, String path, int version){
    super(context, path, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override

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

}

**Below is my DBOperator.Java file**



/**
* Class to manipulate tables & data
* Uses singleton pattern to create single instance
*/
public class DBOperator
{
private static DBOperator instance = null;
private SQLiteDatabase db;

private DBOperator()
{
    //path of database file
    String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;
    db = SQLiteDatabase.openDatabase(path, null, 
SQLiteDatabase.OPEN_READWRITE);
}
/*
 * Singleton Pattern
 * Why should we avoid multiple instances here?
 */
public static DBOperator getInstance()
{
    if (instance==null) instance = new DBOperator();
    return instance;
}
/**
 * Copy database file
 * From assets folder (in the project) to android folder (on device)
 */
public static void copyDB(Context context) throws 
IOException,FileNotFoundException{
    String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;
    File file = new File(path);
    if (!file.exists()){
        DBOpenHelper dbhelper = new DBOpenHelper(context, path ,1);
        dbhelper.getWritableDatabase();
        InputStream is = context.getAssets().open(DBConstant.DATABASE_FILE);
        OutputStream os = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer))>0){
            os.write(buffer, 0, length);
        }
        is.close();
        os.flush();
        os.close();
    }
 }
 /**
 * execute sql without returning data, such as alter
 * @param sql
 */
 public void execSQL(String sql) throws SQLException
 {
    db.execSQL(sql);
 }
 /**
 * execute sql such as update/delete/insert
 * @param sql
 * @param args
 * @throws SQLException
 */
 public void execSQL(String sql, Object[] args) throws SQLException
 {
    db.execSQL(sql, args);
 }
/**
 * execute sql query
 * @param sql
 * @param selectionArgs
 * @return cursor
 * @throws SQLException
 */
public Cursor execQuery(String sql,String[] selectionArgs) throws 
SQLException
{
    return db.rawQuery(sql, selectionArgs);
}
/**
 * execute query without arguments
 * @param sql
 * @return
 * @throws SQLException
 */
public Cursor execQuery(String sql) throws SQLException
{
    return this.execQuery(sql, null);
}
/**
 * close database
 */
public void closeDB()
{
    if (db!=null) db.close();
}
}


Here is my DBOperator.Java

/**
* Class to manipulate tables & data
* Uses singleton pattern to create single instance
*/
public class DBOperator
{
private static DBOperator instance = null;
private SQLiteDatabase db;

private DBOperator()
{
    //path of database file
    String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;
    db = SQLiteDatabase.openDatabase(path, null, 
SQLiteDatabase.OPEN_READWRITE);
}
/*
 * Singleton Pattern
 * Why should we avoid multiple instances here?
 */
public static DBOperator getInstance()
{
    if (instance==null) instance = new DBOperator();
    return instance;
}
/**
 * Copy database file
 * From assets folder (in the project) to android folder (on device)
 */
public static void copyDB(Context context) throws 
IOException,FileNotFoundException{
    String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;
    File file = new File(path);
    if (!file.exists()){
        DBOpenHelper dbhelper = new DBOpenHelper(context, path ,1);
        dbhelper.getWritableDatabase();
        InputStream is = context.getAssets().open(DBConstant.DATABASE_FILE);
        OutputStream os = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer))>0){
            os.write(buffer, 0, length);
        }
        is.close();
        os.flush();
        os.close();
    }
}

/**
 * execute sql without returning data, such as alter
 * @param sql
 */
public void execSQL(String sql) throws SQLException
{
    db.execSQL(sql);
}
/**
 * execute sql such as update/delete/insert
 * @param sql
 * @param args
 * @throws SQLException
 */
public void execSQL(String sql, Object[] args) throws SQLException
{
    db.execSQL(sql, args);
}
/**
 * execute sql query
 * @param sql
 * @param selectionArgs
 * @return cursor
 * @throws SQLException
 */
public Cursor execQuery(String sql,String[] selectionArgs) throws 
SQLException
{
    return db.rawQuery(sql, selectionArgs);
}
/**
 * execute query without arguments
 * @param sql
 * @return
 * @throws SQLException
 */
public Cursor execQuery(String sql) throws SQLException
{
    return this.execQuery(sql, null);
}
/**
 * close database
 */
public void closeDB()
{
    if (db!=null) db.close();
}
}

NewActivity.java

public class NewpActivity extends AppCompatActivity
{
String PaFirstName,PaLastName,PaDOB,PaGender,PaContact,PaStreetAPT,PaCity,PaState,country,PaPincode,PaInsurance;
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    setContentView(R.layout.activity_newp);
    Button signUpBtn = (Button) findViewById(R.id.checkout_btn);
    signUpBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            //Running method for updating string variables from input boxes
            getValues();
            DBOperator.getInstance().execSQL(SQLCommand.NEW_USER, getArgs());
            Toast.makeText(getBaseContext(), "Checkout successfully", Toast.LENGTH_SHORT).show();

        }


    });
}

SQLCommand.java

public abstract class SQLCommand {
    public static String NEW_USER = "insert into Patient(PaFirstName,PaLastName,PaDOB,PaGender,PaContact,PaStreetAPT,PaCity,PaState,PaPincode,PaInsurance) values(?,?,?,?,?,?,?,?,?,?)";
}

2 个答案:

答案 0 :(得分:0)

在copy db方法中,需要在刷新输出流后关闭输入流。

现有代码:

[[1, 1, 4], [1, 1, 5], [1, 2, 4], [1, 2, 5], [2, 1, 4], [2, 1, 5], [2, 2, 4], [2, 2, 5], [3, 1, 4], [3, 1, 5], [3, 2, 4], [3, 2, 5]]

更新的代码:

public static void copyDB(Context context) throws 
IOException,FileNotFoundException{
    String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;
    File file = new File(path);
    if (!file.exists()){
        DBOpenHelper dbhelper = new DBOpenHelper(context, path ,1);
        dbhelper.getWritableDatabase();
        InputStream is = context.getAssets().open(DBConstant.DATABASE_FILE);
        OutputStream os = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer))>0){
            os.write(buffer, 0, length);
        }
        **is.close();
        os.flush();
        os.close();**
    }
}

答案 1 :(得分:0)

问题1-不调用DBOperator copyDB 方法。

您需要调用copyDB方法,以便从资产文件夹复制数据库。否则,将创建一个空数据库。

这应该在尝试获取DBOperator实例之前完成。例如,在设置Activity的ContentView后立即进行此调用很方便。

public class NewpActivity extends AppCompatActivity {
    String PaFirstName, PaLastName, PaDOB, PaGender, PaContact, PaStreetAPT, PaCity, PaState, country, PaPincode, PaInsurance;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        setContentView(R.layout.activity_newp);
        Button signUpBtn = (Button) findViewById(R.id.checkout_btn);
        try {
            DBOperator.copyDB(this);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("DB Copy Failed. Issuing runtime exception");
        }
        signUpBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Running method for updating string variables from input boxes
                //getValues();
                //DBOperator.getInstance().execSQL(SQLCommand.NEW_USER, getArgs());
                Toast.makeText(getBaseContext(), "Checkout successfully", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
  • 请注意,在运行更正的代码之前,您应该删除应用程序的数据或卸载应用程序,以便删除数据库(否​​则copyDB方法将不会复制数据库,因为它已经存在。)

  • 为方便起见,注释掉了行。

问题2-(不是错误)

最好不要硬编码数据库路径,而应通过the_context.getDatabasePath(database_name).getPath方法检索它。

因此,建议您更改:-

String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;

改为:-

String path = context.getDatabasePath(DBConstant.DATABASE_FILE).getPath();

其他内容

  1. 首先,可能要先确认数据库包含预期的表,然后添加代码(在Activit的onCreate方法中添加所有其他内容)

例如“-

public class NewpActivity extends AppCompatActivity {
    String PaFirstName, PaLastName, PaDOB, PaGender, PaContact, PaStreetAPT, PaCity, PaState, country, PaPincode, PaInsurance;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        setContentView(R.layout.activity_newp);
        Button signUpBtn = (Button) findViewById(R.id.checkout_btn);
        try {
            DBOperator.copyDB(this);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("DB Copy Failed. Issuing runtime exception");
        }
        signUpBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Running method for updating string variables from input boxes
                //getValues();
                //DBOperator.getInstance().execSQL(SQLCommand.NEW_USER, getArgs());
                Toast.makeText(getBaseContext(), "Checkout successfully", Toast.LENGTH_SHORT).show();
            }
        });

        //<<<<<<<<<< ADDED TO CONFIRM DATABASE IS AS EXPECTED
        DBOperator checkit = DBOperator.getInstance();
        Cursor csr = checkit.execQuery("SELECT * FROM sqlite_master");
        while (csr.moveToNext()) {
            Log.d(
                    "DBINFO",
                    "Item with a name of " + csr.getString(csr.getColumnIndex("name")) +
                            " and a type of " + csr.getString(csr.getColumnIndex("type")) +
                            " found in the Database."
            );
        }
    }
}
  • 注意:以上示例说明了如何从表中获取数据并对其进行处理,并且使用了您的 execQuery 方法(有效)。< / p>

    1. 如果未将数据库复制到资产文件夹,并且使用了上面的代码,则会在
    2. 处出现错误

:-

11-12 10:17:01.494 2025-2025/? W/System.err: java.io.FileNotFoundException: fail.db
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.content.res.AssetManager.openAsset(Native Method)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:315)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:289)
11-12 10:17:01.494 2025-2025/? W/System.err:     at test.activity.test.DBOperator.copyDB(DBOperator.java:54)
11-12 10:17:01.494 2025-2025/? W/System.err:     at test.activity.test.NewpActivity.onCreate(NewpActivity.java:21)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.Activity.performCreate(Activity.java:5008)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.os.Looper.loop(Looper.java:137)
11-12 10:17:01.494 2025-2025/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:4745)
11-12 10:17:01.494 2025-2025/? W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
11-12 10:17:01.494 2025-2025/? W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
11-12 10:17:01.494 2025-2025/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-12 10:17:01.494 2025-2025/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-12 10:17:01.494 2025-2025/? W/System.err:     at dalvik.system.NativeStart.main(Native Method)
11-12 10:17:01.494 2025-2025/? D/AndroidRuntime: Shutting down VM
11-12 10:17:01.494 2025-2025/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa62a3288)
11-12 10:17:01.494 2025-2025/? E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{test.activity.test/test.activity.test.NewpActivity}: java.lang.RuntimeException: DB Copy Failed. Issuing runtime exception
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.RuntimeException: DB Copy Failed. Issuing runtime exception
        at test.activity.test.NewpActivity.onCreate(NewpActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
        at android.app.ActivityThread.access$600(ActivityThread.java:130) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 
  • 通过将数据库名称更改为fail.db来强制失败
  • 请注意,原始捕获的异常()和发出的运行时异常有两个异常(您必须具有try / catch,因为copyDB方法会引发异常,因此也可能会引发运行时异常)

    1. 如果运行良好(复制数据库或如果数据库不存在,则不复制)将记录以下输出(如果您有更多表或其他具有索引,触发器,视图的项目,则可能会更多)

:-

11-12 09:59:08.910 1917-1917/test.activity.test D/DBINFO: Item with a name of patient and a type of table found in the Database.
11-12 09:59:08.910 1917-1917/test.activity.test D/DBINFO: Item with a name of android_metadata and a type of table found in the Database.
  

我还想从数据库上添加检索数据(单击按钮)   用户功能在此提供的搜索框值的基础   应用。

现在您应该尝试做的,如果遇到问题,则应该提出一个新问题。您需要决定如何做。您要搜索各种列吗?您是否希望结果随输入而更改,或者您想单击以启动搜索。也许下拉列表选择器(Spinner)可用于某些列,例如说出性别,何时会有一组特定的值。