上一篇
安卓如何访问数据库
- 行业动态
- 2025-04-22
- 3
安卓访问数据库的实现方式
本地数据库访问
SQLite数据库
SQLite是安卓内置的轻量级关系型数据库,适合存储本地数据。
核心步骤:
- 创建数据库帮助类:继承
SQLiteOpenHelper
,实现onCreate()
(建表)和onUpgrade()
(更新表)。 - 增删改查操作:通过
SQLiteDatabase
对象执行SQL语句。
示例代码:
public class DbHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "app.db"; private static final int VERSION = 1; public DbHelper(Context context) { super(context, DATABASE_NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE 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); } }
操作方法:
- 插入数据:
db.insert()
或execSQL("INSERT INTO...")
- 查询数据:
db.query()
或rawQuery()
- 更新/删除:
db.update()
或db.delete()
Room持久化库
Room是谷歌推荐的ORM框架,基于SQLite,提供编译时校验和抽象层。
核心组件:
- Entity:标注数据库表结构。
- DAO:定义数据操作接口(增删改查)。
- Database:继承
RoomDatabase
,封装多个DAO。
示例代码:
// Entity定义 @Entity(tableName = "user") public class User { @PrimaryKey(autoGenerate = true) public int id; public String name; } // DAO接口 @Dao public interface UserDao { @Insert void insert(User user); @Query("SELECT FROM user WHERE id = :userId") User getUserById(int userId); } // Database类 @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
优势对比表:
| 特性 | SQLite | Room |
|———————|————————-|————————–|
| 编译时校验 | 无 | 支持(通过注解生成代码) |
| 线程安全 | 需手动处理 | 自动支持(LiveData/Rx) |
| API复杂度 | 低(需手写SQL) | 高(面向对象) |
| 适用场景 | 简单需求 | 复杂业务逻辑 |
远程数据库访问
使用Retrofit+OKHttp
适用于访问服务器上的MySQL、PostgreSQL等数据库,通常通过REST API交互。
实现步骤:
- 添加依赖:
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
- 定义API接口:
public interface ApiService { @GET("users/{id}") Call<User> getUser(@Path("id") int id); }
- 创建Retrofit实例:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); ApiService apiService = retrofit.create(ApiService.class);
- 发送请求并处理响应:
apiService.getUser(1).enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { if (response.isSuccessful()) { User user = response.body(); } } @Override public void onFailure(Call<User> call, Throwable t) { // 处理错误 } });
数据解析与异步处理
- JSON解析:通过
GsonConverterFactory
自动转换。 - 异步处理:使用
enqueue()
方法避免阻塞主线程。 - 错误处理:捕获
onFailure()
中的异常,或自定义OkHttp
拦截器。
其他访问方式
ContentProvider访问系统数据库
用于跨应用共享数据(如读取通讯录、短信)。
示例:读取联系人
ContentResolver resolver = getContentResolver(); Uri uri = ContactsContract.Contacts.CONTENT_URI; Cursor cursor = resolver.query(uri, null, null, null, null); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); } cursor.close();
注意事项
- 线程管理:
- 本地数据库操作需在子线程执行(如
AsyncTask
、Coroutines
)。 - Room支持
LiveData
和RxJava
,自动异步处理。
- 本地数据库操作需在子线程执行(如
- 数据库版本控制:
- 在
SQLiteOpenHelper
或RoomDatabase
的onUpgrade()
中处理迁移逻辑。 - Room可通过
migrationStrategy
简化版本升级。
- 在
相关问题与解答
问题1:Room相比SQLite的优势是什么?
解答:
- 编译时校验:Room通过注解生成代码,提前发现错误,减少运行时崩溃。
- 抽象层级:提供DAO接口,避免手写SQL,降低复杂度。
- 线程安全:内置支持
LiveData
和RxJava
,自动处理异步更新。 - 维护性:代码更清晰,适合复杂业务逻辑。
问题2:如何在Retrofit中处理网络请求的错误?
解答:
- 基础错误处理:在
onFailure()
回调中捕获异常(如网络断开、超时)。 - 自定义拦截器:通过
OkHttp
拦截器统一处理错误码(如404、500)。 - 重试机制:使用
retryWhen
(RxJava)或递归调用实现自动重试。 - 日志记录:集成
Timber
或Log
输出错误详情,便于调试