繁体   English   中英

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

[英]Insert, Delete, Retrieve data from and into existing sqlite database in assests folder

我创建了一个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(?,?,?,?,?,?,?,?,?,?)";
}

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

现有代码:

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

更新的代码:

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

        **os.flush();os.close();        
       is.close();**
    }
}

问题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方法(有效)。

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

:-

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.

我还想根据此应用程序中用户功能提供的搜索框值,从数据库中添加检索数据(单击按钮时)。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM