android 开发进程 0.37 room数据存储的使用
room数据存储简介
room 是jetpack库中的一个数据持久化库,底层还是使用的SQLite的实现方式。但使用方式更加简单,原生的SQLite方法较为繁琐,room使用的是实体类和数据库表映射的方式。更为简洁易懂。
room数据库导入
在module的gradle中添加:
def room_version = "2.3.0" // check latest version from docs
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
注意kapt是在项目使用kotlin后必须添加的,且不是数据库相关代码使用kotlin才需要导入,只要项目导入了kotlin就需要引入kotlin的库,此外GitHub上还有与rxjava等其他可能用到的类库。
room数据库的使用
设置数据表
room数据库集与实体类和数据表的映射关系,首先看如何创建一个基本的数据表:
@Entity(tableName = "User")
public class User {
@PrimaryKey((autoGenerate = true))
@ColumnInfo(name = "id")
private int id;
@ColumnInfo(name = "name")
private String name;
@ColumnInfo(name = "password")
private String password;
}
在上面的代码中我们省去了构造函数和获取类变量的方法。可以看到room使用了注解来简化操作,@Entity 注解表示此类为一个数据库的表,同时其中的tableName设置表名,不显示处理表名即为类名。变量注解@Primarykey设置主键和是否自增,@ColumnInfo是必须的,设置变量为数据库的列名。
设置数据库
设置数据库代码如下:其中UserDataDao是我们准备封装的数据库方法。
@Database(entities = {User.class}, version = 1)
public abstract class UserDataBase extends RoomDatabase {
private static UserDataBase instance;
public static UserDataBase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(), UserDataBase.class,"userdatabase")
.allowMainThreadQueries()
.addMigrations(MISGRATION_1_2)
.fallbackToDestructiveMigration()
.build();
}
return instance;
}
public abstract UserDataDao userDataDao();
注解@Database中的entities关联了数据库表和数据库,后面的version表明数据库的版本,这在数据库的更新中会用到。使用一个静态方法创建数据库,allowMainThreadQueries方法设置可以在主线程中读写数据库,addMigrations是添加数据库升级策略,fallbackToDestructiveMigration允许数据库升级失败后重建而不是直接崩溃。
数据库访问Dao
@Dao
public interface UserDataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(User...users);
@Update
void updata(User...users);
@Delete
void delete(User...users);
@Query("Select * from User")
List<User> selectAll();
}
采用已经设置好的注解,OnConflictStrategy设置冲突时解决策略,即当插入一行时如果此行已经存在即覆盖。room会自动生成一个impl的类,其中实现了具体的SQL执行过程。
使用方式
userDataBase = UserDataBase.getInstance(this);
userDataDao=userDataBase.userDataDao();
User user=new User(1, "11", "111");
userDataDao.insert(user);
List<User> userList= userDataDao.selectAll();
tvMain.setText(userList.toString());
room数据库的升级
数据库的升级是较危险的,很容易造成崩溃,客户端数据库的升级和服务器数据库升级场景也有所不同,设想一个场景,某一app升级版本,新版本中数据库表中字段出现增加,而又不想抛弃原有本机保存的数据。注意版本变化和不同的迁移策略,如1迁移到2 2迁移到3,当前版本如为3可能还需要添加1到3的方法,防止出现错误,下面是几种迁移例子:
static Migration MISGRATION_1_2=new Migration(1,2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//迁移范例1 创建新表
database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
+ "`name` TEXT, PRIMARY KEY(`id`))");
database.execSQL("ALTER TABLE Book "
+ " ADD COLUMN pub_year INTEGER");
//迁移范例2 添加字段
database.execSQL("ALTER TABLE Book "
+ " ADD COLUMN pub_year INTEGER");
//迁移范例3 遍历修改字段,如将原表某一字段加密处理,此例子已加一百为例:
database.execSQL("CREATE TABLE PersionTemp (id TEXT not null, name TEXT, PRIMARY KEY(id))");
Cursor cursor = database.query("select * from Persion");
cursor.moveToFirst();
do {
String id = cursor.getString(cursor.getColumnIndexOrThrow("id"));
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
Log.e("TAG", "migrate: num" + id);
String sql = "insert into PersionTemp (id,name) values (?,?)";
SupportSQLiteStatement statement = database.compileStatement(sql);
statement.bindString(1, id + 100);
statement.bindString(2, name);
statement.execute();
} while (cursor.moveToNext());
database.execSQL("DROP TABLE Persion");
database.execSQL("ALTER TABLE PersionTemp RENAME TO Persion");
}
};
其他
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
}
gradle此设置可以导出数据库相关信息,包括建表语句查询语句等。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 趁着过年的时候手搓了一个低代码框架
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· 乌龟冬眠箱湿度监控系统和AI辅助建议功能的实现