从sqlite中检索记录

时间:2017-11-14 20:33:04

标签: android sqlite android-sqlite

抱歉我的英语不好 我是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);

    }

}

1 个答案:

答案 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从表中检索数据。在以下示例中(前面的示例代码前面,并假设该表名为引号),您可以执行以下示例中的操作: -

EX 1(来自sqlite_master)

    // 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();

EX 2(引号表中的所有行)

    // 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();

EX 3 - 使用WHERE子句和占位符的特定行?

csr3.getLong(0)

注意事项: -

  • 空光标是有效光标a;查询不会返回空游标。
  • 使用列偏移,例如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非常相似。

数据库是在应用程序外部创建的,其中添加了一个名为引号的表,其中添加了两行数据: -

enter image description here

测试1的输出在没有现有数据库的情况下运行: -

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

请注意!文件错误被捕获并被绕过/处理(即仅仅因为数据库不存在)

测试2的输出 - 数据库存在: -

context.getDatabasePath(DATABASE_NAME).getParent();

DatabaseHelper用于上面的

由于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