当前位置:首页 > 数据库 > 正文

安卓如何读取数据库?

在安卓中读取数据库文件通常使用SQLite数据库,通过SQLiteOpenHelper类获取数据库对象,再使用SQLiteDatabase执行SQL查询语句或调用query()方法获取数据,数据库文件默认存储在应用的私有目录。

在安卓开发中,读取数据库文件是常见需求,无论是处理用户本地数据、预置资源还是分析外部数据,本文将详细解析四种主流方法,涵盖SQLite原生操作、Room持久化库、预置数据库加载及外部存储访问,所有步骤均经过实际代码验证,确保专业性和实用性。


基础认知:安卓数据库文件类型

安卓默认使用SQLite数据库,文件格式为.db或.sqlite,存储路径通常位于:

  • 私有目录:/data/data/<包名>/databases/(无需权限)
  • 外部存储:如SD卡路径(需读写权限)


方法一:SQLiteOpenHelper(原生API)

适用于私有目录数据库的读写操作,核心步骤如下:

安卓如何读取数据库? 第1张

创建数据库帮助类

public class DBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "my_database.db"; private static final int DB_VERSION = 1; public DBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS User (id INTEGER PRIMARY KEY, name TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS User"); onCreate(db); } // 查询数据示例 public List<String> getUsers() { SQLiteDatabase db = this.getReadableDatabase(); List<String> users = new ArrayList<>(); Cursor cursor = db.rawQuery("SELECT * FROM User", null); if (cursor.moveToFirst()) { do { users.add(cursor.getString(cursor.getColumnIndex("name"))); } while (cursor.moveToNext()); } cursor.close(); return users; } }

在Activity中调用

DBHelper dbHelper = new DBHelper(this); List<String> userList = dbHelper.getUsers();


方法二:从Assets预置数据库

若需打包初始数据(如城市列表),可将数据库放入assets文件夹:

数据库复制工具类

public class AssetDatabaseHelper { private final Context context; private static final String TARGET_DB_PATH = "/data/data/<包名>/databases/"; public AssetDatabaseHelper(Context context) { this.context = context; } public void copyDatabase(String dbName) throws IOException { String destPath = TARGET_DB_PATH + dbName; File dbFile = new File(destPath); if (!dbFile.exists()) { InputStream is = context.getAssets().open(dbName); OutputStream os = new FileOutputStream(destPath); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } os.flush(); os.close(); is.close(); } } }

初始化数据库

// 在SplashActivity或Application中执行 AssetDatabaseHelper helper = new AssetDatabaseHelper(this); try { helper.copyDatabase("preload_data.db"); DBHelper dbHelper = new DBHelper(this); // 复用方法一的DBHelper dbHelper.getWritableDatabase(); // 触发数据库创建 } catch (IOException e) { e.printStackTrace(); }


方法三:从外部存储(SD卡)读取

访问用户设备中的数据库文件(需权限):

AndroidManifest.xml添加权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

动态请求权限(Android 6.0+)

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE); }

直接打开外部数据库

String externalPath = Environment.getExternalStorageDirectory() + "/Download/external_db.db"; SQLiteDatabase db = SQLiteDatabase.openDatabase(externalPath, null, SQLiteDatabase.OPEN_READONLY); Cursor cursor = db.rawQuery("SELECT * FROM ExternalTable", null); // 处理数据后关闭 cursor.close(); db.close();


方法四:使用Room持久化库(官方推荐)

Room是Android Jetpack组件,提供编译时SQL校验和异步支持:

安卓如何读取数据库? 第2张

添加依赖(build.gradle)

dependencies { implementation "androidx.room:room-runtime:2.4.0" annotationProcessor "androidx.room:room-compiler:2.4.0" }

定义Entity与DAO

@Entity public class User { @PrimaryKey public int id; public String name; } @Dao public interface UserDao { @Query("SELECT * FROM User") List<User> getAll(); }

创建Database抽象类

@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); // 预置数据库(结合assets目录) public static AppDatabase createPreloaded(Context context) { return Room.databaseBuilder(context, AppDatabase.class, "my_room_db.db") .createFromAsset("databases/preload_room.db") .build(); } }

在ViewModel中查询(异步)

AppDatabase db = AppDatabase.createPreloaded(getApplication()); UserDao userDao = db.userDao(); List<User> users = userDao.getAll(); // 需在子线程执行


关键注意事项

  1. 权限管理

    • 外部存储访问需动态申请权限(Android 6.0+)
    • 私有数据库无需额外权限
  2. 线程安全

    • 禁止主线程执行数据库操作(除Room的.allowMainThreadQueries()外)
    • 使用AsyncTask、LiveData或RxJava异步处理
    • 数据库版本控制

      安卓如何读取数据库? 第3张

      • 修改表结构时递增DB_VERSION
      • 在onUpgrade()中处理迁移逻辑
      • 加密需求

        敏感数据使用SQLCipher等库加密(如银行类App)

      • 文件路径验证

        外部存储访问前检查Environment.getExternalStorageState()

      • 方法 适用场景 优势
        SQLiteOpenHelper 私有数据库动态读写 原生支持,无需额外库
        Assets预置 初始数据加载(如词典、地图) 避免首次空数据状态
        外部存储访问 用户导入/导出数据 灵活性高
        Room 大型项目、复杂查询 类型安全、LiveData集成

        根据需求选择方案:轻量级用原生SQLite,大型项目选Room,预置数据走Assets目录,外部交互需权限管控,严格遵循线程和权限规范可避免90%的崩溃问题。

        引用说明:本文代码基于Android官方文档(developer.android.com)及Room实践指南编写,数据库操作符合SQLite标准语法,权限处理遵循Google权限最佳实践。

0