抱歉我的英语不好 我是Android Studio新手。
我有一个外部数据库。使用列id,text1,text2 ... text6 不知怎的,我成功地在youtube教程后将该数据库添加到我的应用程序中。这很好。
我将它添加到资产中,并将mainActivity复制到data / data / mypackage / databases。我在模拟器文件资源管理器中检查了它。
现在我需要从该数据库中获取数据,但我无法弄清楚如何做到这一点。
id列是自动增量整数。 我的应用程序中有一个数组,包含x在一定范围内随机生成的整数。 现在我想向数据库查询数组中的第一个整数,并使用结果更新活动中的textViews。用户点击按钮后,我需要从数组中发送下一个整数的另一个查询,依此类推。
我不知道热门打开数据库,发送查询...我尝试了很多教程,在互联网上搜索解决方案,但没有工作。现在我只是困惑。
我有SQL经验。那应该不是问题。在PHP和MySql中,只需几行代码即可完成。 任何人都可以帮我解决问题。
这是我的dbHelper
package com.examle.mydbapp;
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.SQLException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
class dbHelper extends SQLiteOpenHelper {
private static final String DATABASE_PATH = "/data/data/com.example.mydbapp/databases/";
private static final String DATABASE_NAME = "quotes.db";
private static final int SCHEMA_VERSION = 1;
public SQLiteDatabase dbSglite;
private final Context myContext;
public dbHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
this.myContext=context;
}
@Override
public void onCreate(SQLiteDatabase db){
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void createDatabase(){
createDB();
}
private void createDB(){
boolean dbExist = DBExists();
if(!dbExist){
this.getReadableDatabase();
copyDBFromResource();
}
}
private boolean DBExists(){
SQLiteDatabase db = null;
try {
String databasePath = DATABASE_PATH+DATABASE_NAME;
db = SQLiteDatabase.openDatabase(databasePath,null, SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
db.setVersion(1);
} catch (SQLiteException e) {
Log.e("SqlHelper", "database not found");
}
if (db != null) {
db.close();
}
return db != null ? true : false;
}
private void copyDBFromResource() {
InputStream inputStream = null;
OutputStream outputStream = null;
String dbFilePath=DATABASE_PATH+DATABASE_NAME;
try {
inputStream = myContext.getAssets().open(DATABASE_NAME);
outputStream = new FileOutputStream(dbFilePath);
byte[] buffer = new byte[1024];
int length;
while ((length=inputStream.read(buffer))>0){
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (IOException e) {
throw new Error("Problem copying database.");
}
}
public void openDataBase() throws SQLException {
String myPath = DATABASE_PATH + DATABASE_NAME;
dbSglite = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
}
答案 0 :(得分:1)
简而言之,假设您想要从活动中访问数据,那么
您可以 a)创建 databasehelper的实例 b)调用databasehelper的 createDatabase
方法然后 c)通过调用databasehelper的 getWriteableDatbase
方法来检索SQLiteDatabase实例。
(您可能已经完成了a和b)
e.g。 : -
dbhlpr = new dbHelper(this);
// Create the Database if need be
dbhlpr.createDatabase();
// An example of getting a instance outside of the helper
SQLiteDatabase db = dbhlpr.getWritableDatabase();
您也可以使用SQLiteDatabase db = dbhlpr.dbSglite;
代替SQLiteDatabase db = dbhlpr.getWritableDatabase();
dbhlpr
中的dbHelper dbhlpr;
是使用 Cursor csr = db.query("sqlite_master",null,null,null,null,null,null);
while (csr.moveToNext()) {
String tblinfo = "Row " + csr.getPosition();
for (int i=0; i < csr.getColumnCount(); i++) {
tblinfo = tblinfo + " Column = " + csr.getColumnName(i) + " Value = " + csr.getString(i);
}
Log.d("SQLITEINFO",tblinfo);
}
csr.close();
然后,您可以通过创建Cursor从表中检索数据。在以下示例中(前面的示例代码前面,并假设该表名为引号),您可以执行以下示例中的操作: -
// Get and process data from the quotes table
Cursor csr2 = db.query("quotes",null,null,null,null,null,null);
while (csr2.moveToNext()) {
String tblinfo = "Row " + csr2.getPosition();
for (int i=0; i < csr2.getColumnCount(); i++) {
tblinfo = tblinfo + " Column = " + csr2.getColumnName(i) + " Value = " + csr2.getString(i);
}
Log.d("CURSOR 2 INFO",tblinfo);
}
csr2.close();
// Get and processs data for a specific row according to id
Cursor csr3 = db.query("quotes",null,"id=?",new String[]{"1"},null,null,null);
if (csr3.moveToFirst()) {
Log.d("CURSOR 3 INFO",
" ID is" + csr3.getLong(0) +
" ID is " + csr3.getLong(csr3.getColumnIndex("id")) +
" TEXT1 is " + csr3.getString(csr3.getColumnIndex("text1"))
// ..... etc
);
}
csr3.close();
csr3.getLong(0)
csr3.getLong(csr3.getColumnIndex("id"))
可能会出现问题,因此替代方案更加灵活query
move????
方法返回Cursor时,它的位置在第一行(-1)之前。要访问数据,您必须使用 csr3.moveToFirst()
方法,例如的 move????
即可。如果移动,则 -15 11:30:20.066 8446-8446/? E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
11-15 11:30:20.066 8446-8446/? E/SQLiteLog: (14) os_unix.c:30046: (2) open(/data/data/mjt.usingrecyclerviews/databases/quotes.db) -
11-15 11:30:20.066 8446-8446/? E/SQLiteDatabase: Failed to open database '/data/data/mjt.usingrecyclerviews/databases/quotes.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
at mjt.usingrecyclerviews.dbHelper.DBExists(dbHelper.java:68)
at mjt.usingrecyclerviews.dbHelper.createDB(dbHelper.java:54)
at mjt.usingrecyclerviews.dbHelper.createDatabase(dbHelper.java:49)
at mjt.usingrecyclerviews.MainActivity.onCreate(MainActivity.java:27)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
11-15 11:30:20.066 8446-8446/? E/SqlHelper: database not found
11-15 11:30:20.093 8446-8446/? D/ONCREATE: OnCreate Method Called.
11-15 11:30:20.096 8446-8446/? D/SQLITEINFO: Row 0 Column = type Value = table Column = name Value = quotes Column = tbl_name Value = quotes Column = rootpage Value = 2 Column = sql Value = CREATE TABLE quotes (id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, text3 TEXT, text4 TEXT, text5 TEXT)
11-15 11:30:20.096 8446-8446/? D/SQLITEINFO: Row 1 Column = type Value = table Column = name Value = android_metadata Column = tbl_name Value = android_metadata Column = rootpage Value = 3 Column = sql Value = CREATE TABLE android_metadata (locale TEXT)
11-15 11:30:20.096 8446-8446/? D/CURSOR 2 INFO: Row 0 Column = id Value = 1 Column = text1 Value = Some quote Column = text2 Value = Another quote Column = text3 Value = Yet another quote Column = text4 Value = This is a quote Column = text5 Value = Too many quotes
11-15 11:30:20.096 8446-8446/? D/CURSOR 2 INFO: Row 1 Column = id Value = 2 Column = text1 Value = Seccond quote Column = text2 Value = Third Quote Column = text3 Value = Fourth Quote Column = text4 Value = Fifth Quote Column = text5 Value = Sixth Quote
11-15 11:30:20.096 8446-8446/? D/CURSOR 3 INFO: ID is1 ID is 1 TEXT1 is Some quote
方法返回true,如果无法移动则返回false。 上面的代码已使用DatabaseHelper进行测试,该数据库与问题中提供的DatabaseHelper非常相似。
数据库是在应用程序外部创建的,其中添加了一个名为引号的表,其中添加了两行数据: -
11-15 11:33:17.111 8511-8511/mjt.usingrecyclerviews D/SQLITEINFO: Row 0 Column = type Value = table Column = name Value = quotes Column = tbl_name Value = quotes Column = rootpage Value = 2 Column = sql Value = CREATE TABLE quotes (id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, text3 TEXT, text4 TEXT, text5 TEXT)
11-15 11:33:17.111 8511-8511/mjt.usingrecyclerviews D/SQLITEINFO: Row 1 Column = type Value = table Column = name Value = android_metadata Column = tbl_name Value = android_metadata Column = rootpage Value = 3 Column = sql Value = CREATE TABLE android_metadata (locale TEXT)
11-15 11:33:17.111 8511-8511/mjt.usingrecyclerviews D/CURSOR 2 INFO: Row 0 Column = id Value = 1 Column = text1 Value = Some quote Column = text2 Value = Another quote Column = text3 Value = Yet another quote Column = text4 Value = This is a quote Column = text5 Value = Too many quotes
11-15 11:33:17.112 8511-8511/mjt.usingrecyclerviews D/CURSOR 2 INFO: Row 1 Column = id Value = 2 Column = text1 Value = Seccond quote Column = text2 Value = Third Quote Column = text3 Value = Fourth Quote Column = text4 Value = Fifth Quote Column = text5 Value = Sixth Quote
11-15 11:33:17.113 8511-8511/mjt.usingrecyclerviews D/CURSOR 3 INFO: ID is1 ID is 1 TEXT1 is Some quote
请注意!文件错误被捕获并被绕过/处理(即仅仅因为数据库不存在)
context.getDatabasePath(DATABASE_NAME).getParent();
由于packagename在Databasehelper中是硬编码的,因此必须进行更改。因此,不是硬编码包,而是通过File databasesdir = new File(myContext.getDatabasePath(DATABASE_NAME).getParent());
databasesdir.mkdirs();
获取数据库路径(没有databasename和separatinf /)。如果数据库文件夹/目录不存在,更改的帮助程序将使用class dbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "quotes.db";
private static final int SCHEMA_VERSION = 1;
public SQLiteDatabase dbSglite;
private String mDBPAth;
private final Context myContext;
public dbHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
this.myContext=context;
this.mDBPAth = context.getDatabasePath(DATABASE_NAME).getParent();
}
@Override
public void onCreate(SQLiteDatabase db){
Log.d("ONCREATE","OnCreate Method Called.");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void createDatabase(){
createDB();
}
private void createDB(){
boolean dbExist = DBExists();
if(!dbExist){
copyDBFromResource();
}
dbSglite = getWritableDatabase();
}
private boolean DBExists(){
SQLiteDatabase db = null;
try {
String databasePath = myContext.getDatabasePath(DATABASE_NAME).getPath();
db = SQLiteDatabase.openDatabase(databasePath,null, SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
db.setVersion(1);
} catch (SQLiteException e) {
Log.e("SqlHelper", "database not found");
}
if (db != null) {
db.close();
}
return db != null;
}
private void copyDBFromResource() {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = myContext.getAssets().open(DATABASE_NAME);
File databasesdir = new File(myContext.getDatabasePath(DATABASE_NAME).getParent());
databasesdir.mkdirs();
outputStream = new FileOutputStream(mDBPAth+"/"+DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length=inputStream.read(buffer))>0){
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
throw new Error("Problem copying database.");
}
}
public void openDataBase() throws SQLException {
String myPath = myContext.getDatabasePath(DATABASE_NAME).getPath();
dbSglite = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
}
完整的助手是: -
docker run -p $PM0Port:2551 --rm -e "HOST_IP=$IP" -e "HOST_PORT=$PM0Port" -v $entityLogs:/logs/entityLogs $Image partitionManager $PM0ID $NumberOfPartitions $ZooKeeper