问题从Android Studio中的Assets文件夹读取sqlite版本3

时间:2018-10-24 17:02:08

标签: android sqlite android-studio

我像这样通过C#.net构建sqlite

SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
if (!File.Exists("MyDatabase.sqlite"))
{
    SQLiteConnection.CreateFile("MyDatabase.sqlite");
    m_dbConnection.Open();
    string sql = "CREATE TABLE IF NOT EXISTS farmakology(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,tabaghe TEXT,name TEXT,enname TEXT,img TEXT,farmaco TEXT,amal TEXT,balin TEXT,masraf TEXT,tadakhol TEXT,amozesh TEXT,avarez TEXT);";
    SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
    command.ExecuteNonQuery();

}

然后我将一些数据存储到此sqlite并将其复制到我的android项目的资产文件夹中,然后使用此代码读取它:

public class MyDatabase extends SQLiteAssetHelper {

    private static final String DATABASE_NAME = "MyDatabase.sqlite";
    private static final int DATABASE_VERSION = 3;
    private static final String ENNAME="enname";
    private static final String POSES_TABLE="farmakology";

    public MyDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public ArrayList<Poses> getPoses(){
        SQLiteDatabase db=getWritableDatabase();
        String[] columns={MyDatabase.ENNAME};
        Cursor cursor=db.rawQuery("SELECT * FROM farmakology" , null);
        ArrayList<Poses> questionsArrayList=new ArrayList<>();

        while(cursor.moveToNext()){
            Poses questions=new Poses();
            questions.enname=cursor.getString(cursor.getColumnIndex(MyDatabase.ENNAME));
            questionsArrayList.add(questions);
        }
        return questionsArrayList;
    }
}

但是,logcat显示此错误(没有这样的表)

    java.lang.RuntimeException: Unable to start activity ComponentInfo{ir.toolha.pharmacology/ir.toolha.pharmacology.asli}: android.database.sqlite.SQLiteException: no such table: farmakology (code 1): , while compiling: SELECT * FROM farmakology

哪里出问题了? 该如何解决?

已编辑

我也使用SQLiteOpenHelper,但仍然没有帮助,对我不起作用

public class SqlLiteDataBaseHelper extends SQLiteOpenHelper {
    private static final String TAG = SqlLiteDataBaseHelper.class.getSimpleName();
    private static final int DATABASE_VERSION = 3;
    private static final String DATABASE_PATH = "/data/data/ir.toolha.pharmacology/databases/";
    private static final String DATABASE_NAME = "MyDatabase.sqlite";
    private static final String TABLE_NAME = "farmakology";
    private static final String COL_Name = "enname";
    private Context context;
    private SQLiteDatabase db;

    public SqlLiteDataBaseHelper(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
        this.context = context;
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }


    //This method is just retuning total no of recode in your table Getting single contact count
    public int  getDataCount() {
        String userRollNo = null;
        String query = "SELECT * FROM " + TABLE_NAME ;
        Cursor cursor = db.rawQuery(query, null);
        return cursor.getCount();
    }


    public void openDataBase () throws SQLException {
        String path = DATABASE_PATH+DATABASE_NAME;
        db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.CREATE_IF_NECESSARY);
    }

    public void CopyDataBaseFromAsset() throws IOException {
        InputStream in  = context.getAssets().open(DATABASE_NAME);
        Log.e("sample", "Starting copying");
        String outputFileName = DATABASE_PATH+DATABASE_NAME;
        File databaseFile = new File( "/data/data/ir.toolha.pharmacology/databases");
        // check if databases folder exists, if not create one and its subfolders
        if (!databaseFile.exists()){
            databaseFile.mkdir();
        }

        OutputStream out = new FileOutputStream(outputFileName);

        byte[] buffer = new byte[1024];
        int length;

        while ((length = in.read(buffer))>0){
            out.write(buffer,0,length);
        }
        Log.e("sample", "Completed" );
        out.flush();
        out.close();
        in.close();

    }

    public void deleteDb() {
        File file = new File(DATABASE_PATH);
        if(file.exists()) {
            file.delete();
            Log.d(TAG, "Database deleted.");
        }
    }
    public boolean checkDataBase() {
        boolean checkDB = false;
        try {
            File file = new File(DATABASE_PATH);
            checkDB = file.exists();
        } catch(SQLiteException e) {
            Log.d(TAG, e.getMessage());
        }
        return checkDB;
    }
}

2 个答案:

答案 0 :(得分:1)

您的Java代码中有一些错误。

您已将数据库存储在资产文件夹中。因此,在使用它之前,必须将其复制到正确的数据库文件夹中。可以通过CopyDataBaseFromAsset()完成。但是,您的代码不会调用该方法。

因此,我建议如下更新您的代码:

SqlLiteDataBaseHelper.java

此类仅用于打开数据库。您不在此处执行查询。它仅应管理数据库的创建。 我只是删除了一些方法并更新了构造函数。

public class SqlLiteDataBaseHelper extends SQLiteOpenHelper {

    private static final String TAG = SqlLiteDataBaseHelper.class.getSimpleName();
    private static final int DATABASE_VERSION = 3;
    private static final String DATABASE_PATH = "/data/data/ir.toolha.pharmacology/databases/";
    private static final String DATABASE_NAME = "MyDatabase.sqlite";
    private static final String TABLE_NAME = "farmakology";
    private static final String COL_Name = "enname";

    public SqlLiteDataBaseHelper(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
        if (!checkDataBase()) {
            try {
                CopyDataBaseFromAsset();
            } catch (IOException e) {
                throw new RuntimeException("Error creating source database", e);
            }
        }
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        // Do nothing here
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        // Do nothing here
    }

    public void CopyDataBaseFromAsset() throws IOException {
        InputStream in  = context.getAssets().open(DATABASE_NAME);
        Log.e("sample", "Starting copying");
        String outputFileName = DATABASE_PATH+DATABASE_NAME;
        File databaseFile = new File( "/data/data/ir.toolha.pharmacology/databases");
        // check if databases folder exists, if not create one and its subfolders
        if (!databaseFile.exists()){
            databaseFile.mkdir();
        }

        OutputStream out = new FileOutputStream(outputFileName);

        byte[] buffer = new byte[1024];
        int length;

        while ((length = in.read(buffer))>0){
            out.write(buffer,0,length);
        }
        Log.e("sample", "Completed" );
        out.flush();
        out.close();
        in.close();
    }

    public boolean checkDataBase() {
        boolean checkDB = false;
        try {
            File file = new File(DATABASE_PATH);
            checkDB = file.exists();
        } catch(SQLiteException e) {
            Log.d(TAG, e.getMessage());
        }
        return checkDB;
    }
}

MyDatabase.java

然后,您创建一个新类,该类将负责从数据库中读取值并转换为正确的格式(在您的情况下,转换为数组列表)

public class MyDatabase {

    private SqlLiteDataBaseHelper mSqlHelper;

    public MyDatabase(Context context) {
         mSqlHelper = new SqlLiteDataBaseHelper(context);
    }

    public ArrayList<Poses> getPoses(){
        SQLiteDatabase db = mSqlHelper.getWritableDatabase();

        String[] columns={MyDatabase.ENNAME};
        Cursor cursor=db.rawQuery("SELECT * FROM farmakology" , null);

        ArrayList<Poses> questionsArrayList=new ArrayList<>();

        // You need to move to first item before doing anything
        if(cursor != null) {
            if(cursor.moveToFirst()) {
                while(cursor.moveToNext()){
                    Poses questions=new Poses();
                    questions.enname=cursor.getString(cursor.getColumnIndex(MyDatabase.ENNAME));
                    questionsArrayList.add(questions);
                }
            }
            cursor.close(); // Don't forget to close the cursor.
        }

        db.close(); // Don't forget to close the database once your job is done

        return questionsArrayList;
    }
}

最重要:

  1. 您必须将数据库从资产文件夹复制到适当的数据库文件夹(/data/data/ir.toolha.pharmacology/databases/

  2. SQLiteOpenHelper可帮助您打开和关闭数据库。

  3. 打开数据库,读取值,关闭数据库并返回结果是必需的第三类。

  4. 您可以将所有内容封装在一个类中。但是,我认为最好将这些代码分成两个类。

  5. 我没有测试我建议的代码。.所以,请谨慎使用。.我的目的只是表明您应该在代码中进行改进的地方。

希望它对您有帮助

答案 1 :(得分:0)

为什么不使用SQLiteOpenHelper而不是SQLiteAssetHelper并在onCreate中创建数据库:

public class MyDatabase extends SQLiteAssetHelper {

    private static final String DATABASE_NAME = "MyDatabase.sqlite";
    private static final int DATABASE_VERSION = 3;
    private static final String ENNAME="enname";
    private static final String POSES_TABLE="farmakology";
    string sql = "CREATE TABLE IF NOT EXISTS farmakology(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,tabaghe TEXT,name TEXT,enname TEXT,img TEXT,farmaco TEXT,amal TEXT,balin TEXT,masraf TEXT,tadakhol TEXT,amozesh TEXT,avarez TEXT);";

public MyDatabase(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(sql);
  }
}