安卓APP如何操作SQLite数据库?

在安卓中读取SQLite数据库的核心步骤:创建SQLiteOpenHelper子类管理数据库,通过getReadableDatabase()或getWritableDatabase()获取可读数据库对象,使用query()或rawQuery()执行查询,遍历返回的Cursor对象获取数据,最后关闭Cursor。

基础准备:理解安卓数据库架构

安卓默认使用轻量级SQLite数据库,数据存储在/data/data/<包名>/databases/目录,读取前需完成:

安卓APP如何操作SQLite数据库?

  1. 创建数据库
    继承SQLiteOpenHelper类定义数据库结构:

    public class DBHelper extends SQLiteOpenHelper {
        private static final String DATABASE_NAME = "UserDB";
        private static final int DATABASE_VERSION = 1;
        private static final String TABLE_USERS = "users";
        private static final String COLUMN_ID = "id";
        private static final String COLUMN_NAME = "name";
        public DBHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            String createTable = "CREATE TABLE " + TABLE_USERS + " (" +
                    COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    COLUMN_NAME + " TEXT)";
            db.execSQL(createTable);
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);
            onCreate(db);
        }
    }

方法1:原生SQLite读取(适合小型项目)

步骤详解

  1. 获取可读数据库对象

    DBHelper dbHelper = new DBHelper(context);
    SQLiteDatabase db = dbHelper.getReadableDatabase(); // 只读模式
  2. 执行查询语句
    使用rawQuery()query()方法:

    // 原始SQL查询
    Cursor cursor = db.rawQuery("SELECT * FROM users WHERE name=?", new String[]{"小明"});
    // 结构化查询(推荐)
    Cursor cursor = db.query(
            "users",                     // 表名
            new String[]{"id", "name"},  // 返回列
            "age > ?",                   // WHERE条件
            new String[]{"18"},          // 条件参数
            null, null, null             // GROUP BY, HAVING, ORDER BY
    );
  3. 解析Cursor数据

    if (cursor != null && cursor.moveToFirst()) {
        do {
            int id = cursor.getInt(cursor.getColumnIndexOrThrow("id"));
            String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
            Log.d("UserData", "ID: " + id + ", Name: " + name);
        } while (cursor.moveToNext());
    }
  4. 关闭资源(防止内存泄漏)

    if (cursor != null) cursor.close();
    db.close();

✅ 优点:无额外依赖,控制灵活
⚠️ 风险

  • 直接SQL操作易出错(如SQL注入)
  • 手动管理Cursor易导致内存泄漏

方法2:Room Persistence Library(官方推荐方案)

Google推出的ORM库,自动生成模板代码,提供编译时校验。

实现步骤

  1. 添加依赖build.gradle

    dependencies {
        def room_version = "2.5.0"
        implementation "androidx.room:room-runtime:$room_version"
        annotationProcessor "androidx.room:room-compiler:$room_version"
    }
  2. 定义数据实体

    安卓APP如何操作SQLite数据库?

    @Entity(tableName = "users")
    public class User {
        @PrimaryKey(autoGenerate = true)
        public int id;
        @ColumnInfo(name = "user_name")
        public String name;
    }
  3. 创建DAO接口

    @Dao
    public interface UserDao {
        @Query("SELECT * FROM users WHERE name = :userName")
        List<User> getUsersByName(String userName);
    }
  4. 构建数据库对象

    @Database(entities = {User.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
        public abstract UserDao userDao();
    }
    // 初始化实例(单例模式)
    AppDatabase db = Room.databaseBuilder(
            context.getApplicationContext(),
            AppDatabase.class, "user_database"
    ).build();
  5. 异步读取数据(避免主线程阻塞)

    Executor executor = Executors.newSingleThreadExecutor();
    executor.execute(() -> {
        List<User> users = db.userDao().getUsersByName("小明");
        // 更新UI需切回主线程:runOnUiThread()或LiveData
    });

✅ 核心优势

  • 编译时SQL语法检查
  • 自动线程管理
  • 支持LiveData实时更新UI

方法3:ContentProvider跨进程读取

适用于应用间共享数据(如通讯录读取)。

关键步骤

  1. 声明权限AndroidManifest.xml

    <uses-permission android:name="com.example.provider.READ_PERMISSION"/>
  2. 通过URI查询数据

    Uri uri = Uri.parse("content://com.example.provider/users");
    Cursor cursor = getContentResolver().query(
            uri,                       // 目标URI
            null,                      // 返回列(null表示全部)
            "gender=?",                // 筛选条件
            new String[]{"male"},      // 参数
            null                       // 排序
    );
  3. 解析Cursor流程同原生方案

⚠️ 注意

安卓APP如何操作SQLite数据库?

  • 需目标应用暴露ContentProvider
  • 敏感数据需显式声明权限

安全与性能优化

  1. 线程管理

    • 禁止主线程操作数据库(Room默认强制异步)
    • 原生SQLite使用AsyncTaskThreadPoolExecutor
  2. 防SQL注入

    永远使用参数化查询(占位符),避免拼接SQL

  3. 连接复用

    单例模式管理数据库实例(避免多次打开)

  4. 数据加密
    敏感数据集成SQLCipher:

    implementation 'net.zetetic:android-database-sqlcipher:4.5.3'

总结建议

场景 推荐方案 复杂度
简单查询/小型应用 原生SQLite
稳定应用/团队协作 Room Persistence
跨应用数据共享 ContentProvider

关键提示

  • 始终在后台线程执行数据库操作
  • 使用完CursorSQLiteDatabase后立即关闭
  • 生产环境推荐Room + LiveData架构

引用说明
本文代码示例基于Android官方文档SQLite指南Room使用指南,安全建议参照OWASP移动安全标准,数据库加密方案采用SQLCipher开源库。

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/8797.html

(0)
酷盾叔酷盾叔
上一篇 2025年6月1日 00:48
下一篇 2025年6月1日 00:56

相关推荐

  • 数据库外键如何轻松实战设置?

    建立外键用于关联两个表,确保数据一致性,在子表中定义外键字段(通常为另一表主键),使用 REFERENCES 关键字指定父表及对应主键列,数据库将强制约束,禁止违反引用完整性的修改操作。

    2025年6月1日
    400
  • 如何用VC快速连接数据库?完整步骤详解

    在Visual C++中连接数据库,通常使用ODBC、ADO或第三方库(如MySQL Connector),步骤包括引入头文件、配置连接字符串(服务器地址、数据库名、账号密码),通过API建立连接并执行SQL操作,最后关闭连接释放资源,需确保驱动和环境配置正确。

    2025年5月29日
    300
  • 数据库表格如何快速建立?

    在数据库中,通过CREATE TABLE语句定义表名、字段名、数据类型及约束(如主键)来建立新表格,用于存储结构化数据。

    2025年6月6日
    100
  • 淘宝如何高效构建关键词库快速提升流量?

    淘宝建立关键词数据库需通过多渠道收集数据,包括平台热搜词、竞品标题词、行业工具词等,结合生意参谋等工具分析搜索量、转化率及竞争度,筛选高价值关键词后,按类目分层管理,定期优化词库结构,匹配商品特性和用户搜索习惯,提升关键词精准度与流量转化效果。

    2025年5月28日
    500
  • MongoDB如何高效删除数据?

    使用 deleteOne() 删除单个文档,deleteMany() 删除多个文档,通过指定条件(如 {字段:值})匹配目标数据,操作前务必确认条件,防止误删重要数据。

    2025年6月7日
    200

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN