安卓写入本地数据库
- 行业动态
- 2025-04-24
- 2228
安卓本地数据库类型选择
数据库类型 | 特点 | 适用场景 |
---|---|---|
SQLite | 轻量级嵌入式数据库,支持SQL语法,无需独立服务器进程 | 本地数据存储(如用户信息、配置参数) |
Room | 基于SQLite的抽象层,提供编译时校验,简化开发流程 | 需要对象关系映射(ORM)的复杂场景 |
使用SQLite直接操作数据库
创建数据库帮助类
public class DBHelper extends SQLiteOpenHelper { private static final String NAME = "app_data.db"; private static final int VERSION = 1; public DBHelper(Context context) { super(context, NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建用户表 String sql = "CREATE TABLE user(id INTEGER PRIMARY KEY,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); } }
执行增删改查操作
// 插入数据 ContentValues values = new ContentValues(); values.put("name", "张三"); values.put("age", 25); SQLiteDatabase db = helper.getWritableDatabase(); db.insert("user", null, values);
// 更新数据
ContentValues updateValues = new ContentValues();
updateValues.put(“age”, 26);
db.update(“user”, updateValues, “name=?”, new String[]{“张三”});
// 删除数据
db.delete(“user”, “age>?”, new String[]{“30”});
// 查询数据
Cursor cursor = db.query(“user”, null, “age>?”, new String[]{“20”}, null, null, “age DESC”);
while(cursor.moveToNext()){
int id = cursor.getInt(cursor.getColumnIndex(“id”));
String name = cursor.getString(cursor.getColumnIndex(“name”));
// 处理数据…
}
三、使用Room持久化库
1. 定义实体类
```java
@Entity(tableName = "user")
public class User {
@PrimaryKey(autoGenerate = true)
public int id;
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "age")
public int age;
}
创建DataBase类
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
定义DAO接口
@Dao public interface UserDao { @Insert void insertUser(User... users); @Update void updateUser(User... users); @Delete void deleteUser(User... users); @Query("SELECT FROM user WHERE age > :minAge") List<User> getUsersByAge(int minAge); }
使用示例
AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "app_data.db").build(); UserDao userDao = db.userDao();
// 插入数据
User user = new User();
user.name = “李四”;
user.age = 30;
userDao.insertUser(user);
四、关键注意事项
1. 线程处理:
SQLiteDatabase在多线程场景需注意并发问题,建议使用`synchronized`或开启事务
Room默认禁止在主线程执行耗时操作,可通过`allowMainThreadQueries()`临时允许(仅限调试)
2. 数据库迁移:
| 场景 | 处理方式 |
|------|----------|
| 表结构变更 | 在`onUpgrade()`方法中执行ALTER语句或迁移数据 |
| 版本号更新 | 必须递增VERSION参数并实现迁移逻辑 |
Room通过`Migration`类实现版本控制,示例:
```java
Room.migrations(new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE user ADD COLUMN address TEXT");
}
}).build();
相关问题与解答
Q1:SQLite和Room应该如何选择?
A:如果项目需要快速实现简单功能且团队熟悉原生SQL,可选用SQLite;若追求代码规范性、减少运行时错误,或需要复杂数据关系映射,推荐使用Room,Room通过编译时校验能提前发现语法错误,并提供LiveData等响应式编程支持。
Q2:如何实现多表关联查询?
A:在Room中可通过@Relation
注解实现对象关系映射,例如定义订单(Order)和商品(Product)的一对多关系:
@Entity public class Order { @PrimaryKey(autoGenerate = true) public int id; public String orderName; } @Entity(foreignKeys = @ForeignKey(entity = Order.class, parentColumns = "id", childColumns = "orderId")) public class Product { @PrimaryKey(autoGenerate = true) public int id; public int orderId; public String productName; } // 定义关联查询 @Transaction @Query("SELECT FROM order") public abstract List<OrderWithProducts> getOrdersWithProducts(); // 定义嵌套对象结构 public class OrderWithProducts { @Embedded public Order order; @Relation(parentColumn = "id", entityColumn = "orderId") public List<Product> products; }