Android系统内置了SQLite数据库,并提供了多种操作数据库的方式,包括原生SQLite API、第三方ORM框架(如GreenDao)以及官方推荐的Room组件,以下是主流方案对比:
数据库方案 | 特点 |
---|---|
SQLite | 系统原生支持,轻量级,需手写SQL语句,无编译时校验 |
Room | 基于SQLite的抽象层,提供编译时校验,支持LiveData响应式编程 |
GreenDao | 高性能ORM框架,支持复杂查询,需手动编写Dao接口 |
// build.gradle (Module) dependencies { implementation "androidx.room:room-runtime:2.5.1" kapt "androidx.room:room-compiler:2.5.1" // 如果使用Kotlin }
// 使用@Entity标注表结构,@PrimaryKey定义主键 @Entity(tableName = "user") public class User { @PrimaryKey(autoGenerate = true) public int id; @ColumnInfo(name = "name") public String name; @ColumnInfo(name = "age") public int age; }
// 定义数据访问方法,使用@Query自定义SQL @Dao public interface UserDao { @Insert void insertUser(User user); @Update void updateUser(User user); @Delete void deleteUser(User user); @Query("SELECT FROM user WHERE id = :userId") User getUserById(int userId); }
// @Database标注数据库,包含多个Dao @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
AppDatabase db = Room.databaseBuilder( getApplicationContext(), AppDatabase.class, "app-database" ).build();
public class DBHelper extends SQLiteOpenHelper { private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS user (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT," + "age INTEGER)"; public DBHelper(Context context) { super(context, "app.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS user"); onCreate(db); } }
SQLiteDatabase db = helper.getWritableDatabase(); // 插入数据 ContentValues values = new ContentValues(); values.put("name", "John"); values.put("age", 25); db.insert("user", null, values); // 查询数据 Cursor cursor = db.query("user", null, "id=?", new String[]{"1"}, null, null, null); if(cursor.moveToFirst()){ String name = cursor.getString(cursor.getColumnIndex("name")); } cursor.close();
场景 | 解决方案 |
---|---|
主线程操作数据库 | 使用AsyncTask 或ExecutorService 进行异步处理 |
数据库版本升级 | 实现onUpgrade() 方法,使用ALTER TABLE 或迁移工具 |
复杂查询需求 | 优先使用Room的@RawQuery 或@Query 注解 |
数据监听 | 结合Room的LiveData 实现UI自动更新 |
Q1:为什么官方推荐使用Room而不是原生SQLite?
A1:Room提供以下优势:
Q2:如何处理多线程并发访问数据库?
A2:推荐以下方案:
RoomDatabase.inTransaction()
保证原子性 setQueryResultCallback()
异步获取游标 Executors.newFixedThreadPool()
复用线程