我创建了一个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(?,?,?,?,?,?,?,?,?,?)";
}
答案 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)
您需要调用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方法将不会复制数据库,因为它已经存在。)
为方便起见,注释掉了行。
最好不要硬编码数据库路径,而应通过the_context.getDatabasePath(database_name).getPath
方法检索它。
因此,建议您更改:-
String path = DBConstant.DATABASE_PATH + "/" + DBConstant.DATABASE_FILE;
改为:-
String path = context.getDatabasePath(DBConstant.DATABASE_FILE).getPath();
例如“-
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>
:-
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)
请注意,原始捕获的异常()和发出的运行时异常有两个异常(您必须具有try / catch,因为copyDB方法会引发异常,因此也可能会引发运行时异常)
:-
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)可用于某些列,例如说出性别,何时会有一组特定的值。