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) { // 创建用户表 String sql = "CREATE TABLE user(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,age INTEGER)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 数据库升级处理 db.execSQL("DROP TABLE IF EXISTS user"); onCreate(db); } }
// 获取可写数据库 SQLiteDatabase db = new DBHelper(context).getWritableDatabase(); // 方式1:使用execSQL插入原始数据 String sql = "INSERT INTO user(name,age) VALUES('张三',25)"; db.execSQL(sql); // 方式2:使用ContentValues插入数据 ContentValues values = new ContentValues(); values.put("name","李四"); values.put("age",30); db.insert("user",null,values); // 事务处理(推荐) db.beginTransaction(); try { db.insert("user",null,values); db.setTransactionSuccessful(); } finally { db.endTransaction(); }
@Entity(tableName = "user") public class User { @PrimaryKey(autoGenerate = true) public int id; @ColumnInfo(name = "name") public String name; @ColumnInfo(name = "age") public int age; }
@Dao public interface UserDao { @Insert void insertUser(User... users); // 支持批量插入 @Insert(onConflict = OnConflictStrategy.REPLACE) // 主键冲突时替换 void insertOrReplace(User user); @Query("SELECT FROM user WHERE name LIKE :name") List<User> findByName(String name); }
@Database(entities = {User.class},version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
AppDatabase db = Room.databaseBuilder(context,AppDatabase.class,"app.db").build(); User user = new User(); user.name = "王五"; user.age = 28; // 单条插入 db.userDao().insertUser(user); // 批量插入 List<User> users = new ArrayList<>(); users.add(new User(){{name="赵六";age=22;}}); users.add(new User(){{name="孙七";age=35;}}); db.userDao().insertUser(users.toArray(new User[0]));
特性 | SQLite直接操作 | Room持久化库 |
---|---|---|
编译时检查 | 无 | 有(通过注解处理器) |
类型安全 | 需手动转换 | 自动处理 |
抽象层 | 底层API | 面向对象 |
编译期错误检测 | 运行时报错 | 编译时报错 |
数据库迁移支持 | 需手动实现 | 提供Migration API |
LiveData支持 | 无 | 内置(观察数据变化) |
NetworkOnMainThreadException
onUpgrade
方法,处理数据迁移OnConflictStrategy
(IGNORE/REPLACE等)db.close()
释放数据库连接Q1:如何实现数据库版本升级时的数据迁移?
migration
方法实现: Room.databaseBuilder(context,AppDatabase.class,"app.db") .addMigrations(new Migration(1,2) { @Override public void migrate(SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE user ADD COLUMN address TEXT"); } }).build();
传统SQLite需在onUpgrade
方法中执行ALTER语句。
Q2:如何处理外键约束关系?
A2:在Room实体类中使用@ForeignKey
注解:
@Entity(foreignKeys = @ForeignKey(entity = User.class,parentColumns = "id",childColumns = "user_id")) public class Order { @PrimaryKey(autoGenerate = true) public int id; public int user_id; // 关联用户表的外键 public String product; }
需在RoomDatabase
中开启外键支持:.fallbackToDestructiveMigration().build()