如何使用我自己的sqlite数据库?

我把我的数据库字段放在“assets”文件夹中。 并使用从这个博客的代码复制数据库到“/ data / data / my_packname / databases /”,(这个副本代码我运行它在onCreate()方法,当我运行这个应用程序),然后使用select * from ..获取数据。 但它给了我例外:没有这样的表。

有人告诉我,如果我试图在SQLiteOpenHelper的onCreate()中复制文件,那就太迟了。 所以复制文件代码不能复制完整的文件。

所以我需要使用adb或ddms来拉数据库?

那么,任何人都可以教我如何使用我自己的数据库? 你能告诉我的设置?

Solutions Collecting From Web of "如何使用我自己的sqlite数据库?"

我已经使用了该博客文章中的说明,并在正确的轨道上发现,通过不必要的扩展SQLiteOpenHelper使问题严重复杂化。 我有更好的运气做以下几点:

  1. 创build一个实用程序类,通过将其复制到资源中正确的目录来创build静态数据库,但不会自动挂上SQLiteOpenHelper格式。

  2. 使用相同的实用程序类来打开数据库通过使用SQLiteDatabase.openDatabase()

编辑:这是我创build的这个工具类的一个版本; 它不完全,但你会得到漂移。

 public class DbUtils { private static final String DB_PATH = "/data/data/com.mypackage.myapp/databases/"; private static final String DB_NAME = "my.db"; public static void createDatabaseIfNotExists(Context context) throws IOException { boolean createDb = false; File dbDir = new File(DB_PATH); File dbFile = new File(DB_PATH + DB_NAME); if (!dbDir.exists()) { dbDir.mkdir(); createDb = true; } else if (!dbFile.exists()) { createDb = true; } else { // Check that we have the latest version of the db boolean doUpgrade = false; // Insert your own logic here on whether to upgrade the db; I personally // just store the db version # in a text file, but you can do whatever // you want. I've tried MD5 hashing the db before, but that takes a while. // If we are doing an upgrade, basically we just delete the db then // flip the switch to create a new one if (doUpgrade) { dbFile.delete(); createDb = true; } } if (createDb) { // Open your local db as the input stream InputStream myInput = context.getAssets().open(DB_NAME); // Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(dbFile); // transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // Close the streams myOutput.flush(); myOutput.close(); myInput.close(); } } public static SQLiteDatabase getStaticDb() { return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); } } 

在复制数据库之后,您应该在执行任何查询之前尝试closures并重新打开SQLiteDatabase对象。 我有一个从inputstream复制数据库类似的问题,这就是为我解决这个问题。

这里是我的版本从“西尔维奥·唐尼尼”代码:),现在你可以很容易地更新数据库。

 private static final String DB_PATH = "/data/data/pakagename/databases/"; private static final String DB_NAME = "databaseName"; private static SQLiteDatabase db; public static void createDatabaseIfNotExists(Context context,int version) throws IOException { boolean createDb = false; File dbDir = new File(DB_PATH); File dbFile = new File(DB_PATH + DB_NAME); if (!dbDir.exists()) { dbDir.mkdir(); createDb = true; } else if (!dbFile.exists()) { createDb = true; } else { // Check that we have the latest version of the db db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); if (db.getVersion() != version) { dbFile.delete(); createDb = true; } } if (createDb) { // Open your local db as the input stream InputStream myInput = context.getResources().openRawResource(R.raw.database); // Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(dbFile); // transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // Close the streams myOutput.flush(); myOutput.close(); myInput.close(); SQLiteDatabase dbwrite = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE); dbwrite.setVersion(version); dbwrite.close(); if (db != null) db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); } } public static SQLiteDatabase getStaticDb() { if (db != null) return db; return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); } 

我知道这是一个老问题,但在所有答复的帮助下,我花了很多时间弄清楚了。


问题是设备将数据库存储在他的data / data /…/ databases文件夹中。 所以,当你改变有关数据库(名称,添加Android元数据表,大小..)它不会有任何区别,因为存储的数据库和检查现有的数据库的方法。


要获取最新的数据库,在更改它之后,您必须运行程序而不检查现有的数据库(例如,而不是dbExist = checkDataBase();使其成为false)。

 dbExist = checkDataBase(); 

改成:

 dbExists = false; 

拿起“新”数据库后,你可以返回检查现有的数据库。

希望它能帮助别人,迪娜

我知道这是一个旧的post,但对于那些仍然在Google或Bingsearch之后到达这里的人来说,这是解决所述问题的方法:

在createDataBase()中有以下检查;

 this.getReadableDatabase(); 

这将检查是否已经有一个提供名称的数据库,如果没有创build一个空的数据库,可以用assets文件夹中的一个来覆盖它。 在较新的设备上,这完美的工作,但有一些设备上,这是行不通的。 主要是旧设备。 我不知道为什么,但似乎getReadableDatabase()函数不仅获取数据库,但也打开它。 如果您然后从资产文件夹复制数据库,它仍然有一个空数据库的指针,你会得到表不存在的错误。

所以为了使它在所有的设备上工作,你应该修改它到以下几行:

 SQLiteDatabase db = this.getReadableDatabase(); if (db.isOpen()){ db.close(); } 

即使数据库在支票中打开,之后也会closures,这不会给您带来麻烦。

冷静下来,经过长时间的研究终于find了“没有这样的表”的错误

检查资产文件夹中的数据库的名称,如果它像“DATABASE_NAME.EXTENSION”,然后把全名的助手类与扩展它解决了我的问题。

比如说在Assets中的数据库名称是login.sqlite或者login.db什么的。 将DB_NAME = login.sqlite完全扩展。 本教程现在完美地工作。

从你发布的文章中创build数据库的方式有点不同,它是如何在android示例中完成的(我不想说它是好是坏)。

我已经学会了如何使用SDK NotePad示例中的数据库

这是一个很好的例子,因为它涵盖了通过ContentProvider创build数据库主题和数据库访问(它实际上是从数据库获取数据的唯一好方法,否则在尝试从代码的许多地方同时获取数据时会遇到问题) 。

你应该注意到,SQLiteOpenHelper真的很强大,如果你能正确使用它,它会帮助你。 例如,它存储当前的数据库版本(不是sqlite版本,但是您使用数据库模式版本进行分配),当您使用新的数据库结构创build新的应用程序版本时,可以将当前模式更新为onUpdate中的新版本。