如何为android创建SQL数据库?
嘿,我想知道如何为android创建一个数据库,而不是一个由用户编辑的数据库,一个完整的数据库,在应用程序apk中。 我是否使用excel或access,然后将数据库添加到应用程序文件夹中,或者我应该怎么做?我在互联网上所能找到的就是如何制作一个数据库,它的数据是使用应用程序本身添加的。如何为android创建SQL数据库?,android,sqlite,Android,Sqlite,嘿,我想知道如何为android创建一个数据库,而不是一个由用户编辑的数据库,一个完整的数据库,在应用程序apk中。 我是否使用excel或access,然后将数据库添加到应用程序文件夹中,或者我应该怎么做?我在互联网上所能找到的就是如何制作一个数据库,它的数据是使用应用程序本身添加的。 那么我如何建立一个数据库呢 如果我没记错的话,您只需将带有数据库的sqlite文件添加到应用程序资源中,并将其与DBHelper类一起使用,就像但适合您的应用程序需要一样 我个人使用创建和编辑sqlite文件。
那么我如何建立一个数据库呢 如果我没记错的话,您只需将带有数据库的sqlite文件添加到应用程序资源中,并将其与DBHelper类一起使用,就像但适合您的应用程序需要一样
我个人使用创建和编辑sqlite文件。您可以将现有的sqlite数据库放置到应用程序的资产文件夹中。 如果您想在运行时访问应用程序中的此数据库,可以使用此代码打开数据库
SQLiteDatabase db = SQLiteDatabase.openDatabase("path-to-database", null, SQLiteDatabase.OPEN_READONLY);
目前我不知道您是否可以直接从资产中打开db文件。否则,您可能会将其复制到应用程序的内部数据库目录:
private void copyDatabase(final Context context) {
InputStream reader = null;
try {
reader = context.getAssets().open("asset-name");
final File out = context.getDatabasePath("databasename");
final OutputStream writer = new FileOutputStream(out);
final byte[] buffer = new byte[1024 * 100];
int bytesRead = reader.read(buffer);
while (bytesRead > 0) {
writer.write(buffer, 0, bytesRead);
bytesRead = reader.read(buffer);
}
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
}
@丹尼回答说:
创建和更新数据库有两个选项
一种是在外部创建数据库,然后将其放在项目的资产文件夹中,然后从那里复制整个数据库。如果数据库中有很多表和其他组件,那么这会更快。通过更改res/values/strings.xml文件中的数据库版本号可触发升级。然后,通过在外部创建新数据库、用新数据库替换资产文件夹中的旧数据库、以另一个名称将旧数据库保存在内部存储器中、将新数据库从资产文件夹复制到内部存储器、从旧数据库传输所有数据来完成升级(之前已重命名)导入新数据库,最后删除旧数据库。您可以使用SQLite Manager FireFox插件执行创建sql语句来创建原始数据库
另一个选项是从sql文件内部创建数据库。这并不是很快,但如果数据库只有几个表,用户可能不会注意到延迟。通过更改res/values/strings.xml文件中的数据库版本号可以触发升级。然后,通过处理升级来完成升级sql文件。数据库中的数据将保持不变,除非删除其容器,例如删除表
下面的示例演示了如何使用这两种方法
下面是一个示例create_database.sql文件。它将放置在项目的资产文件夹中,用于内部方法,或复制到SQLite管理器的“Execute sql”中,以创建外部方法的数据库。(注意:请注意有关Android所需表的注释。)
下面是一个示例update_database.sql文件。它将放置在项目的资产文件夹中,用于内部方法,或复制到SQLite管理器的“Execute sql”中,以创建外部方法的数据库。(注意:请注意,本例中包含的sql解析器将忽略所有三种类型的sql注释。)
以下是要添加到/res/values/strings.xml文件中的数据库版本号条目
<item type="string" name="databaseVersion" format="integer">1</item>
以下是数据库帮助器类,如果需要,可以在其中创建或更新数据库。(注意:Android要求您创建一个扩展SQLiteOpenHelper的类,以便使用Sqlite数据库。)
package.example;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入android.content.Context;
导入android.database.sqlite.SQLiteDatabase;
导入android.database.sqlite.SQLiteOpenHelper;
/**
*@作者Danny Remington-MacroSolve
*
*sqlite数据库的帮助器类。
*/
公共类DatabaseHelper扩展了SQLiteOpenHelper{
/*
*内部应用程序数据库的Android默认系统路径
*应用程序包是存储路径的一部分
*目录。
*/
私有静态字符串DB_DIR=“/data/data/android.example/databases/”;
私有静态字符串DB_NAME=“database.sqlite”;
私有静态字符串DB_PATH=DB_DIR+DB_NAME;
私有静态字符串OLD_DB_PATH=DB_DIR+“OLD_”+DB_NAME;
私有最终上下文myContext;
私有布尔createDatabase=false;
私有布尔upgradeDatabase=false;
/**
*构造函数获取并保留所传递上下文的引用,以便
*访问应用程序资产和资源。
*
*@param上下文
*/
公共数据库助手(上下文){
super(context,DB_NAME,null,context.getResources().getInteger(
R.string.databaseVersion);
myContext=上下文;
//获取基于上下文的数据库路径。
DB_PATH=myContext.getDatabasePath(DB_NAME.getAbsolutePath();
}
/**
*升级内部存储中的数据库(如果存在但不是当前数据库)。
*如果内部存储中不存在空数据库,请在其中创建新的空数据库。
*/
public void initializeDataBase(){
/*
*如果需要,在内部存储器中创建或更新数据库
*在打开数据库之前。在所有情况下,打开数据库副本
*将内部存储器中的数据库存储到缓存中。
*/
getWritableDatabase();
如果(创建数据库){
/*
*如果数据库是通过copy方法创建的,则
*代码需要转到此处。此方法包括复制新的
*将数据库从资产存储到内部存储,然后对其进行缓存。
*/
试一试{
/*
*重写在内部数据库中创建的空数据
*存储在资产中,然后缓存它。
*/
copyDataBase();
--CREATE TABLE "kitchen_table"; This is one type of comment in sql. It is ignored by parseSql.
/*
* CREATE TABLE "coffee_table"; This is a second type of comment in sql. It is ignored by parseSql.
*/
{
CREATE TABLE "pool_table"; This is a third type of comment in sql. It is ignored by parseSql.
}
/* CREATE TABLE "dining_room_table"; This is a second type of comment in sql. It is ignored by parseSql. */
{ CREATE TABLE "card_table"; This is a third type of comment in sql. It is ignored by parseSql. }
--DROP TABLE "picnic_table"; Uncomment this if picnic table was previously created and now is being replaced.
CREATE TABLE "picnic_table" ("plates" TEXT);
INSERT INTO "picnic_table" VALUES ('paper');
<item type="string" name="databaseVersion" format="integer">1</item>
package android.example;
import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
/**
* @author Danny Remington - MacroSolve
*
* Activity for demonstrating how to use a sqlite database.
*/
public class Database extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DatabaseHelper myDbHelper;
SQLiteDatabase myDb = null;
myDbHelper = new DatabaseHelper(this);
/*
* Database must be initialized before it can be used. This will ensure
* that the database exists and is the current version.
*/
myDbHelper.initializeDataBase();
try {
// A reference to the database can be obtained after initialization.
myDb = myDbHelper.getWritableDatabase();
/*
* Place code to use database here.
*/
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
myDbHelper.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
myDb.close();
}
}
}
}
package android.example;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* @author Danny Remington - MacroSolve
*
* Helper class for sqlite database.
*/
public class DatabaseHelper extends SQLiteOpenHelper {
/*
* The Android's default system path of the application database in internal
* storage. The package of the application is part of the path of the
* directory.
*/
private static String DB_DIR = "/data/data/android.example/databases/";
private static String DB_NAME = "database.sqlite";
private static String DB_PATH = DB_DIR + DB_NAME;
private static String OLD_DB_PATH = DB_DIR + "old_" + DB_NAME;
private final Context myContext;
private boolean createDatabase = false;
private boolean upgradeDatabase = false;
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* @param context
*/
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, context.getResources().getInteger(
R.string.databaseVersion));
myContext = context;
// Get the path of the database that is based on the context.
DB_PATH = myContext.getDatabasePath(DB_NAME).getAbsolutePath();
}
/**
* Upgrade the database in internal storage if it exists but is not current.
* Create a new empty database in internal storage if it does not exist.
*/
public void initializeDataBase() {
/*
* Creates or updates the database in internal storage if it is needed
* before opening the database. In all cases opening the database copies
* the database in internal storage to the cache.
*/
getWritableDatabase();
if (createDatabase) {
/*
* If the database is created by the copy method, then the creation
* code needs to go here. This method consists of copying the new
* database from assets into internal storage and then caching it.
*/
try {
/*
* Write over the empty data that was created in internal
* storage with the one in assets and then cache it.
*/
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
} else if (upgradeDatabase) {
/*
* If the database is upgraded by the copy and reload method, then
* the upgrade code needs to go here. This method consists of
* renaming the old database in internal storage, create an empty
* new database in internal storage, copying the database from
* assets to the new database in internal storage, caching the new
* database from internal storage, loading the data from the old
* database into the new database in the cache and then deleting the
* old database from internal storage.
*/
try {
FileHelper.copyFile(DB_PATH, OLD_DB_PATH);
copyDataBase();
SQLiteDatabase old_db = SQLiteDatabase.openDatabase(OLD_DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
SQLiteDatabase new_db = SQLiteDatabase.openDatabase(DB_PATH,null, SQLiteDatabase.OPEN_READWRITE);
/*
* Add code to load data into the new database from the old
* database and then delete the old database from internal
* storage after all data has been transferred.
*/
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
/*
* Close SQLiteOpenHelper so it will commit the created empty database
* to internal storage.
*/
close();
/*
* Open the database in the assets folder as the input stream.
*/
InputStream
myInput = myContext.getAssets().open(DB_NAME);
/*
* Open the empty db in interal storage as the output stream.
*/
OutputStream myOutput = new FileOutputStream(DB_PATH);
/*
* Copy over the empty db in internal storage with the database in the
* assets folder.
*/
FileHelper.copyFile(myInput, myOutput);
/*
* Access the copied database so SQLiteHelper will cache it and mark it
* as created.
*/
getWritableDatabase().close();
}
/*
* This is where the creation of tables and the initial population of the
* tables should happen, if a database is being created from scratch instead
* of being copied from the application package assets. Copying a database
* from the application package assets to internal storage inside this
* method will result in a corrupted database.
* <P>
* NOTE: This method is normally only called when a database has not already
* been created. When the database has been copied, then this method is
* called the first time a reference to the database is retrieved after the
* database is copied since the database last cached by SQLiteOpenHelper is
* different than the database in internal storage.
*/
@Override
public void onCreate(SQLiteDatabase db) {
/*
* Signal that a new database needs to be copied. The copy process must
* be performed after the database in the cache has been closed causing
* it to be committed to internal storage. Otherwise the database in
* internal storage will not have the same creation timestamp as the one
* in the cache causing the database in internal storage to be marked as
* corrupted.
*/
createDatabase = true;
/*
* This will create by reading a sql file and executing the commands in
* it.
*/
// try {
// InputStream is = myContext.getResources().getAssets().open(
// "create_database.sql");
//
// String[] statements = FileHelper.parseSqlFile(is);
//
// for (String statement : statements) {
// db.execSQL(statement);
// }
// } catch (Exception ex) {
// ex.printStackTrace();
// }
}
/**
* Called only if version number was changed and the database has already
* been created. Copying a database from the application package assets to
* the internal data system inside this method will result in a corrupted
* database in the internal data system.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/*
* Signal that the database needs to be upgraded for the copy method of
* creation. The copy process must be performed after the database has
* been opened or the database will be corrupted.
*/
upgradeDatabase = true;
/*
* Code to update the database via execution of sql statements goes
* here.
*/
/*
* This will upgrade by reading a sql file and executing the commands in
* it.
*/
// try {
// InputStream is = myContext.getResources().getAssets().open(
// "upgrade_database.sql");
//
// String[] statements = FileHelper.parseSqlFile(is);
//
// for (String statement : statements) {
// db.execSQL(statement);
// }
// } catch (Exception ex) {
// ex.printStackTrace();
// }
}
/**
* Called everytime the database is opened by getReadableDatabase or
* getWritableDatabase. This is called after onCreate or onUpgrade is
* called.
*/
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
}
/*
* Add your public helper methods to access and get content from the
* database. You could return cursors by doing
* "return myDataBase.query(....)" so it'd be easy to you to create adapters
* for your views.
*/
}