安卓数据库操作指南:让你轻松实现数据存储与访问 (android访问数据库)
在开发安卓应用程序时,数据的存储和访问是非常重要的一个环节。数据库的使用是实现数据存储和访问的一种非常常见的方式。本篇文章将介绍如何通过使用安卓的数据库操作来实现数据的存储和访问。
I. 数据库的概念和基本操作
1.1 数据库的概念
数据库是指按照一定规则在一定范围内组织起来的、具有共享性、永久性,可在一定目的下被反复利用的数据。
1.2 安卓数据库的基本操作
安卓提供了SQLite作为它的开源的关系型数据库管理系统(RDBMS)。我们通过SQLiteOpenHelper 来对SQLite数据库进行操作。SQLiteOpenHelper 是一个抽象类,我们需要继承它,并在子类中实现几个方法。
1.2.1 SQLiteOpenHelper的使用
SQLiteOpenHelper 是用于管理数据库版本和创建和更新数据库的类,我们需要继承该类,并实现 onCreate()、onUpgrade() 等抽象方法。
下面是一个示例代码:
“`
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = “mydata.db”; // 数据库名字
public static final int DATABASE_VERSION = 1; // 数据库版本号
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 创建数据库表
String sql = “CREATE TABLE IF NOT EXISTS person (“
+ “_id INTEGER PRIMARY KEY AUTOINCREMENT,”
+ “name TEXT,”
+ “age INTEGER,”
+ “address TEXT”
+ “);”;
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 升级数据库表
db.execSQL(“DROP TABLE IF EXISTS person”);
onCreate(db);
}
}
“`
1.2.2 SQLite数据库的操作
1.2.2.1 插入数据
下面是一个示例代码:
“`
ContentValues contentValues = new ContentValues();
contentValues.put(“name”, “张三”);
contentValues.put(“age”, 28);
contentValues.put(“address”, “北京市朝阳区”);
SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();
sqLiteDatabase.beginTransaction();
try {
sqLiteDatabase.insert(“person”, null, contentValues);
sqLiteDatabase.setTransactionSuccessful();
} finally {
sqLiteDatabase.endTransaction();
sqLiteDatabase.close();
}
“`
1.2.2.2 查询数据
下面是一个示例代码:
“`
SQLiteDatabase sqLiteDatabase = databaseHelper.getReadableDatabase();
Cursor cursor = null;
try {
cursor = sqLiteDatabase.query(“person”, new String[]{“_id”, “name”, “age”, “address”}, null, null, null, null, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex(“_id”));
String name = cursor.getString(cursor.getColumnIndex(“name”));
int age = cursor.getInt(cursor.getColumnIndex(“age”));
String address = cursor.getString(cursor.getColumnIndex(“address”));
}
} finally {
if (cursor != null) {
cursor.close();
}
sqLiteDatabase.close();
}
“`
1.2.2.3 更新数据
下面是一个示例代码:
“`
ContentValues contentValues = new ContentValues();
contentValues.put(“name”, “李四”);
contentValues.put(“age”, 30);
contentValues.put(“address”, “上海市浦东新区”);
SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();
sqLiteDatabase.beginTransaction();
try {
sqLiteDatabase.update(“person”, contentValues, “_id = ?”, new String[]{“1”});
sqLiteDatabase.setTransactionSuccessful();
} finally {
sqLiteDatabase.endTransaction();
sqLiteDatabase.close();
}
“`
1.2.2.4 删除数据
下面是一个示例代码:
“`
SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();
sqLiteDatabase.beginTransaction();
try {
sqLiteDatabase.delete(“person”, “_id = ?”, new String[]{“1”});
sqLiteDatabase.setTransactionSuccessful();
} finally {
sqLiteDatabase.endTransaction();
sqLiteDatabase.close();
}
“`
II. 数据库加密
在实际应用中,由于安全性的限制,我们经常需要对数据库进行加密保护。SQLite提供了 SQLCipher 这个开源的加密库,可以实现对SQLite数据库的AES-256加密。
2.1 SQLCipher的使用
我们需要先添加 SQLCipher 依赖库到应用的 build.gradle 中:
“`
implementation ‘net.zetetic:android-database-sqlcipher:4.4.2@aar’
“`
对于最新版SQLCipher的引入方式,可以参照官网文档 https://www.zetetic.net/sqlcipher/sqlcipher-for-android/ 。
然后我们需要在继承SQLiteOpenHelper的类中使用 SQLCipher,代码如下:
“`
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = “mydata.db”; // 数据库名字
public static final int DATABASE_VERSION = 1; // 数据库版本号
public static final String DATABASE_PASSWORD = “mysecretkey”; // 数据库加密密码
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION, new com.tencent.wstt.gt.datatool.util.Database.EncryptListener() {
@Override
public void onCorrupted() {
// 数据库文件损坏回调
Log.e(TAG, “onCorrupted: “);
}
});
SQLiteDatabase.loadLibs(context); // 加载SQLCipher库
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(“PRAGMA key=’mysecretkey’;”); // 设置加密密码
sqLiteDatabase.execSQL(“CREATE TABLE IF NOT EXISTS person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, address TEXT);”);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
// 升级数据库表
sqLiteDatabase.execSQL(“DROP TABLE IF EXISTS person”);
onCreate(sqLiteDatabase);
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
db.execSQL(“PRAGMA key=’mysecretkey’;”); // 打开数据库时设置加密密码
}
}
“`
2.2 SQLCipher的特点及优势
SQLCipher 是一个高性能、完整、易于使用的加密库,它为 SQLite 数据库提供了 AES 加密的函数。SQLCipher 的主要特点如下:
– 可以将现有的 SQLite 数据库文件用 SQLCipher 在不需修改任何代码的情况下轻松地升级为加密数据库。
– SQLCipher 的加密算法属于 NIST 评估过的 AES 加密。可以用 256 位的 AES 密码进行加密数据库的文件,以确保数据在安全性上得到保障。
– SQLCipher 的架构是企业级的,在全球范围内得到广泛的应用。
– SQLCipher 的文档清晰明了,提供了丰富的使用例子,支持多个操作系统平台。
III. 数据库调试工具
在开发应用的过程中,我们难免会遇到数据库操作出现异常的情况,这时我们可以使用 Android Studio 自带的数据库查看器来查看数据库的情况。
3.1 数据库查看器的使用
在 Android Studio 的 Device File Explorer 中,找到 /data/data/com.*(应用包名)/databases/ 目录,然后将SQLite数据库导出到计算机,即可使用 SQLite 数据库查看器来查看数据库的内容。
3.2 数据库查看器的效果图
数据库查看器提供了如下图的界面:
![数据库查看器界面](https://img-blog.csdnimg.cn/20230713150848207.png)
在数据库查看器界面上,我们可以对数据库进行操作,如浏览表数据、执行 SQL 语句、导出数据等。
IV. 数据库操作频繁报错问题
在开发中,我们经常会遇到 SQLITE_BUSY 异常问题,主要原因是因为数据库操作频繁导致。
我们可以通过如下方式解决这个问题:
4.1 数据库事务的使用
在“插入数据、更新数据、删除数据”的操作中,如果每一条语句都是单独执行的,那么数据库就需要在执行每一条SQL语句的时候都会加锁,这样就会导致数据库频繁加锁,出现 SQLITE_BUSY 异常。我们可以使用事务来解决这个问题。
事务的使用如下所示:
“`
SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();
sqLiteDatabase.beginTransaction();
try {
sqLiteDatabase.insert(“person”, null, contentValues);
sqLiteDatabase.setTransactionSuccessful();
} finally {
sqLiteDatabase.endTransaction();
sqLiteDatabase.close();
}
“`
4.2 使用线程池并行执行数据库操作
我们可以使用线程池来并行执行数据库操作,从而减少数据库操作的时间,降低出现 SQLITE_BUSY 异常的概率。
下面是一个示例代码:
“`
Executor executor = Executors.newFixedThreadPool(3);
executor.execute(new Runnable() {
@Override
public void run() {
// SQL操作(增删改查)
}
});
“`
V. 本文
本篇文章主要介绍了如何使用安卓的数据库操作来实现数据存储与访问。同时我们还介绍了如何使用 SQLCipher 来保护和加密数据库,以及如何使用数据库查看器和解决数据库操作频繁报错问题。对于安卓开发者来说,掌握本文所述的知识,将能够帮助其轻松地实现数据存储与访问操作。